Request/Response Models¶
Pydantic schemas for API data validation.
Common Models¶
BaseResponse¶
All API responses extend this base model:
class BaseResponse(BaseModel):
status: Literal["success", "error"]
data: Optional[Any] = None
errors: Optional[List[ErrorDetail]] = None
metadata: ResponseMetadata
ErrorDetail¶
class ErrorDetail(BaseModel):
code: str # Error code (e.g., "VALIDATION_ERROR")
message: str # Human-readable message
field: Optional[str] = None # Field that caused error
detail: Optional[str] = None # Additional details
ResponseMetadata¶
class ResponseMetadata(BaseModel):
timestamp: datetime
version: str = "0.1.0"
request_id: Optional[str] = None
Optimization Models¶
OptimizationRequest¶
class OptimizationRequest(BaseModel):
demand_forecast: Dict[str, List[float]]
fleet_state: FleetState
constraints: OptimizationConstraints
options: Optional[OptimizationOptions] = None
class Config:
json_schema_extra = {
"example": {
"demand_forecast": {
"1": [15, 18, 22, 25],
"2": [10, 12, 14, 16]
},
"fleet_state": {
"vehicles": [
{"id": "V001", "location": 1, "capacity": 1}
]
},
"constraints": {
"max_distance": 100,
"min_service_level": 0.95
}
}
}
FleetState¶
class Vehicle(BaseModel):
id: str
location: int
capacity: int = 1
status: Literal["operational", "maintenance", "downtime"] = "operational"
class FleetState(BaseModel):
vehicles: List[Vehicle]
OptimizationConstraints¶
class OptimizationConstraints(BaseModel):
max_distance: float = 100.0
min_service_level: float = 0.95
max_rebalancing_cost: Optional[float] = None
capacity_per_vehicle: int = 1
OptimizationResponse¶
class AllocationItem(BaseModel):
vehicle_id: str
source_location: int
target_location: int
cost: float
assignment: Literal["stay", "rebalance", "maintenance"]
class OptimizationKPIs(BaseModel):
demand_coverage: float
utilization: float
rebalanced_count: int
total_distance: float
class OptimizationResult(BaseModel):
allocation_plan: List[AllocationItem]
total_cost: float
kpis: OptimizationKPIs
solver_status: str
class OptimizationResponse(BaseResponse):
data: Optional[OptimizationResult] = None
Forecasting Models¶
ForecastRequest¶
class ForecastRequest(BaseModel):
location_ids: List[int]
horizon_hours: int = 168 # 7 days
features: Optional[ForecastFeatures] = None
class ForecastFeatures(BaseModel):
start_date: Optional[date] = None
include_intervals: bool = False
confidence_level: float = 0.95
ForecastResponse¶
class ForecastMetadata(BaseModel):
model: str
horizon_hours: int
generated_at: datetime
class ForecastResult(BaseModel):
forecasts: Dict[str, List[float]]
intervals: Optional[Dict[str, Dict[str, List[float]]]] = None
metadata: ForecastMetadata
class ForecastResponse(BaseResponse):
data: Optional[ForecastResult] = None
Risk Models¶
RiskScoreRequest¶
class VehicleRiskInput(BaseModel):
id: str
age_days: int
utilization_rate: float
days_since_maintenance: int
class RiskScoreRequest(BaseModel):
vehicles: List[VehicleRiskInput]
RiskScoreResponse¶
class RiskFactors(BaseModel):
age_contribution: float
utilization_contribution: float
maintenance_contribution: float
class VehicleRiskScore(BaseModel):
vehicle_id: str
risk_score: float
risk_category: Literal["low", "medium", "high"]
factors: RiskFactors
class RiskScoreResult(BaseModel):
risk_scores: List[VehicleRiskScore]
class RiskScoreResponse(BaseResponse):
data: Optional[RiskScoreResult] = None
Data Models¶
LocationModel¶
class Location(BaseModel):
id: int
name: str
latitude: float
longitude: float
avg_demand: Optional[float] = None
max_capacity: Optional[int] = None
FleetSummary¶
class FleetSummary(BaseModel):
total_vehicles: int
operational: int
maintenance: int
downtime: int
avg_utilization: float
avg_risk_score: float
Validation Rules¶
Demand Forecast¶
@validator('demand_forecast')
def validate_demand(cls, v):
for location_id, values in v.items():
if not all(x >= 0 for x in values):
raise ValueError(f"Demand values must be non-negative")
if len(values) == 0:
raise ValueError(f"Demand array cannot be empty")
return v
Constraints¶
@validator('min_service_level')
def validate_service_level(cls, v):
if not 0 <= v <= 1:
raise ValueError("Service level must be between 0 and 1")
return v
@validator('max_distance')
def validate_distance(cls, v):
if v <= 0:
raise ValueError("Max distance must be positive")
return v
OpenAPI Schema¶
The full OpenAPI schema is available at:
- Swagger UI:
http://localhost:8000/docs - ReDoc:
http://localhost:8000/redoc - JSON Schema:
http://localhost:8000/openapi.json