from datetime import datetime from typing import List, Optional try: from pydantic import BaseModel, Field, ConfigDict _CONFIG_DICT_SUPPORTED = True except ImportError: # pragma: no cover - Pydantic v1 fallback from pydantic import BaseModel, Field # type: ignore _CONFIG_DICT_SUPPORTED = False class ECGInferenceRequest(BaseModel): patient_id: str = Field(..., example="patient-123") signal: List[float] = Field(..., min_items=1, example=[0.1, 0.2, 0.3]) device_id: Optional[str] = Field(None, example="device-abc") sampling_rate: Optional[float] = Field(None, gt=0, example=250.0) age: Optional[int] = Field(None, ge=0, example=70) has_prior_stroke: Optional[bool] = Field(None, example=False) class ECGInferenceResponse(BaseModel): patient_id: str label: str score: float alert_level: str hr: Optional[int] = None sample_id: int created_at: datetime explanations: List[str] = Field(default_factory=list) if _CONFIG_DICT_SUPPORTED: # type: ignore model_config = ConfigDict(from_attributes=True) # type: ignore else: class Config: orm_mode = True class DashboardStats(BaseModel): time_window_hours: int total_samples: int unique_patients: int alert_distribution: dict label_distribution: dict avg_score: float estimated_energy_savings_pct: float timestamp: str class PatientSummary(BaseModel): patient_id: str latest_label: Optional[str] latest_score: float latest_alert_level: Optional[str] latest_hr: Optional[int] last_updated: str total_samples: int alert_count: int class AlertSummary(BaseModel): sample_id: int patient_id: str alert_level: str label: Optional[str] score: float hr: Optional[int] timestamp: str