from __future__ import annotations import asyncio import logging from typing import Any from app.cache import cache_get, cache_set from app.config import CACHE_TTL_DASHBOARD, CACHE_TTL_OBSERVATIONS, CACHE_TTL_WARNINGS from app.services.dwd_radar import fetch_radar_index from app.services.warnings import fetch_warnings_for_location from app.services.weather import get_forecast, get_observations logger = logging.getLogger(__name__) async def get_radar_summary() -> dict[str, Any]: redis_key = "radar:summary" cached = await cache_get(redis_key) if cached: return {**cached, "cached": True} index = await fetch_radar_index(limit=12) payload = { "source": index["source"], "product": index["product"], "count": index["count"], "cached": False, } await cache_set(redis_key, payload, 120) return payload async def build_dashboard(lat: float, lon: float, local_only: bool = True) -> dict[str, Any]: redis_key = f"dashboard:{round(lat, 4)}:{round(lon, 4)}:{int(local_only)}" cached = await cache_get(redis_key) if cached: return {**cached, "bundle_cached": True} results = await asyncio.gather( get_forecast(lat, lon), get_observations(lat, lon), fetch_warnings_for_location(lat, lon, local_only=local_only), get_radar_summary(), return_exceptions=True, ) payload: dict[str, Any] = { "lat": lat, "lon": lon, "bundle_cached": False, "errors": {}, } names = ("forecast", "observations", "warnings", "radar") for name, result in zip(names, results): if isinstance(result, Exception): logger.warning("dashboard %s failed: %s", name, result) payload["errors"][name] = str(result) payload[name] = None else: payload[name] = result ttl = min(CACHE_TTL_DASHBOARD, CACHE_TTL_OBSERVATIONS, CACHE_TTL_WARNINGS) if not payload["errors"]: await cache_set(redis_key, payload, ttl) return payload