--- title: Reportes Racing emoji: ⚽ colorFrom: green colorTo: gray sdk: docker app_port: 7860 pinned: false --- # Reportes Racing Web privada para generar los reportes tácticos reales (pre-partido / head-to-head, post-partido y bloques z-score) sin setup local. La data se descarga desde Azure Data Lake; nada de datos en el repo. ## Cómo se usa (gente no técnica) 1. Abrir el link del Space (te invitan con tu cuenta de Hugging Face) e ingresar la contraseña si la web la pide. 2. **Reporte previo / Bloques**: elegir Equipo A y Equipo B (cualquier par, aunque no se hayan jugado), opcionalmente fechas desde/hasta para Bloques, y tildar qué reportes querés. Click en *Generar*. 3. **Reporte post-partido**: tocar *Cargar lista de partidos jugados*, elegir el partido y *Generar post-partido* (corre también el previo de ese partido automáticamente). 4. Aparece una pantalla de progreso que se actualiza sola. Puede tardar varios minutos (especialmente la primera vez del día). Al terminar muestra los links para **Ver** y **Descargar** cada reporte. ## Deploy en Hugging Face Spaces (privado) 1. Crear un Space tipo **Docker**, visibilidad **Private**. 2. Conectarlo a este repo (o `git push` al remoto del Space). 3. En *Settings → Variables and secrets* cargar los secrets de Azure (Service Principal con permiso de lectura sobre el Data Lake): ``` AZURE_TENANT_ID=... AZURE_CLIENT_ID=... AZURE_CLIENT_SECRET=... AZURE_STORAGE_ACCOUNT=stdlprodfrancecentral001 AZURE_FILESYSTEM=fs-dl-prod-francecentral-001 AZURE_PREPROCESSED_ROOT=raw/eventing/processed AZURE_REPORT_ARTIFACTS_ROOT=raw/eventing/report_artifacts ACCESS_PASSWORD=una-clave-compartida # opcional, candado extra ``` 4. Build automático. El disco del Space es efímero: en un arranque en frío se vuelven a descargar los datasets desde Azure (lento la primera vez, luego queda cacheado mientras el Space siga vivo). Invitar a la gente al Space privado = control de acceso. ## Uso local (desarrollo) ```bash python -m venv .venv && source .venv/bin/activate pip install -e ".[dev]" cp .env.sample .env # editar credenciales az login # auth local (sin Service Principal) racing-reports-web # http://127.0.0.1:7860 ``` Para correr sin Azure (con datos ya locales) exportar `RACING_LOCAL_DATA_DIR=/ruta/con/preprocessed+artifacts`. ## Prerrequisito de datos en Azure Los reportes reales necesitan, además del preprocessed base, artifacts pesados y el preprocessed **etiquetado**. Subirlos una vez con: ```bash python scripts/upload_report_artifacts.py # parquets + bundles GNN python ../scripts/upload_preprocessed_labeled.py \ --local-path /ruta/preprocessed_..._etiquetado_final.csv \ --remote-name preprocessed_SSD_25-26_etiquetado_modelo.csv ``` ## Modelo de predicción de ataque (matchup GNN) El reporte previo / head-to-head puede mostrar la **distribución de ataque esperada por zona** (local y visitante) según un modelo de red neuronal. El modelo de producción es el **matchup GNN** (`train_attack_matchup_gnn.py`), que reemplaza al viejo `attack_distribution_gnn`: selecciona ~200 features de alta señal (en vez de ~950, atacando el sobreajuste), agrega una interacción bilineal explícita atacante × defensor por zona, y aprende un *delta* sobre el promedio del equipo. En test le gana al baseline "promedio de temporada" de forma estadísticamente robusta (IC bootstrap del 95% que excluye el cero). Las predicciones están **apagadas por defecto** (MVP). Hay dos formas de servir los artifacts del modelo; en ambas se activa con el secret `RR_ENABLE_NN_PREDICTIONS=1` en el Space. **Opción A — bundlear en el repo (sin Azure, recomendada).** El datastore usa los artifacts reales de `vendor/data/modeling/` antes de ir a Azure. Como la app recalcula los rolling al vuelo desde las columnas crudas, el dataset se recorta de **71 MB → ~10 MB** sin cambiar ninguna predicción: ```bash python ../scripts/build_app_modeling_subset.py --copy-bundles git add racing-reports/vendor/data/modeling/{attack_prediction_dataset.parquet,attack_matchup_gnn_bundle.pt,pv_distribution_gnn_bundle.pt} git commit -m "bundle modelo de ataque" # parquet ~10 MB: usar git-lfs si tu remoto lo pide ``` En el próximo arranque la app usa esos archivos directamente, sin tocar Azure. **Opción B — subir a Azure.** Si preferís no commitear artifacts: ```bash RR_ENABLE_NN_PREDICTIONS=1 python scripts/upload_report_artifacts.py --source /ruta/Racing/data --overwrite ``` En el cold start la app descarga `modeling/attack_matchup_gnn_bundle.pt` (y el de PV + el dataset) desde Azure. ## Actualizar la data y el modelo (pipeline) Un solo orquestador idempotente encadena todo el ciclo, desde los eventos crudos hasta el bundle publicado que consume la app: ```bash python ../scripts/run_attack_model_pipeline.py # todo (saltea lo que ya está al día) python ../scripts/run_attack_model_pipeline.py --list # ver los stages python ../scripts/run_attack_model_pipeline.py --only train --train-args "--top-k 200 --seeds 3" python ../scripts/run_attack_model_pipeline.py --from dataset --force ``` Stages: `events` → `zone_features` → `dataset` → `rolling` → `train` → `publish`. Los stages `events` y `publish` requieren credenciales de Azure. ## Salida ```text {RACING_REPORTS_OUTPUT_DIR}/{league}/{season}/{slug}/{report}.html {RACING_REPORTS_OUTPUT_DIR}/{league}/{season}/{slug}/manifest.json ```