Yash030/claude-code-proxy
2
1"""Admin dashboard for session monitoring."""2 3import time4from typing import Any5 6from fastapi import APIRouter, Depends, Request7from starlette.responses import HTMLResponse8from starlette.templating import Jinja2Templates9 10from core.session_tracker import SessionTracker11 12from .dependencies import require_api_key13 14router = APIRouter()15 16templates = Jinja2Templates(directory="templates")17 18 19def _get_blocked_providers() -> set[str]:20 """Get currently blocked provider IDs. Placeholder - returns empty set."""21 return set()22 23 24def _format_time(seconds: float) -> str:25 """Format seconds as human-readable string."""26 if seconds < 60:27 return f"{int(seconds)}s ago"28 elif seconds < 3600:29 return f"{int(seconds // 60)}m ago"30 else:31 return f"{int(seconds // 3600)}h ago"32 33 34def _get_admin_data() -> dict[str, Any]:35 """Gather all data for the admin dashboard."""36 tracker = SessionTracker.get_instance()37 blocked = _get_blocked_providers()38 39 session_loads = tracker.get_all_session_loads()40 provider_loads = tracker.get_all_provider_loads(blocked)41 42 now = time.monotonic()43 44 total_requests = 045 all_providers = set()46 sessions_list = []47 48 for session_id, load in session_loads.items():49 total_requests += load.total_requests50 all_providers.update(load.providers.keys())51 52 state = tracker._sessions.get(session_id)53 last_activity_seconds = 0.054 if state:55 last_activity_seconds = now - state.last_request_time56 57 req_per_min = 0.058 if state and state.requests_in_window > 0:59 req_per_min = (state.requests_in_window / tracker._window_seconds) * 6060 61 sessions_list.append(62 {63 "session_id": session_id,64 "total_requests": load.total_requests,65 "providers": list(load.providers.keys()),66 "last_activity_seconds": last_activity_seconds,67 "last_activity_display": _format_time(last_activity_seconds),68 "requests_per_minute": int(req_per_min),69 "status": "Active" if last_activity_seconds < 300 else "Idle",70 "status_class": "status-active"71 if last_activity_seconds < 30072 else "status-idle",73 }74 )75 76 providers_list = []77 for provider_id, load in provider_loads.items():78 remaining = 079 if provider_id in blocked:80 remaining = 30 # placeholder, real impl would check rate limiter81 status = "Rate Limited" if not load.is_healthy else "Healthy"82 if not load.is_healthy and remaining > 0:83 status += f" ({remaining}s remaining)"84 85 providers_list.append(86 {87 "provider_id": provider_id,88 "active_requests": load.active_requests,89 "sessions_count": load.session_count,90 "requests_per_minute": int(load.requests_per_minute),91 "is_healthy": load.is_healthy,92 "status": status,93 }94 )95 96 return {97 "summary": {98 "active_sessions": len(session_loads),99 "total_requests": total_requests,100 "providers": len(all_providers),101 },102 "sessions": sessions_list,103 "providers": providers_list,104 }105 106 107@router.get("/admin", response_class=HTMLResponse)108async def admin_dashboard(109 request: Request,110 _auth=Depends(require_api_key),111):112 """Admin dashboard HTML page."""113 data = _get_admin_data()114 return templates.TemplateResponse("admin.html", {"request": request, **data})115 116 117@router.get("/api/admin/sessions")118async def admin_sessions_json(119 _auth=Depends(require_api_key),120):121 """JSON API for session data (for external tools)."""122 return _get_admin_data()123 