REFACTOR external service and improve websocket training

This commit is contained in:
Urtzi Alfaro
2025-10-09 14:11:02 +02:00
parent 7c72f83c51
commit 3c689b4f98
111 changed files with 13289 additions and 2374 deletions

View File

@@ -9,7 +9,7 @@ import structlog
from app.models.weather import WeatherData, WeatherForecast
from app.external.aemet import AEMETClient
from app.schemas.weather import WeatherDataResponse, WeatherForecastResponse, HourlyForecastResponse
from app.schemas.weather import WeatherDataResponse, WeatherForecastResponse, WeatherForecastAPIResponse, HourlyForecastResponse
from app.repositories.weather_repository import WeatherRepository
logger = structlog.get_logger()
@@ -58,23 +58,26 @@ class WeatherService:
source="error"
)
async def get_weather_forecast(self, latitude: float, longitude: float, days: int = 7) -> List[WeatherForecastResponse]:
"""Get weather forecast for location"""
async def get_weather_forecast(self, latitude: float, longitude: float, days: int = 7) -> List[Dict[str, Any]]:
"""Get weather forecast for location - returns plain dicts"""
try:
logger.debug("Getting weather forecast", lat=latitude, lon=longitude, days=days)
forecast_data = await self.aemet_client.get_forecast(latitude, longitude, days)
if forecast_data:
logger.debug("Forecast data received", count=len(forecast_data))
# Validate each forecast item before creating response
# Validate and normalize each forecast item
valid_forecasts = []
for item in forecast_data:
try:
if isinstance(item, dict):
# Ensure required fields are present
# Ensure required fields are present and convert to serializable format
forecast_date = item.get("forecast_date", datetime.now())
generated_at = item.get("generated_at", datetime.now())
forecast_item = {
"forecast_date": item.get("forecast_date", datetime.now()),
"generated_at": item.get("generated_at", datetime.now()),
"forecast_date": forecast_date.isoformat() if isinstance(forecast_date, datetime) else str(forecast_date),
"generated_at": generated_at.isoformat() if isinstance(generated_at, datetime) else str(generated_at),
"temperature": float(item.get("temperature", 15.0)),
"precipitation": float(item.get("precipitation", 0.0)),
"humidity": float(item.get("humidity", 50.0)),
@@ -82,19 +85,19 @@ class WeatherService:
"description": str(item.get("description", "Variable")),
"source": str(item.get("source", "unknown"))
}
valid_forecasts.append(WeatherForecastResponse(**forecast_item))
valid_forecasts.append(forecast_item)
else:
logger.warning("Invalid forecast item type", item_type=type(item))
except Exception as item_error:
logger.warning("Error processing forecast item", error=str(item_error), item=item)
continue
logger.debug("Valid forecasts processed", count=len(valid_forecasts))
return valid_forecasts
else:
logger.warning("No forecast data received from AEMET client")
return []
except Exception as e:
logger.error("Failed to get weather forecast", error=str(e), lat=latitude, lon=longitude)
return []