117 lines
4.6 KiB
Python
117 lines
4.6 KiB
Python
from fastapi import APIRouter, Depends, Query, HTTPException
|
|
import asyncpg
|
|
from ..dependencies import get_db, get_cache
|
|
# DropdownService deprecated; using normalized schema service
|
|
from ..services.vehicles_service import VehiclesService
|
|
from ..repositories.vehicles_repository import VehiclesRepository
|
|
from ..services.cache_service import CacheService
|
|
from ..models.responses import (
|
|
MakesResponse, ModelsResponse, TrimsResponse,
|
|
EnginesResponse,
|
|
MakeItem, ModelItem, TrimItem, EngineItem
|
|
)
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
router = APIRouter(prefix="/vehicles", tags=["Vehicles"])
|
|
|
|
@router.get("/years", response_model=list[int])
|
|
async def get_years(
|
|
db: asyncpg.Connection = Depends(get_db),
|
|
cache: CacheService = Depends(get_cache),
|
|
):
|
|
"""Get available model years (distinct, desc)"""
|
|
service = VehiclesService(cache, VehiclesRepository())
|
|
return await service.get_years(db)
|
|
|
|
@router.get("/makes", response_model=MakesResponse)
|
|
async def get_makes(
|
|
year: int = Query(..., description="Model year", ge=1980, le=2050),
|
|
db: asyncpg.Connection = Depends(get_db),
|
|
cache: CacheService = Depends(get_cache)
|
|
):
|
|
"""Get makes for a specific year
|
|
|
|
Hierarchical API: First level - requires year parameter only
|
|
"""
|
|
try:
|
|
service = VehiclesService(cache, VehiclesRepository())
|
|
makes = await service.get_makes(db, year)
|
|
return MakesResponse(makes=[MakeItem(**m) for m in makes])
|
|
except Exception as e:
|
|
logger.error(f"Failed to get makes for year {year}: {e}")
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail=f"Failed to retrieve makes for year {year}"
|
|
)
|
|
|
|
@router.get("/models", response_model=ModelsResponse)
|
|
async def get_models(
|
|
year: int = Query(..., description="Model year", ge=1980, le=2050),
|
|
make_id: int = Query(..., description="Make ID", ge=1),
|
|
db: asyncpg.Connection = Depends(get_db),
|
|
cache: CacheService = Depends(get_cache)
|
|
):
|
|
"""Get models for year and make
|
|
|
|
Hierarchical API: Second level - requires year and make_id parameters
|
|
"""
|
|
try:
|
|
service = VehiclesService(cache, VehiclesRepository())
|
|
models = await service.get_models(db, year, make_id)
|
|
return ModelsResponse(models=[ModelItem(**m) for m in models])
|
|
except Exception as e:
|
|
logger.error(f"Failed to get models for year {year}, make {make_id}: {e}")
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail=f"Failed to retrieve models for year {year}, make {make_id}"
|
|
)
|
|
|
|
@router.get("/trims", response_model=TrimsResponse)
|
|
async def get_trims(
|
|
year: int = Query(..., description="Model year", ge=1980, le=2050),
|
|
make_id: int = Query(..., description="Make ID", ge=1),
|
|
model_id: int = Query(..., description="Model ID", ge=1),
|
|
db: asyncpg.Connection = Depends(get_db),
|
|
cache: CacheService = Depends(get_cache)
|
|
):
|
|
"""Get trims for year, make, and model
|
|
|
|
Hierarchical API: Third level - requires year, make_id, and model_id parameters
|
|
"""
|
|
try:
|
|
service = VehiclesService(cache, VehiclesRepository())
|
|
trims = await service.get_trims(db, year, model_id)
|
|
return TrimsResponse(trims=[TrimItem(**t) for t in trims])
|
|
except Exception as e:
|
|
logger.error(f"Failed to get trims for year {year}, make {make_id}, model {model_id}: {e}")
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail=f"Failed to retrieve trims for year {year}, make {make_id}, model {model_id}"
|
|
)
|
|
|
|
@router.get("/engines", response_model=EnginesResponse)
|
|
async def get_engines(
|
|
year: int = Query(..., description="Model year", ge=1980, le=2050),
|
|
make_id: int = Query(..., description="Make ID", ge=1),
|
|
model_id: int = Query(..., description="Model ID", ge=1),
|
|
trim_id: int = Query(..., description="Trim ID", ge=1),
|
|
db: asyncpg.Connection = Depends(get_db),
|
|
cache: CacheService = Depends(get_cache)
|
|
):
|
|
"""Get engines for year, make, model, and trim"""
|
|
try:
|
|
service = VehiclesService(cache, VehiclesRepository())
|
|
engines = await service.get_engines(db, year, model_id, trim_id)
|
|
return EnginesResponse(engines=[EngineItem(**e) for e in engines])
|
|
except Exception as e:
|
|
logger.error(
|
|
f"Failed to get engines for year {year}, make {make_id}, model {model_id}, trim {trim_id}: {e}"
|
|
)
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail=(
|
|
f"Failed to retrieve engines for year {year}, make {make_id}, model {model_id}, trim {trim_id}"
|
|
)
|
|
)
|