- Python 89.2%
- HTML 8.7%
- Just 1%
- Dockerfile 0.6%
- Shell 0.5%
- Bump Docker base image, requires-python, and CI to Python 3.15 - uv lock --upgrade to refresh all dependencies - Fix lint/type findings from updated ruff/ty; noqa deliberate broad-except Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|---|---|---|
| .claude/commands | ||
| .github | ||
| docs | ||
| plugins | ||
| tests | ||
| .dockerignore | ||
| .gitattributes | ||
| .gitignore | ||
| CLAUDE.md | ||
| docker-compose.yml | ||
| docker-run.sh | ||
| Dockerfile | ||
| entrypoint.sh | ||
| hockeydb_scraper.py | ||
| justfile | ||
| metadata.json | ||
| metadata.yaml | ||
| migrate_venue_coordinates.py | ||
| monte_carlo.py | ||
| playoff_predictor.py | ||
| playoff_simulations.py | ||
| prek.toml | ||
| program.py | ||
| pyproject.toml | ||
| README.md | ||
| retrain.py | ||
| uv.lock | ||
AHL Scraper
A Python web scraping application that collects comprehensive game data from the American Hockey League (AHL) and serves it through an interactive datasette interface.
Features
- 42 Seasons of Historical Data — Complete game records from Season 49 through Season 91 (12,799+ games)
- Current Season Coverage — Season 90 (2025-26) with 798 played games, including scores, attendance, goals, and penalties
- Player Database — 9,013+ players with biographical information
- Game Rosters — Complete roster data linking players to games (21,060+ entries)
- Automated Updates — Daily scheduled scraping to keep data current
- Interactive Analytics — Powered by datasette for SQL-based data exploration
Helpful Links
Season 90 (2025-26) Analytics
-
Browse All Games — Filter by team, date, season, and more
-
Player Database — 9,000+ player records with biographical information
Playoff Predictions
The application includes Monte Carlo-based playoff bracket predictions that update daily as the regular season progresses.
Features
- Projected Brackets — Generate playoff predictions based on current standings for seasons before playoffs begin
- Daily Updates — Update predictions as teams' records change throughout the season
- Win Probabilities — Monte Carlo simulations show likelihood of each series outcome
- Interactive Visualization — View brackets and predictions in the
/playoffsdatasette page
Quick Start
For ongoing season predictions:
# Generate or update projected playoffs for Season 90 (2025-26)
uv run playoff_predictor.py update --season-id 90 --projected
Once the playoff season is officially created:
# Update with actual playoff results
uv run playoff_predictor.py update --season-id 90
Configuration
The system uses environment variables to map regular seasons to playoff seasons. Create a .env file in the project root:
# .env
AHL_SEASON_PAIRS={"77": 80, "81": 84, "86": 88, "90": 92}
Default mapping (if no .env file):
- Season 77 → Playoff 80 (2022-23)
- Season 81 → Playoff 84 (2023-24)
- Season 86 → Playoff 88 (2024-25)
- Season 90 → Playoff 92 (2025-26, once created)
Use null for seasons where the playoff season hasn't been created yet:
AHL_SEASON_PAIRS={"77": 80, "81": 84, "86": 88, "90": null}
Deployment
Environment Variables:
- Set
AHL_SEASON_PAIRSas an environment variable on your deployment platform - Coolify: Add in dashboard → Variables
- Docker Compose: Set in
environment:section - GitHub Actions: Use repository secrets
Daily Cronjob:
# Add to your cronjob or CI/CD scheduler
0 2 * * * cd /path/to/ahl && AHL_SEASON_PAIRS='{"77": 80, "81": 84, "86": 88, "90": 92}' uv run playoff_predictor.py update --season-id 90 --projected
Commands
playoff_predictor.py init— Create playoff prediction tablesplayoff_predictor.py update [--season-id N] [--projected] [--n-simulations 1000]— Generate/update predictionsplayoff_predictor.py status [--season-id N]— Show last update time and prediction counts
Getting Started
Prerequisites
- Python 3.14+
- Just (recommended for command running)
- Docker (optional, for containerized deployment)
Development Setup
-
Clone the repository
git clone https://github.com/ryancheley/ahl.git cd ahl -
Install dependencies
uv sync # Install dependencies from pyproject.toml -
Run the scraper
just load # Execute the main scraping script
Common Commands
Scraping & Data
just load— Execute the main scraping scriptjust game <game_id>— Get specific game datajust recent— Show most recent game ID
Datasette
just datasette— Install datasette dependencies and serve data locally
Testing
pytest— Run test suite
Docker (Deployment)
just build— Build Docker imagesjust up— Start Docker servicesjust down— Stop Docker servicesjust logs— View Docker service logsjust docker-test— Build, start, and test both endpoints
See CLAUDE.md for comprehensive development documentation.
Architecture
The project uses SQLite for data storage:
- my_database.db — SQLite database with all scraped game data (games, goals, penalties, officials, players, game rosters, teams, arenas, conferences, divisions, seasons, dates)
Data Flow
program.pyscrapes the AHL website (lscluster.hockeytech.com)- Updates
my_database.dbwith raw game data - Datasette provides interactive SQL interface at ahl-data.ryancheley.com
Code Quality
- Formatter: ruff
- Type Checker: ty
- Testing: pytest-based test suite
- Pre-commit Hooks: prek validates commit messages (emoji prefix), formatting, and requirements compilation