Fix Data API

This commit is contained in:
Urtzi Alfaro
2025-07-19 12:09:10 +02:00
parent ff8a632915
commit 72a7c0a0a6
9 changed files with 814 additions and 950 deletions

View File

@@ -1,12 +1,13 @@
# ================================================================
# services/data/app/api/weather.py
# services/data/app/api/weather.py - FIXED VERSION
# ================================================================
"""Weather data API endpoints"""
"""Weather data API endpoints with improved error handling"""
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List, Optional
from datetime import datetime, timedelta
import structlog
from app.core.database import get_db
from app.core.auth import get_current_user, AuthInfo
@@ -21,6 +22,7 @@ from app.schemas.external import (
router = APIRouter()
weather_service = WeatherService()
logger = structlog.get_logger()
@router.get("/current", response_model=WeatherDataResponse)
async def get_current_weather(
@@ -30,13 +32,25 @@ async def get_current_weather(
):
"""Get current weather for location"""
try:
logger.debug("API: Getting current weather", lat=latitude, lon=longitude)
weather = await weather_service.get_current_weather(latitude, longitude)
if not weather:
logger.warning("No weather data available", lat=latitude, lon=longitude)
raise HTTPException(status_code=404, detail="Weather data not available")
logger.debug("Successfully returning weather data", temp=weather.temperature)
return weather
except HTTPException:
# Re-raise HTTP exceptions
raise
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
logger.error("Unexpected error in weather API", error=str(e))
import traceback
logger.error("Weather API traceback", traceback=traceback.format_exc())
raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
@router.get("/forecast", response_model=List[WeatherForecastResponse])
async def get_weather_forecast(
@@ -47,20 +61,38 @@ async def get_weather_forecast(
):
"""Get weather forecast for location"""
try:
logger.debug("API: Getting weather forecast", lat=latitude, lon=longitude, days=days)
forecast = await weather_service.get_weather_forecast(latitude, longitude, days)
# Publish event
await data_publisher.publish_weather_updated({
"type": "forecast_requested",
"latitude": latitude,
"longitude": longitude,
"days": days,
"timestamp": datetime.utcnow().isoformat()
})
if not forecast:
logger.warning("No forecast data available", lat=latitude, lon=longitude)
raise HTTPException(status_code=404, detail="Weather forecast not available")
# Publish event (with error handling)
try:
await data_publisher.publish_weather_updated({
"type": "forecast_requested",
"latitude": latitude,
"longitude": longitude,
"days": days,
"timestamp": datetime.utcnow().isoformat()
})
except Exception as pub_error:
logger.warning("Failed to publish weather forecast event", error=str(pub_error))
# Continue processing - event publishing failure shouldn't break the API
logger.debug("Successfully returning forecast data", count=len(forecast))
return forecast
except HTTPException:
# Re-raise HTTP exceptions
raise
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
logger.error("Unexpected error in weather forecast API", error=str(e))
import traceback
logger.error("Weather forecast API traceback", traceback=traceback.format_exc())
raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
@router.get("/historical", response_model=List[WeatherDataResponse])
async def get_historical_weather(
@@ -84,17 +116,68 @@ async def get_historical_weather(
latitude, longitude, start_date, end_date, db
)
# Publish event
await data_publisher.publish_weather_updated({
"type": "historical_requested",
"latitude": latitude,
"longitude": longitude,
"start_date": start_date.isoformat(),
"end_date": end_date.isoformat(),
"records_count": len(historical_data),
"timestamp": datetime.utcnow().isoformat()
})
# Publish event (with error handling)
try:
await data_publisher.publish_weather_updated({
"type": "historical_requested",
"latitude": latitude,
"longitude": longitude,
"start_date": start_date.isoformat(),
"end_date": end_date.isoformat(),
"records_count": len(historical_data),
"timestamp": datetime.utcnow().isoformat()
})
except Exception as pub_error:
logger.warning("Failed to publish historical weather event", error=str(pub_error))
# Continue processing
return historical_data
except HTTPException:
# Re-raise HTTP exceptions
raise
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
logger.error("Unexpected error in historical weather API", error=str(e))
raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
@router.post("/store")
async def store_weather_data(
latitude: float = Query(..., description="Latitude"),
longitude: float = Query(..., description="Longitude"),
db: AsyncSession = Depends(get_db),
current_user: AuthInfo = Depends(get_current_user)
):
"""Store current weather data to database"""
try:
# Get current weather data
weather = await weather_service.get_current_weather(latitude, longitude)
if not weather:
raise HTTPException(status_code=404, detail="No weather data to store")
# Convert to dict for storage
weather_dict = {
"date": weather.date,
"temperature": weather.temperature,
"precipitation": weather.precipitation,
"humidity": weather.humidity,
"wind_speed": weather.wind_speed,
"pressure": weather.pressure,
"description": weather.description,
"source": weather.source
}
success = await weather_service.store_weather_data(
latitude, longitude, weather_dict, db
)
if success:
return {"status": "success", "message": "Weather data stored successfully"}
else:
raise HTTPException(status_code=500, detail="Failed to store weather data")
except HTTPException:
raise
except Exception as e:
logger.error("Error storing weather data", error=str(e))
raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")