Spaces:
Paused
Paused
File size: 2,113 Bytes
4eefabb | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | """Pydantic request / response schemas — the contract between FE and BE."""
from __future__ import annotations
from typing import Literal
from pydantic import BaseModel, Field
TerrainType = Literal["Valley", "Slope", "Flat", "Peak", "Unknown"]
RiskLevel = Literal["Safe", "Caution", "Warning", "Danger"]
ActivityType = Literal["hiker", "driver", "construction", "general"]
class PredictionRequest(BaseModel):
latitude: float = Field(..., ge=-90.0, le=90.0, description="WGS84 latitude")
longitude: float = Field(..., ge=-180.0, le=180.0, description="WGS84 longitude")
activity: ActivityType = "general"
class VetoTrigger(BaseModel):
rule: str
value: float | None
message_en: str
message_zh: str
class InferenceStep(BaseModel):
"""One line of the XAI (explainable AI) inference log."""
kind: Literal["info", "ml", "rule", "veto", "score", "hazard", "table", "activity"]
text_en: str
text_zh: str
class HazardSubscores(BaseModel):
"""Per-category risk score 0-100. Matches the four hazard types
enumerated in the D5 proposal §3.7 (P4.3)."""
rainfall: int = Field(..., ge=0, le=100)
fog: int = Field(..., ge=0, le=100)
wind_gust: int = Field(..., ge=0, le=100)
thunderstorm: int = Field(..., ge=0, le=100)
class DecisionTableMatch(BaseModel):
"""A row of D5 §3.7.2 / Table 4.2 that has fired for this request."""
rule: str # 'R1' | 'R2' | 'R3' | 'R4'
description: str
conclusion_en: str
conclusion_zh: str
class PredictionResponse(BaseModel):
latitude: float
longitude: float
elevation_m: float
terrain: TerrainType
ml_rain_probability: float = Field(..., ge=0.0, le=1.0)
hazard_subscores: HazardSubscores
decision_table_matches: list[DecisionTableMatch]
activity: ActivityType
risk_score: int = Field(..., ge=0, le=100)
risk_level: RiskLevel
veto_triggers: list[VetoTrigger]
inference_log: list[InferenceStep]
advice_en: str
advice_zh: str
cached: bool = False
cache_ttl: int = 0
|