# services/external/app/api/weather_data.py """ Weather Data API - Atomic CRUD operations on WeatherData model """ from fastapi import APIRouter, Depends, HTTPException, Query, Path from typing import List, Optional from datetime import date from uuid import UUID import structlog from app.schemas.weather import WeatherDataResponse from app.services.weather_service import WeatherService from shared.routing.route_builder import RouteBuilder from sqlalchemy.ext.asyncio import AsyncSession from app.core.database import get_db route_builder = RouteBuilder('external') router = APIRouter(tags=["weather-data"]) logger = structlog.get_logger() def get_weather_service(): """Dependency injection for WeatherService""" return WeatherService() @router.get( route_builder.build_base_route("weather-data"), response_model=List[WeatherDataResponse] ) async def list_weather_data( tenant_id: UUID = Path(..., description="Tenant ID"), start_date: Optional[date] = Query(None), end_date: Optional[date] = Query(None), latitude: Optional[float] = Query(None), longitude: Optional[float] = Query(None), limit: int = Query(100, ge=1, le=1000), db: AsyncSession = Depends(get_db), weather_service: WeatherService = Depends(get_weather_service) ): """List stored weather data records""" try: logger.info("Listing weather data", tenant_id=tenant_id) weather_records = await weather_service.get_stored_weather_data( tenant_id=tenant_id, start_date=start_date, end_date=end_date, latitude=latitude, longitude=longitude, limit=limit, db=db ) return weather_records except Exception as e: logger.error("Failed to list weather data", error=str(e), tenant_id=tenant_id) raise HTTPException(status_code=500, detail="Failed to retrieve weather data") @router.get( route_builder.build_resource_detail_route("weather-data", "weather_id"), response_model=WeatherDataResponse ) async def get_weather_data( tenant_id: UUID = Path(..., description="Tenant ID"), weather_id: UUID = Path(..., description="Weather data ID"), db: AsyncSession = Depends(get_db), weather_service: WeatherService = Depends(get_weather_service) ): """Get a specific weather data record""" try: logger.info("Getting weather data", tenant_id=tenant_id, weather_id=weather_id) weather_record = await weather_service.get_weather_data_by_id( tenant_id=tenant_id, weather_id=weather_id, db=db ) if not weather_record: raise HTTPException(status_code=404, detail="Weather data not found") return weather_record except HTTPException: raise except Exception as e: logger.error("Failed to get weather data", error=str(e), tenant_id=tenant_id) raise HTTPException(status_code=500, detail="Failed to retrieve weather data") @router.delete( route_builder.build_resource_detail_route("weather-data", "weather_id") ) async def delete_weather_data( tenant_id: UUID = Path(..., description="Tenant ID"), weather_id: UUID = Path(..., description="Weather data ID"), db: AsyncSession = Depends(get_db), weather_service: WeatherService = Depends(get_weather_service) ): """Delete a weather data record""" try: logger.info("Deleting weather data", tenant_id=tenant_id, weather_id=weather_id) success = await weather_service.delete_weather_data( tenant_id=tenant_id, weather_id=weather_id, db=db ) if not success: raise HTTPException(status_code=404, detail="Weather data not found") return {"message": "Weather data deleted successfully"} except HTTPException: raise except Exception as e: logger.error("Failed to delete weather data", error=str(e), tenant_id=tenant_id) raise HTTPException(status_code=500, detail="Failed to delete weather data")