File size: 2,485 Bytes
9fb2c27
62f41ca
 
 
 
9fb2c27
62f41ca
 
9fb2c27
 
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
63
64
65
66
67
68
69
70
71
72
73
74
---
title: Scouting · Racing Santander
emoji: 
colorFrom: blue
colorTo: indigo
sdk: docker
app_port: 7860
pinned: true
---

# Scouting · Racing Santander

FastAPI + DuckDB scouting dashboard. Reuses the visual design of the static
HTML report but loads data from a Hugging Face Dataset and recomputes scoring
on the server.

## Required Space secrets

Set these in **Settings → Repository secrets** of the Space:

| Secret | Required | Purpose |
|---|---|---|
| `APP_PASSWORD` | yes | Shared password for the login gate |
| `SESSION_SECRET` | yes | Random string used to sign auth cookies |
| `DATASET_REPO_ID` | yes | HF dataset repo id, e.g. `racing-tools/scouting-data` |
| `HF_TOKEN` | yes if dataset is private | Read-scope token for the dataset repo |
| `DATA_MAX_AGE_HOURS` | no | Cache TTL before re-pulling the dataset (default 24) |

## Local development

```bash
cd scouting
# 1. produce parquets locally (one-time / on refresh)
python ingest_azure.py
python build_player_season.py
python enrich_attrs.py
python enrich_tm.py --skip-extra --limit 100

# 2. point app to the local data dir and run
export DATA_DIR=$(pwd)/data/clean
cd app && uvicorn main:app --reload --port 7860
```

Open http://localhost:7860/ — no `APP_PASSWORD` set means dev-mode (any
password is accepted on the login form, or skip if env unset).

## Refreshing data without a Docker rebuild

```bash
HF_TOKEN=hf_xxx python scripts/push_to_hf_dataset.py
```

Then restart the Space (Settings → Factory rebuild) — the next boot pulls the
new parquets via `huggingface_hub.snapshot_download`.

## Architecture

- `app/main.py` — FastAPI app, mounts static, registers routes
- `app/data.py` — DuckDB on parquet, registers `base` view joining player_season + tm_enrichment
- `app/scoring.py` — wraps `scouting_score.py` for in-memory scoring with custom weights
- `app/auth.py` — signed-cookie shared-password gate
- `app/routes/` — meta / score / player / best11 endpoints
- `app/static/` — extracted HTML, CSS, JS from `generate_report.py` with `fetch()` calls

## API quick reference

- `GET /api/meta` — seasons, leagues, positions, blocks
- `POST /api/score` — filtered + scored player-season rows
- `GET /api/player/{playerId}?season=24-25` — full detail
- `POST /api/best11` — top-1 per pitch slot
- `POST /api/login` — set auth cookie
- `GET /api/auth-status` — whether the current session is authenticated
- `GET /healthz` — bypasses auth, returns row counts