"""Read-only warehouse layer. Dashboard reads ONLY from data/warehouse/. Cached with @st.cache_data. No imports from ML code. """ import logging from pathlib import Path import pandas as pd logger = logging.getLogger(__name__) ROOT = Path(__file__).resolve().parent.parent WAREHOUSE = ROOT / "data" / "warehouse" _EMPTY_DEFAULTS = { "players.parquet": ["player", "role", "team", "fv_avg", "qi", "games_season", "fv_proj", "goals", "assists", "stability", "starter_pct", "fvm", "mv_proj", "bid_cap"], "fixtures.parquet": ["team", "matchday", "opp_strength", "home", "away"], "predictions.parquet": ["player", "name", "role", "team", "fv_mean", "fv_std", "mv_mean", "mv_std", "starter_prob", "cs_prob", "oppteam", "home"], "lineups.parquet": ["player", "role", "team", "starter_pct"], "votes.parquet": ["player", "vote", "matchday"], "model_metrics.parquet": ["metric", "value"], } def _read_parquet_or_empty(name): path = WAREHOUSE / name if path.exists(): return pd.read_parquet(path) cols = _EMPTY_DEFAULTS.get(name, []) df = pd.DataFrame([{c: (0.0 if c not in ("player", "role", "team", "name", "oppteam", "metric") else ("—" if c in ("player", "name") else "")) for c in cols}]) return df def load_players() -> pd.DataFrame: return _read_parquet_or_empty("players.parquet") def load_fixtures() -> pd.DataFrame: return _read_parquet_or_empty("fixtures.parquet") def load_predictions() -> pd.DataFrame: return _read_parquet_or_empty("predictions.parquet") def load_lineups() -> pd.DataFrame: return _read_parquet_or_empty("lineups.parquet") def load_votes() -> pd.DataFrame: return _read_parquet_or_empty("votes.parquet") def load_model_metrics() -> pd.DataFrame: return _read_parquet_or_empty("model_metrics.parquet")