from typing import Any from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from app import crud from app.api import deps from app.db.session import get_db from app.models.user import User from app.schemas.weather import CurrentWeather, Forecast from app.services.cache_service import cache from app.services.weather_service import WeatherService router = APIRouter() @router.get("/current", response_model=CurrentWeather) async def get_current_weather( lat: float = Query(..., le=90, ge=-90, description="Latitude coordinate"), lon: float = Query(..., le=180, ge=-180, description="Longitude coordinate"), location_name: str = Query(None, description="Optional location name"), db: Session = Depends(get_db), current_user: User = Depends(deps.get_current_active_user), ) -> Any: """ Get current weather data for a specific location. """ # Create cache key cache_key = f"current_weather:{lat}:{lon}" # Check cache first cached_data = cache.get(cache_key) if cached_data: return cached_data # Fetch data from weather service weather_service = WeatherService() weather_data = await weather_service.get_current_weather( lat=lat, lon=lon, location_name=location_name ) # Cache the result cache.set(cache_key, weather_data) return weather_data @router.get("/current/default", response_model=CurrentWeather) async def get_current_weather_for_default_location( db: Session = Depends(get_db), current_user: User = Depends(deps.get_current_active_user), ) -> Any: """ Get current weather data for the user's default location. """ # Get user's default location default_location = crud.get_user_default_location(db, user_id=current_user.id) if not default_location: raise HTTPException( status_code=404, detail="No default location set for this user" ) # Create cache key cache_key = f"current_weather:{default_location.latitude}:{default_location.longitude}" # Check cache first cached_data = cache.get(cache_key) if cached_data: return cached_data # Fetch data from weather service weather_service = WeatherService() weather_data = await weather_service.get_current_weather( lat=default_location.latitude, lon=default_location.longitude, location_name=default_location.name ) # Cache the result cache.set(cache_key, weather_data) return weather_data @router.get("/forecast", response_model=Forecast) async def get_forecast( lat: float = Query(..., le=90, ge=-90, description="Latitude coordinate"), lon: float = Query(..., le=180, ge=-180, description="Longitude coordinate"), location_name: str = Query(None, description="Optional location name"), db: Session = Depends(get_db), current_user: User = Depends(deps.get_current_active_user), ) -> Any: """ Get 5-day weather forecast for a specific location. """ # Create cache key cache_key = f"forecast:{lat}:{lon}" # Check cache first cached_data = cache.get(cache_key) if cached_data: return cached_data # Fetch data from weather service weather_service = WeatherService() forecast_data = await weather_service.get_forecast( lat=lat, lon=lon, location_name=location_name ) # Cache the result cache.set(cache_key, forecast_data) return forecast_data @router.get("/forecast/default", response_model=Forecast) async def get_forecast_for_default_location( db: Session = Depends(get_db), current_user: User = Depends(deps.get_current_active_user), ) -> Any: """ Get 5-day weather forecast for the user's default location. """ # Get user's default location default_location = crud.get_user_default_location(db, user_id=current_user.id) if not default_location: raise HTTPException( status_code=404, detail="No default location set for this user" ) # Create cache key cache_key = f"forecast:{default_location.latitude}:{default_location.longitude}" # Check cache first cached_data = cache.get(cache_key) if cached_data: return cached_data # Fetch data from weather service weather_service = WeatherService() forecast_data = await weather_service.get_forecast( lat=default_location.latitude, lon=default_location.longitude, location_name=default_location.name ) # Cache the result cache.set(cache_key, forecast_data) return forecast_data