Files
bakery-ia/services/external/app/schemas/traffic.py

106 lines
4.1 KiB
Python
Raw Normal View History

2025-08-12 18:17:30 +02:00
# services/external/app/schemas/traffic.py
"""
Traffic Service Pydantic Schemas
"""
2025-08-08 09:08:41 +02:00
2025-08-10 17:31:38 +02:00
from pydantic import BaseModel, Field, field_validator
2025-08-08 09:08:41 +02:00
from datetime import datetime
from typing import Optional, List
from uuid import UUID
class TrafficDataBase(BaseModel):
"""Base traffic data schema"""
location_id: str = Field(..., max_length=100, description="Traffic monitoring location ID")
date: datetime = Field(..., description="Date and time of traffic measurement")
traffic_volume: Optional[int] = Field(None, ge=0, description="Vehicles per hour")
pedestrian_count: Optional[int] = Field(None, ge=0, description="Pedestrians per hour")
2025-08-10 17:31:38 +02:00
congestion_level: Optional[str] = Field(None, pattern="^(low|medium|high)$", description="Traffic congestion level")
2025-08-08 09:08:41 +02:00
average_speed: Optional[float] = Field(None, ge=0, le=200, description="Average speed in km/h")
source: str = Field("madrid_opendata", max_length=50, description="Data source")
raw_data: Optional[str] = Field(None, description="Raw data from source")
class TrafficDataCreate(TrafficDataBase):
"""Schema for creating traffic data"""
pass
class TrafficDataUpdate(BaseModel):
"""Schema for updating traffic data"""
traffic_volume: Optional[int] = Field(None, ge=0)
pedestrian_count: Optional[int] = Field(None, ge=0)
2025-08-10 17:31:38 +02:00
congestion_level: Optional[str] = Field(None, pattern="^(low|medium|high)$")
2025-08-08 09:08:41 +02:00
average_speed: Optional[float] = Field(None, ge=0, le=200)
raw_data: Optional[str] = None
class TrafficDataResponseDB(TrafficDataBase):
"""Schema for traffic data responses from database"""
2025-08-08 09:08:41 +02:00
id: str = Field(..., description="Unique identifier")
created_at: datetime = Field(..., description="Creation timestamp")
updated_at: datetime = Field(..., description="Last update timestamp")
2025-08-10 17:31:38 +02:00
@field_validator('id', mode='before')
@classmethod
2025-08-08 09:08:41 +02:00
def convert_uuid_to_string(cls, v):
if isinstance(v, UUID):
return str(v)
return v
class Config:
from_attributes = True
json_encoders = {
datetime: lambda v: v.isoformat()
}
class TrafficDataList(BaseModel):
"""Schema for paginated traffic data responses"""
data: List[TrafficDataResponseDB]
2025-08-08 09:08:41 +02:00
total: int = Field(..., description="Total number of records")
page: int = Field(..., description="Current page number")
per_page: int = Field(..., description="Records per page")
has_next: bool = Field(..., description="Whether there are more pages")
has_prev: bool = Field(..., description="Whether there are previous pages")
class TrafficAnalytics(BaseModel):
"""Schema for traffic analytics"""
location_id: str
period_start: datetime
period_end: datetime
avg_traffic_volume: Optional[float] = None
avg_pedestrian_count: Optional[float] = None
peak_traffic_hour: Optional[int] = None
peak_pedestrian_hour: Optional[int] = None
congestion_distribution: dict = Field(default_factory=dict)
2025-08-12 18:17:30 +02:00
avg_speed: Optional[float] = None
class TrafficDataResponse(BaseModel):
"""Schema for API traffic data responses"""
date: datetime = Field(..., description="Date and time of traffic measurement")
traffic_volume: Optional[int] = Field(None, ge=0, description="Vehicles per hour")
pedestrian_count: Optional[int] = Field(None, ge=0, description="Pedestrians per hour")
congestion_level: Optional[str] = Field(None, pattern="^(low|medium|high)$", description="Traffic congestion level")
average_speed: Optional[float] = Field(None, ge=0, le=200, description="Average speed in km/h")
source: str = Field(..., description="Data source")
class Config:
json_encoders = {
datetime: lambda v: v.isoformat()
}
2025-08-12 18:17:30 +02:00
class LocationRequest(BaseModel):
latitude: float
longitude: float
address: Optional[str] = None
class DateRangeRequest(BaseModel):
start_date: datetime
end_date: datetime
class HistoricalTrafficRequest(BaseModel):
latitude: float
longitude: float
start_date: datetime
end_date: datetime
class TrafficForecastRequest(BaseModel):
latitude: float
longitude: float
hours: int = 24