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'})