from datetime import datetime, timezone from enum import Enum from uuid import UUID, uuid4 from pydantic import BaseModel, ConfigDict, Field, HttpUrl def now_utc() -> datetime: return datetime.now(timezone.utc) class MonitorState(str, Enum): unknown = "unknown" up = "up" down = "down" class MonitorCreate(BaseModel): name: str = Field(min_length=1, max_length=100) url: HttpUrl timeout_seconds: float | None = Field(None, gt=0, le=60) class MonitorUpdate(BaseModel): name: str | None = Field(None, min_length=1, max_length=100) url: HttpUrl | None = None timeout_seconds: float | None = Field(None, gt=0, le=60) class MonitorStatus(BaseModel): state: MonitorState = MonitorState.unknown checked_at: datetime | None = None http_status: int | None = None latency_ms: float | None = None error: str | None = None class Monitor(BaseModel): model_config = ConfigDict(from_attributes=True) id: UUID = Field(default_factory=uuid4) name: str url: HttpUrl timeout_seconds: float created_at: datetime = Field(default_factory=now_utc) updated_at: datetime = Field(default_factory=now_utc) status: MonitorStatus = Field(default_factory=MonitorStatus) class CheckResult(MonitorStatus): pass class ErrorBody(BaseModel): code: str message: str details: list[dict[str, object]] | None = None class ErrorResponse(BaseModel): error: ErrorBody