"""Admin router module for managing Aider sessions and configurations.""" import os import shutil import tempfile from fastapi import APIRouter, Depends, HTTPException, Security from fastapi.security import APIKeyHeader from app.core.config import settings from app.models.admin import ConfigResponse, ConfigUpdate, SessionInfo, SessionList router = APIRouter(prefix="/admin", tags=["admin"]) # Security API_KEY_NAME = "X-API-Key" api_key_header = APIKeyHeader(name=API_KEY_NAME) # Define dependency outside of function signature verify_admin_dep = Security(api_key_header) async def verify_admin_key(api_key: str = verify_admin_dep) -> str: """Verify the admin API key.""" if api_key != settings.ADMIN_API_KEY: raise HTTPException(status_code=403, detail="Invalid API key") return api_key @router.get("/sessions", response_model=SessionList) async def list_sessions(api_key: str = Depends(verify_admin_key)) -> SessionList: """List all active Aider sessions.""" sessions = [] temp_dir = tempfile.gettempdir() for dir_name in os.listdir(temp_dir): if dir_name.startswith(settings.TEMP_DIR_PREFIX): session_path = os.path.join(temp_dir, dir_name) if os.path.isdir(session_path): sessions.append( SessionInfo( id=dir_name, path=session_path, created_at=os.path.getctime(session_path), size=sum( os.path.getsize(os.path.join(session_path, f)) for f in os.listdir(session_path) if os.path.isfile(os.path.join(session_path, f)) ), ) ) return SessionList(sessions=sessions) @router.delete("/sessions/{session_id}") async def delete_session( session_id: str, api_key: str = Depends(verify_admin_key) ) -> dict: """Delete a specific Aider session.""" session_path = os.path.join(tempfile.gettempdir(), session_id) if not os.path.exists(session_path): raise HTTPException(status_code=404, detail="Session not found") try: shutil.rmtree(session_path) return {"message": "Session deleted successfully"} except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.delete("/sessions") async def delete_all_sessions(api_key: str = Depends(verify_admin_key)) -> dict: """Delete all Aider sessions.""" temp_dir = tempfile.gettempdir() deleted_count = 0 for dir_name in os.listdir(temp_dir): if dir_name.startswith(settings.TEMP_DIR_PREFIX): session_path = os.path.join(temp_dir, dir_name) if os.path.isdir(session_path): try: shutil.rmtree(session_path) deleted_count += 1 except Exception as e: raise HTTPException(status_code=500, detail=str(e)) return {"message": f"Deleted {deleted_count} sessions"} @router.get("/config", response_model=ConfigResponse) async def get_config(api_key: str = Depends(verify_admin_key)) -> ConfigResponse: """Get current configuration settings.""" masked_key = ( settings.OPENAI_API_KEY[:8] + "..." if settings.OPENAI_API_KEY else None ) return ConfigResponse( openai_api_key=masked_key, aider_model=settings.AIDER_MODEL, temp_dir_prefix=settings.TEMP_DIR_PREFIX, ) @router.put("/config") async def update_config( config: ConfigUpdate, api_key: str = Depends(verify_admin_key) ) -> dict: """Update configuration settings.""" if config.openai_api_key: settings.OPENAI_API_KEY = config.openai_api_key if config.aider_model: settings.AIDER_MODEL = config.aider_model if config.temp_dir_prefix: settings.TEMP_DIR_PREFIX = config.temp_dir_prefix return {"message": "Configuration updated successfully"}