| """ |
| Pydantic models β exact mirrors of Phoebe iOS Swift DTOs. |
| |
| Field names = snake_case matching CodingKeys from: |
| - APIModels.swift (HeadacheLogSnapshotDTO, DailySnapshotDTO) |
| - InsightPayloadDTO.swift (HealthKitMetricsDTO, WeatherDataDTO, UserContextDTO) |
| """ |
|
|
| from __future__ import annotations |
| from pydantic import BaseModel, Field |
| from typing import List, Optional |
| from enum import Enum |
|
|
|
|
| |
|
|
| class MedicationResponseEnum(str, Enum): |
| horrible = "horrible" |
| worse = "worse" |
| same = "same" |
| better = "better" |
| excellent = "excellent" |
|
|
|
|
| |
|
|
| class SymptomsPayload(BaseModel): |
| symptoms: List[str] = [] |
|
|
| class TriggersPayload(BaseModel): |
| triggers: List[str] = [] |
|
|
| class MedicationPayload(BaseModel): |
| medication_taken: List[str] = [] |
|
|
| class TherapeuticPayload(BaseModel): |
| therapeutic_activities: List[str] = [] |
|
|
|
|
| |
|
|
| class SleepAnalysisDTO(BaseModel): |
| total_duration_hours: Optional[float] = None |
| deep_sleep_minutes: Optional[float] = None |
| rem_sleep_minutes: Optional[float] = None |
|
|
| class HRVSummaryDTO(BaseModel): |
| average_ms: Optional[float] = None |
|
|
| class HealthKitMetricsDTO(BaseModel): |
| resting_heart_rate: Optional[float] = None |
| sleep_analysis: Optional[SleepAnalysisDTO] = None |
| hrv_summary: Optional[HRVSummaryDTO] = None |
| workout_minutes: Optional[int] = None |
| had_menstrual_flow: Optional[bool] = None |
|
|
|
|
| |
|
|
| class WeatherDataDTO(BaseModel): |
| barometric_pressure_mb: float = 1013.25 |
| pressure_change_24h_mb: float = 0.0 |
| humidity_percent: float = 50.0 |
| temperature_celsius: float = 15.0 |
|
|
|
|
| |
|
|
| class HeadacheLogSnapshotDTO(BaseModel): |
| severity: int = 0 |
| duration_hours: float = 0.0 |
| symptoms: SymptomsPayload = Field(default_factory=SymptomsPayload) |
| triggers: TriggersPayload = Field(default_factory=TriggersPayload) |
| notes: Optional[str] = None |
| input_date: str = "" |
| input_time: Optional[str] = None |
| end_date: Optional[str] = None |
| end_time: Optional[str] = None |
| pain_frontal: bool = False |
| pain_temporal_left: bool = False |
| pain_temporal_right: bool = False |
| pain_occipital: bool = False |
| pain_parietal: bool = False |
| pain_ocular_left: bool = False |
| pain_ocular_right: bool = False |
| pain_sinus: bool = False |
| mood: Optional[str] = None |
| medication_taken: Optional[MedicationPayload] = None |
| medication_response: Optional[MedicationResponseEnum] = None |
| therapeutic_activities: Optional[TherapeuticPayload] = None |
|
|
|
|
| |
|
|
| class DailySnapshotDTO(BaseModel): |
| headache_log: Optional[HeadacheLogSnapshotDTO] = None |
| health_kit_metrics: Optional[HealthKitMetricsDTO] = None |
| weather_data: Optional[WeatherDataDTO] = None |
|
|
|
|
| |
|
|
| class UserContextDTO(BaseModel): |
| age_range: Optional[str] = None |
| location_region: Optional[str] = None |
|
|
|
|
| |
|
|
| class PredictionRequest(BaseModel): |
| user_context: Optional[UserContextDTO] = None |
| daily_snapshots: List[DailySnapshotDTO] |
|
|
| class DayPrediction(BaseModel): |
| day: int |
| date: Optional[str] = None |
| prediction: int |
| probability: float |
| risk_level: str |
| top_risk_factors: List[str] = [] |
|
|
| class PredictionResponse(BaseModel): |
| predictions: List[DayPrediction] |
| model_version: str |
| threshold: float |
|
|
| |
| class SinglePredictionRequest(BaseModel): |
| features: List[float] |
|
|
| class SinglePredictionResponse(BaseModel): |
| prediction: int |
| probability: float |
|
|