Python client for the StatHead fantasy football model — rookie career predictions, historical ADP, and flattened feature matrices.
Project description
stathead
Python client for the StatHead fantasy football model. Returns pandas DataFrames of rookie career predictions, historical ADP, and the flattened feature matrix used to train the models.
Install
pip install stathead
Optional extras:
pip install "stathead[polars]" # for sh.to_polars() / sh.load_polars() helpers
pip install "stathead[duckdb]" # for local SQL querying (sh.query)
Quick start
import stathead as sh
# 2026 rookie class predictions (77 players × ~80 columns)
rookies = sh.load_career_predictions_2026()
rookies.nlargest(10, "percentile")[["name", "position", "predictedCareerPPG", "modelTier"]]
# Historical backtest — predicted vs actual for every drafted rookie 2010-2025
backtest = sh.load_career_backtest()
wr = backtest[backtest.position == "WR"]
wr.groupby("modelTier")[["actualPPG", "predictedPPG"]].mean()
# Historical ADP, every season fully populated
adp = sh.load_adp_historical()
adp[(adp.season == 2023) & (adp.adp <= 24)]
SQL querying
With the duckdb extra, sh.query() runs SQL over the loaders — the same
surface as the site's Data Query tab, in Python. Every table joins on
player_key.
pip install "stathead[duckdb]"
import stathead as sh
sh.query("""
SELECT c.name, c.position, c.predictedCareerPPG, d.value_1qb
FROM career_2026 c
JOIN dynasty_values d USING (player_key)
WHERE c.percentile >= 80
ORDER BY d.value_1qb DESC
""")
sh.list_tables() # every queryable table name
Tables load lazily — only the ones a query references are materialized, so a
query that never touches player_stats (~400k rows) doesn't pay for it.
Register your own DataFrame (a roster, a league export) to join against the
model tables:
sh.register("my_roster", roster_df)
sh.query("SELECT * FROM career_2026 c JOIN my_roster r USING (player_key)")
Polars
Loaders return pandas. With the polars extra, convert any of them — handy on
the big tables like load_player_stats (~400k rows) where polars is faster.
pip install "stathead[polars]"
import stathead as sh
pl_df = sh.to_polars(sh.load_player_stats(2024))
# Or convert a loader by reference, without calling it yourself:
pl_df = sh.load_polars(sh.load_player_stats, 2024)
Pinning to a specific version
Loaders resolve against the upstream GitHub repo. Pin to a commit SHA, tag, or branch for reproducibility:
sh.pin_version("a6720e5") # or a tagged release
Clear the local cache if you want to re-fetch:
sh.clear_cache()
Data freshness
Data files are cached under ~/.cache/stathead/<ref>/ after the first
download. Subsequent runs read from disk — no network roundtrip. Delete the
cache directory or call clear_cache() to force a refresh.
Available loaders
Every table on the StatHead site is available here as a pandas DataFrame.
Predictions & prospects
| Function | Returns | Shape |
|---|---|---|
load_career_predictions_2026() |
2026 rookie predictions | ~77 × ~80 cols |
load_career_backtest() |
Historical rookies with pred + actual PPG | ~1087 × ~100 cols |
load_prospect_grades(year=2026) |
Scouting-report grades | ~200 × 7 |
load_career_2027() |
2027 draft-class early board + college aggregates | ~200 × ~30 |
Projections (model outputs)
| Function | Returns | Shape |
|---|---|---|
load_redraft_projections() |
Seasonal redraft PPG (PPR) + receptions/game | ~250 × 7 |
load_ppg_projections() |
Model-predicted PPG for established players | ~250 × 4 |
load_adp_value_model() |
VOR vs ADP, hit probability, confidence interval | ~153 × 10 |
load_volume_projections() |
Team pass/rush/target volumes with low/high bands | ~153 × ~14 |
load_share_projections() |
Predicted target + rush share | ~153 × 6 |
load_taxi_predictions() |
Taxi-squad roster/drop probabilities (+ df.attrs['meta']) |
~96 × 6 |
Market & stats
| Function | Returns | Shape |
|---|---|---|
load_player_stats(season=None) |
Per-player per-week NFL box scores 2010-present | ~400k × ~50 |
load_dynasty_values() |
In-house blended dynasty value (1QB + Superflex) | ~500 × 10 |
load_dynasty_value_history() |
Blended daily dynasty value history | variable |
load_adp_historical() |
Model-training ADP 2010-2025 | 4507 × 10 |
load_adp_ffc(season=None) |
FFC PPR raw ADP (per season as fetched) — data via Fantasy Football Calculator | variable |
Identity & raw
| Function | Returns | Shape |
|---|---|---|
load_player_crosswalk() |
Canonical cross-source player IDs | ~10k × ~20 |
resolve_player(name, position=None) / get_player(key) / load_player_profile(key) |
Name → player_key helpers |
— |
load_feature_matrix() |
Raw feature-matrix.json (dict) |
— |
load_manual_overrides() |
Manual CFBD usage overrides (dict) | — |
Every row-shaped loader carries a player_key column that joins to
load_player_crosswalk().
Dynasty values are the app's in-house blend
load_dynasty_values() returns the same blended value the web app displays:
KTC rankings rescaled into FantasyCalc's scale via a per-player ratio
(fc_value / ktc_value, with a positional-median fallback below a value
floor). The ratio snapshot is built offline and committed as
public/data/dynasty-fc-rescale.json; the loader just applies it. No raw KTC
value is exposed — only the rescaled blend.
Feature columns
Career-prediction and backtest rows include flattened model features
under names like collegeDominatorRating, relativeAthleticScore,
recruitRating, nflDraftPick, plus two source-agnostic families
aggregated from the project's scouting-report pipeline:
scout*— single-scout grade signals (e.g.scoutGradeDraft,scoutTierOrdinal,scoutBreadthDraft,scoutNComps).guide*— multi-source draft-guide aggregations (guideRankMean,guideRankSpread,guideNStrengths,guideNWeaknesses,guideSentimentNet, …).
Both families are derived numeric features (counts, means, ordinals) —
no verbatim scouting-report text is shipped. hasScoutGrade /
hasGuideData flag missing-data so models can distinguish
"no scout coverage" from "low score".
Licensing & attribution
Package code is MIT-licensed. The data this package retrieves is derived from the StatHead project's own modeling pipeline; upstream sources (nflverse, FFC, CFBD, etc.) retain their own terms — see each source's license before redistributing. Sources whose terms do not permit third-party redistribution (e.g. KeepTradeCut dynasty values, verbatim prose from paid scouting reports) are intentionally not exposed by this client.
ADP data exposed by load_adp_ffc is courtesy of
Fantasy Football Calculator — please
preserve attribution when redistributing.
If you're building on these predictions, a link back to the StatHead repo is appreciated but not required.
Contributing
The package is small and focused — see
python/src/stathead/ for the loader modules. Issues
and PRs welcome at the main repo.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file stathead-0.3.1.tar.gz.
File metadata
- Download URL: stathead-0.3.1.tar.gz
- Upload date:
- Size: 22.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c043a020aef04df81709a3245198af527ddb10197ea8fea209f6b00de6eee991
|
|
| MD5 |
2971a01bceb50b242c68c4731f079c9d
|
|
| BLAKE2b-256 |
0fa3924d85e6fa6b1c0c6ea88a947a246f97a148bec18d66a9cda034236c02b6
|
Provenance
The following attestation bundles were made for stathead-0.3.1.tar.gz:
Publisher:
python-publish.yml on dachhack/stathead
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stathead-0.3.1.tar.gz -
Subject digest:
c043a020aef04df81709a3245198af527ddb10197ea8fea209f6b00de6eee991 - Sigstore transparency entry: 2026844343
- Sigstore integration time:
-
Permalink:
dachhack/stathead@f69dbb78f8fa82997ba161ceff9efd3432e9f96e -
Branch / Tag:
refs/heads/claude/nfl-fantasy-workbench-6D1yd - Owner: https://github.com/dachhack
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@f69dbb78f8fa82997ba161ceff9efd3432e9f96e -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file stathead-0.3.1-py3-none-any.whl.
File metadata
- Download URL: stathead-0.3.1-py3-none-any.whl
- Upload date:
- Size: 23.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
37c03492937f9a4c4a9d141ac5fdbe0ca2a4d0b317121331a406cc48701c8677
|
|
| MD5 |
4e27d080d1e4774b65c5455d43285f17
|
|
| BLAKE2b-256 |
b69ad89174e193d6050f1e2bf62bab9a41a43a0fd85f549b38787b384cd278fb
|
Provenance
The following attestation bundles were made for stathead-0.3.1-py3-none-any.whl:
Publisher:
python-publish.yml on dachhack/stathead
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stathead-0.3.1-py3-none-any.whl -
Subject digest:
37c03492937f9a4c4a9d141ac5fdbe0ca2a4d0b317121331a406cc48701c8677 - Sigstore transparency entry: 2026844404
- Sigstore integration time:
-
Permalink:
dachhack/stathead@f69dbb78f8fa82997ba161ceff9efd3432e9f96e -
Branch / Tag:
refs/heads/claude/nfl-fantasy-workbench-6D1yd - Owner: https://github.com/dachhack
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@f69dbb78f8fa82997ba161ceff9efd3432e9f96e -
Trigger Event:
workflow_dispatch
-
Statement type: