Pregame_MLB_Report / README.md
JakeR3's picture
Upload 3 files
526acc6 verified
|
Raw
History Blame Contribute Delete
3.14 kB
---
title: MLB Pregame Dashboard
emoji:
colorFrom: blue
colorTo: indigo
sdk: gradio
sdk_version: "5.23.3"
python_version: "3.10"
app_file: app.py
pinned: false
---
# MLB Pregame Dashboard
A compact, data-dense Gradio web app for pregame analysis.
## Quick Start
```bash
pip install -r requirements.txt
python app.py
# → open http://localhost:7860
```
## File Structure
```
pregame_dashboard/
├── app.py # Gradio UI — layout, callbacks, HTML builders
├── chart_builder.py # Plotly figure factories (innings, pitch count, velo)
├── data_fetcher.py # All data sources: pybaseball, StatsAPI, RotoGrinders
├── requirements.txt
└── README.md
```
## Data Sources & What Each Provides
| Source | What | How |
|--------|------|-----|
| **MLB StatsAPI** (`MLB-StatsAPI` pkg) | Schedule, confirmed lineups, live game state, score, inning | `statsapi.schedule()`, `statsapi.boxscore_data()` |
| **Baseball Savant** (`pybaseball`) | Statcast: xwOBA splits, FB velocity, pitcher pitch-by-pitch | `pyb.statcast_batter()`, `pyb.statcast_pitcher()` |
| **FanGraphs** (`pybaseball`) | Pitcher game logs (IP, pitches, GS flag), bullpen roster | `pyb.pitching_stats_range()`, `pyb.pitching_stats()` |
| **RotoGrinders** (scraped) | Today's weather (temp, wind), projected lineups | `requests` GET → regex parse |
## Graceful Degradation
Every data function has a `_mock_*` fallback.
If a package is missing or a network call fails, mock data is returned and a `warnings.warn()` is emitted — the UI never crashes.
## Performance
- All fetches are wrapped in `@_cached()` with a 5-minute TTL.
- `pybaseball.cache.enable()` adds a disk cache layer on top.
- Heavy Statcast pulls (full season per pitcher) happen once per player/date combo.
- To increase cache TTL, edit `_CACHE_TTL` in `data_fetcher.py`.
## Extending
### Adding live game tracking
- Poll `statsapi.game(game_pk)` on a timer; Gradio supports `gr.Timer`.
### Adding RotoGrinders lineup parsing
- RotoGrinders serves lineups via an internal JSON endpoint.
Try: `GET https://rotogrinders.com/api/lineups?sport=mlb&date=YYYY-MM-DD`
Parse the JSON and map to the `player_dict` format in `data_fetcher.get_lineups()`.
### Adding Baseball Reference splits
- `pyb.split_stats()` or scrape `https://www.baseball-reference.com/players/split.fcgi?id=PLAYER_ID`
### Updating league averages
- Edit the `LEAGUE_AVG` dict at the top of `data_fetcher.py` each season.
## Known Limitations
- **RotoGrinders** is JS-rendered; the weather scraper uses a regex heuristic
and may break if their HTML changes. Consider Playwright for more robustness.
- **Projected lineups** (non-confirmed) come from RotoGrinders projected data
or default to empty with a ⚠ flag if unavailable.
- **Game card selection** uses a JS workaround to update a hidden Gradio number
input. If Gradio internals change, revisit `app.py``selectGame()`.
## League Average Constants (2024)
Update yearly in `data_fetcher.py → LEAGUE_AVG`:
- `xwOBA`: 0.318
- `K_pct`: 0.226
- `BB_pct`: 0.082
- `SP_FB_velo`: 93.9 mph
- `RP_FB_velo`: 95.2 mph