File size: 2,648 Bytes
a683532
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cc5354e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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)