from typing import Any, Dict, List, cast from fastapi import APIRouter, HTTPException, Request, status from pydantic import BaseModel from config.database import SessionLocal from services.reporting import generate_report router = APIRouter(prefix="/api/reporting", tags=["Reporting"]) def get_db(): db = SessionLocal() try: yield db finally: db.close() def _validate_payload(payload: Any) -> List[Dict[str, float]]: if not isinstance(payload, list): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid input format", ) typed_payload = cast(List[Any], payload) validated: List[Dict[str, float]] = [] for index, item in enumerate(typed_payload): if not isinstance(item, dict): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Entry at index {index} must be an object", ) value = cast(Dict[str, Any], item).get("result") if not isinstance(value, (int, float)): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Entry at index {index} must include numeric 'result'", ) validated.append({"result": float(value)}) return validated class ReportSummary(BaseModel): count: int mean: float median: float min: float max: float std_dev: float variance: float percentile_10: float percentile_90: float percentile_5: float percentile_95: float value_at_risk_95: float expected_shortfall_95: float @router.post("/summary", response_model=ReportSummary) async def summary_report(request: Request): payload = await request.json() validated_payload = _validate_payload(payload) summary = generate_report(validated_payload) return ReportSummary( count=int(summary["count"]), mean=float(summary["mean"]), median=float(summary["median"]), min=float(summary["min"]), max=float(summary["max"]), std_dev=float(summary["std_dev"]), variance=float(summary["variance"]), percentile_10=float(summary["percentile_10"]), percentile_90=float(summary["percentile_90"]), percentile_5=float(summary["percentile_5"]), percentile_95=float(summary["percentile_95"]), value_at_risk_95=float(summary["value_at_risk_95"]), expected_shortfall_95=float(summary["expected_shortfall_95"]), )