"""Admin dashboard for session monitoring.""" import time from typing import Any from fastapi import APIRouter, Depends, Request from starlette.responses import HTMLResponse from starlette.templating import Jinja2Templates from core.session_tracker import SessionTracker from .dependencies import require_api_key router = APIRouter() templates = Jinja2Templates(directory="templates") def _get_blocked_providers() -> set[str]: """Get currently blocked provider IDs. Placeholder - returns empty set.""" return set() def _format_time(seconds: float) -> str: """Format seconds as human-readable string.""" if seconds < 60: return f"{int(seconds)}s ago" elif seconds < 3600: return f"{int(seconds // 60)}m ago" else: return f"{int(seconds // 3600)}h ago" def _get_admin_data() -> dict[str, Any]: """Gather all data for the admin dashboard.""" tracker = SessionTracker.get_instance() blocked = _get_blocked_providers() session_loads = tracker.get_all_session_loads() provider_loads = tracker.get_all_provider_loads(blocked) now = time.monotonic() total_requests = 0 all_providers = set() sessions_list = [] for session_id, load in session_loads.items(): total_requests += load.total_requests all_providers.update(load.providers.keys()) state = tracker._sessions.get(session_id) last_activity_seconds = 0.0 if state: last_activity_seconds = now - state.last_request_time req_per_min = 0.0 if state and state.requests_in_window > 0: req_per_min = (state.requests_in_window / tracker._window_seconds) * 60 sessions_list.append( { "session_id": session_id, "total_requests": load.total_requests, "providers": list(load.providers.keys()), "last_activity_seconds": last_activity_seconds, "last_activity_display": _format_time(last_activity_seconds), "requests_per_minute": int(req_per_min), "status": "Active" if last_activity_seconds < 300 else "Idle", "status_class": "status-active" if last_activity_seconds < 300 else "status-idle", } ) providers_list = [] for provider_id, load in provider_loads.items(): remaining = 0 if provider_id in blocked: remaining = 30 # placeholder, real impl would check rate limiter status = "Rate Limited" if not load.is_healthy else "Healthy" if not load.is_healthy and remaining > 0: status += f" ({remaining}s remaining)" providers_list.append( { "provider_id": provider_id, "active_requests": load.active_requests, "sessions_count": load.session_count, "requests_per_minute": int(load.requests_per_minute), "is_healthy": load.is_healthy, "status": status, } ) return { "summary": { "active_sessions": len(session_loads), "total_requests": total_requests, "providers": len(all_providers), }, "sessions": sessions_list, "providers": providers_list, } @router.get("/admin", response_class=HTMLResponse) async def admin_dashboard( request: Request, _auth=Depends(require_api_key), ): """Admin dashboard HTML page.""" data = _get_admin_data() return templates.TemplateResponse("admin.html", {"request": request, **data}) @router.get("/api/admin/sessions") async def admin_sessions_json( _auth=Depends(require_api_key), ): """JSON API for session data (for external tools).""" return _get_admin_data()