statistics.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import json
  2. from pathlib import Path
  3. from fastapi import APIRouter, Depends, HTTPException
  4. from fastapi.responses import HTMLResponse
  5. from ..core.config import get_settings
  6. from ..db_models.internal import UsuarioAdmin
  7. from ..dependencies import get_current_admin
  8. router = APIRouter(prefix="/statistics", tags=["Estadísticas"])
  9. settings = get_settings()
  10. STATS_DIR = Path(settings.models_base_path) / "statistics"
  11. FIGURES_DIR = STATS_DIR / "iframe_figures"
  12. DASHBOARDS: dict[str, str] = {
  13. "attendance": "dashboard_attendance.json",
  14. "demographics": "dashboard_demographics.json",
  15. "school_group": "dashboard_school_group.json",
  16. "student_performance": "dashboard_student_performance.json",
  17. "subject_performance": "dashboard_subject_performance.json",
  18. "support": "dashboard_support.json",
  19. "term_progression": "dashboard_term_progression.json",
  20. }
  21. @router.get("/", summary="Lista de dashboards y figuras disponibles")
  22. def list_statistics(_: UsuarioAdmin = Depends(get_current_admin)):
  23. figures = sorted(f.stem for f in FIGURES_DIR.glob("*.html")) if FIGURES_DIR.exists() else []
  24. return {
  25. "dashboards": list(DASHBOARDS.keys()),
  26. "iframe_figures": figures,
  27. }
  28. @router.get("/{name}", summary="Datos Plotly JSON de un dashboard estadístico")
  29. def get_dashboard(name: str, _: UsuarioAdmin = Depends(get_current_admin)):
  30. if name not in DASHBOARDS:
  31. raise HTTPException(
  32. status_code=404,
  33. detail=f"Dashboard '{name}' no encontrado. Disponibles: {list(DASHBOARDS.keys())}",
  34. )
  35. path = STATS_DIR / DASHBOARDS[name]
  36. return json.loads(path.read_text(encoding="utf-8"))
  37. @router.get("/figures/{name}", response_class=HTMLResponse, summary="Figura interactiva HTML (iframe)")
  38. def get_figure(name: str, _: UsuarioAdmin = Depends(get_current_admin)):
  39. path = FIGURES_DIR / f"{name}.html"
  40. if not path.exists():
  41. available = sorted(f.stem for f in FIGURES_DIR.glob("*.html"))
  42. raise HTTPException(
  43. status_code=404,
  44. detail=f"Figura '{name}' no encontrada. Disponibles: {available}",
  45. )
  46. return HTMLResponse(content=path.read_text(encoding="utf-8"))