from __future__ import annotations from fastapi import APIRouter, FastAPI, Request from fastapi.responses import JSONResponse from starlette.exceptions import HTTPException as StarletteHTTPException from web.api import db ENDPOINTS = [ "/api/tss/info", "/api/tss/live", "/api/tss/player/{uid}", "/api/tss/player/{uid}/games", "/api/tss/player/{uid}/history", "/api/tss/search/{nick}", "/api/tss/match/{session_id}", "/api/tss/match/{session_id}/scoreboard", "/api/tss/matches/search", "/api/tss/maps", "/api/tss/leaderboard/players", "/api/tss/leaderboard/vehicles", "/api/tss/leaderboard/stats", "/api/tss/tournaments", "/api/tss/tournament/{id}", "/api/tss/tournament/{id}/standings", "/api/tss/tournament/{id}/matches", ] info_router = APIRouter() @info_router.get("/api/tss/info") async def info() -> dict: matches = await db.query_one(db.battles_path(), "SELECT COUNT(*) c FROM match_summary") pg = await db.query_one(db.battles_path(), "SELECT COUNT(*) c FROM player_games_hist") tn = await db.query_one(db.tournaments_path(), "SELECT COUNT(*) c FROM tournaments") return { "service": "tss", "counts": { "matches": matches["c"] if matches else 0, "player_games": pg["c"] if pg else 0, "tournaments": tn["c"] if tn else 0, }, "endpoints": ENDPOINTS, } def create_app() -> FastAPI: app = FastAPI(title="TSS HTTP API", version="1.0.0") @app.exception_handler(StarletteHTTPException) async def _err(_: Request, exc: StarletteHTTPException) -> JSONResponse: detail = exc.detail body = detail if isinstance(detail, dict) else {"error": str(detail)} return JSONResponse(status_code=exc.status_code, content=body) app.include_router(info_router) from web.api.routes_players import router as players_router from web.api.routes_matches import router as matches_router from web.api.routes_leaderboard import router as lb_router from web.api.routes_tournaments import router as tour_router app.include_router(players_router) app.include_router(matches_router) app.include_router(lb_router) app.include_router(tour_router) return app app = create_app()