import logging from fastapi import FastAPI, Request, HTTPException from fastapi.responses import FileResponse, JSONResponse from fastapi.staticfiles import StaticFiles from fastapi.middleware.cors import CORSMiddleware # Optional: If needed later # Import the data loading function from data.py from .data import get_sorted_leaderboard_data # Configure logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) app = FastAPI(title="Leaderboard API") try: app.mount("/static", StaticFiles(directory="static"), name="static") except RuntimeError: logger.warning("Static directory not found or is invalid. Static files (CSS, JS) may not be served.") @app.get("/", include_in_schema=False) async def read_index(): """Serves the main index.html file.""" logger.info("Serving index.html") # Ensure index.html exists at the root level alongside the 'app' folder try: return FileResponse('index.html', media_type='text/html') except RuntimeError as e: logger.error(f"Error serving index.html: {e}. Make sure index.html exists in the root directory.") raise HTTPException(status_code=500, detail="Frontend file not found.") @app.get("/api/leaderboard") async def get_leaderboard(): """Returns the sorted leaderboard data.""" logger.info("Request received for /api/leaderboard") try: data = get_sorted_leaderboard_data() return JSONResponse(content=data) except HTTPException as http_exc: # Forward HTTPException raised by data loading function logger.error(f"HTTPException during data retrieval: {http_exc.detail}") raise http_exc except Exception as e: # Catch any other unexpected errors during data retrieval logger.error(f"Unexpected error getting leaderboard data: {e}", exc_info=True) raise HTTPException(status_code=500, detail="An internal error occurred while retrieving leaderboard data.") # Health check endpoint (optional but good practice) @app.get("/health") async def health_check(): return {"status": "ok"} # Example of adding a custom exception handler (optional) @app.exception_handler(Exception) async def general_exception_handler(request: Request, exc: Exception): logger.error(f"Unhandled exception for request {request.url}: {exc}", exc_info=True) return JSONResponse( status_code=500, content={"message": "An internal server error occurred."}, ) if __name__ == "__main__": # This block is mainly for local development, uvicorn command is used in Docker import uvicorn uvicorn.run(app, host="0.0.0.0", port=7860)