"""Routes for macroeconomic data (FRED-powered).""" import functools import logging from collections.abc import Awaitable, Callable from typing import ParamSpec, TypeVar from fastapi import APIRouter, HTTPException, Query from models import ApiResponse import macro_service logger = logging.getLogger(__name__) router = APIRouter(prefix="/api/v1") P = ParamSpec("P") R = TypeVar("R") def _safe(fn: Callable[P, Awaitable[R]]) -> Callable[P, Awaitable[R]]: @functools.wraps(fn) async def wrapper(*args: P.args, **kwargs: P.kwargs) -> R: try: return await fn(*args, **kwargs) except HTTPException: raise except Exception: logger.exception("Upstream data error") raise HTTPException( status_code=502, detail="Data provider error. Check server logs.", ) return wrapper # type: ignore[return-value] @router.get("/macro/overview", response_model=ApiResponse) @_safe async def macro_overview(): """Get key macro indicators: Fed rate, treasury yields, CPI, unemployment, GDP, VIX.""" data = await macro_service.get_macro_overview() return ApiResponse(data=data) @router.get("/macro/series/{series_id}", response_model=ApiResponse) @_safe async def macro_series( series_id: str, limit: int = Query(default=30, ge=1, le=1000), ): """Get a specific FRED time series by ID.""" data = await macro_service.get_series(series_id, limit=limit) return ApiResponse(data=data)