| | """ |
| | 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 |
| |
|