""" Pydantic models for Instant PromQL Query tool input validation. Defines InstantQueryRequest: query (required) and optional RFC3339 evaluation time. """ from datetime import datetime from typing import Optional from pydantic import BaseModel, Field, field_validator # Internal labels to exclude from output per spec (FR-013) EXCLUDE_LABELS = {"__address__"} def filter_display_labels(labels: dict[str, str]) -> dict[str, str]: """ Exclude internal labels for display. Excludes __address__; redundant instance is handled in formatting. """ return {k: v for k, v in labels.items() if k not in EXCLUDE_LABELS} class InstantQueryRequest(BaseModel): """ Input model for instant query requests. Validates PromQL query string and optional RFC3339 evaluation timestamp. """ query: str = Field( ..., description="PromQL query string to execute", min_length=1, examples=['up{job="prometheus"}', "rate(http_requests_total[5m])"], ) time: Optional[str] = Field( default=None, description="Optional evaluation time in RFC3339 format (default: now)", examples=["2024-01-01T12:00:00Z"], ) cluster_id: str = Field( ..., description="Cluster identifier", ) env: str = Field( ..., description="Environment name used in biz_type resolution (e.g. prod, staging, dev)", ) deploy_type: str = Field( ..., description=( "Cluster deploy type used in biz_type resolution " "(dedicated, premium, resource_pool, starter, essential)" ), ) @field_validator("time") @classmethod def validate_time(cls, v: Optional[str]) -> Optional[str]: if v is None or not v.strip(): return None try: datetime.fromisoformat(v.replace("Z", "+00:00")) return v.strip() except ValueError as e: raise ValueError(f"Invalid timestamp format: {v}. Must be RFC3339/ISO8601.") from e @field_validator("env", "deploy_type", mode="before") @classmethod def normalize_scope_text(cls, v: str) -> str: return v.strip().lower() @field_validator("cluster_id", mode="before") @classmethod def normalize_cluster_id(cls, v: object) -> str: if not isinstance(v, str): raise ValueError("cluster_id must be a string. Quote numeric IDs explicitly.") return str(v).strip()