File size: 2,059 Bytes
62f41ca 695067b 62f41ca 695067b 62f41ca 1fcef7f 62f41ca 1fcef7f 62f41ca | 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 | """
FastAPI entrypoint for the Scouting · Racing Santander Space.
"""
import os
import warnings
from pathlib import Path
# Cosmetic: pandas PerformanceWarning when scoring 10k+ row dfs (we add columns
# one-by-one — copies the frame internally; cost is a few ms per request).
warnings.filterwarnings('ignore', category=Warning, module='pandas')
warnings.filterwarnings('ignore', message='.*highly fragmented.*')
from fastapi import FastAPI, Request
from fastapi.responses import FileResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
from auth import AuthMiddleware, register_auth_routes
from data import bootstrap_data, get_meta
from routes.meta import router as meta_router
from routes.rows import router as rows_router
from routes.player import router as player_router
APP_DIR = Path(__file__).parent
STATIC_DIR = APP_DIR / 'static'
app = FastAPI(title='Scouting · Racing Santander', docs_url='/api/docs', redoc_url=None)
# Bootstrap data (HF download if needed) before serving requests.
bootstrap_data()
# Auth — wraps everything except /api/login and the static index page (it shows the login form itself).
app.add_middleware(AuthMiddleware)
register_auth_routes(app)
app.include_router(meta_router, prefix='/api')
app.include_router(rows_router, prefix='/api')
app.include_router(player_router, prefix='/api')
@app.get('/healthz')
def healthz():
meta = get_meta()
return {'ok': True, 'players': meta['n_players'], 'leagues': len(meta['leagues'])}
# Static assets (CSS, JS, images)
app.mount('/static', StaticFiles(directory=STATIC_DIR), name='static')
@app.get('/')
def index():
return FileResponse(STATIC_DIR / 'index.html')
@app.exception_handler(401)
async def unauthorized_handler(request: Request, exc):
# for HTML routes return the index (frontend renders the login modal on 401 fetch)
if request.url.path == '/' or request.url.path.startswith('/static'):
return FileResponse(STATIC_DIR / 'index.html')
return JSONResponse(status_code=401, content={'detail': 'unauthorized'})
|