Changelog archive
Releases before 0.1.5. The newest are on the Changelog.
0.1.4 Release: September 1, 2026
Added
- CFB:
create_box_scoreaddsAirYds,aDOT,CompAirYds,YACandAirYdsPctto thepassandreceiversections; null (not zero) where plays carry no catch spot, i.e. every season before 2025 (ESPN play text states the catch point only since 2025 week 9). (#414) - CFB: new penalty play-by-play columns
penalty_side,penalty_yards_net(signed, only where two of three signals agree),EPA_penalty_direct,EP_penalty_cf(EP had the penalty not occurred) andpenalty_enforcement; penalty parsers are era-aware (2004-13 / 2014-24 / 2025 template). (#408) - CFB: new penalty spot and count columns
penalty_spot_side,penalty_spot_yardline,penalty_spot_yardsToEndzone,penalty_cf_yardsToEndzone,penalty_team_id,penalty_count,penalty_declined_count,penalty_all_declined,penalty_negated_play. (#408) - CFB: new first-down provenance columns
first_down_earned,first_down_yards,first_down_penalty,firstD_by_yards,firstD_by_penalty,firstD_by_poss,firstD_by_kickoff,new_series. (#408) - CFB: new extra-point columns
xp_attempt,xp_made,xp_kicker_player_name; with the penalty and first-down columns,espn_cfb_pbpgrows from 476 to 501 columns. (#408)
Changed
- CI / Docs: CI dispatches the Game on Paper deploy on every push to
main; the docs site's social metadata is completed. (#410, #412)
Fixed
- CFB: EPA no longer uses ESPN's mirrored
end.yardsToEndzone(a-1marker, kick returns read against the wrong possession team, an all-zero end state);EP_betweenno longer folds across a score, a no-effect penalty has no penalty EPA,yds_sackedis right for 2004-07. (#408, #411, #413) - CFB:
wp_afterno longer uses the wrong possession perspective (24,332 home/away rows) or flips when the next play keeps possession (867 rows). (#408, #411, #413) - CFB: a Timeout row no longer lends phantom EP to the next play, an all-zero end state reads as 99, the last row of an in-progress game no longer shows 0.0% WP, and plays ESPN inserts late (2014+ feed) are moved back into sequence before any lag runs. (#408, #411, #413)
- CFB: air yards are no longer null for every play of a team whose play text spots the catch with
its own abbreviation (
UHM,USCfor South Carolina,OSUfor Oregon State) rather than ESPN's; the side is now learned from the game itself, as in cfbfastR (cfbfastR#146). (#418) - CFB: returning production (
cfb_returning_production) raisedColumnNotFoundErroron every call sinceload_cfb_rostersmoved to ESPN in 0.1.1 (#399); it now keys onteam_idand adds the CFBD preseason roster, so week-1 players no longer all look departed. (#417, #419) - Codegen: generated wrappers now let caller params reach ESPN, and endpoints that were silently truncated return in full. (#409)
Data
- CFB: every cfbfastR-cfb-raw final (2004-2026) was rebuilt on this code and every
espn_cfb_*season republished on 2026-09-01; finals'processing_versionnow carries the sdv-py commit (0.1.3+9efee9f1.3), so a lock bump can no longer leave a stale final looking current.
0.1.3 Release: August 28, 2026
Fixed
- CFB: formation prefixes (
No Huddle-Shotgun #1 C.Parker, a third passer in game 401896383) no longer leak into the 19*_player_namecolumns where ESPN has no participant; such a play still forms its ownC.Parkerbox-score row besideCarson Parker. (#407)
0.1.2 Release: August 27, 2026
Fixed
- CFB:
create_box_scoreno longer returns an emptyadvBoxScore["pass"]for every game whenjoin_participants=True(no passers on Game on Paper);athlete_nameis recomputed from the current passer/rusher columns and the QBR join is a left join, so a QBR failure leaves one column null. (#405)
0.1.1 Release: August 27, 2026
Supersedes 0.1.0, released the same day; everything below shipped in this release. 0.1.0 remains on PyPI, but 0.1.1 is the one to install.
Highlights
- Every source family reaches the top-level namespace (~6,180 names, up from 4,655): all 12 ESPN
soccer leagues and league-scoped
pff_<slug>_*aliases. - Release-asset reads separate a missing season (
NoDataError) from a failed fetch (newAssetFetchError);NoESPNDataErrorremains an alias ofNoDataError. - CFB datasets: new
load_cfb_teamsandload_cfb_team_info;load_cfb_rostersnow reads ESPN rosters (breaking;load_cfb_rosters_cfbdkeeps the CFBD frame). - NCAA basketball: loaders for all 24 published
ncaa_*datasets, plus the league-wide RAPM solver and its input adapter. - New
sportsdataverse.wexpwin-expectancy harness (NFL + CFB) and the sharedsportsdataverse.scrape.espn-rawarchive engine.
Road to 0.1.0 — highlights since 0.0.40 (0.0.41 → 0.1.0, December 2025 → August 2026)
- Foundation (0.0.50): polars 0.18 → 1.x migration (~165 call sites across the seven
*_pbp.pymodules), uv + PEP 621 packaging, conda installability, and the nflreadpy-parity NFL surface with its cache/config layer. - ESPN cross-league (0.0.51–0.0.59): one core + thin extensions (121 short names × 8+ leagues = 819 wrappers), the universal parser layer, the 21-section summary dispatcher, a weekly drift cron; then college hockey and baseball/softball, UFL/XFL/CFL, soccer, cricket, Fox, Yahoo, The Odds API.
- Docs (0.0.53–0.0.55, 0.0.75): declarative codegen replaced Sphinx: generated per-league reference pages, returns-schema tables, a CI drift gate, offline full-text search and a gh-pages deploy.
- NFL models (0.0.60–0.0.71): nflfastR-parity EP / WP / CP (
ep0.996,wp0.997 vs nflverse), the 76-class xYAC model, xpass + the nfl4th fourth-down surface, era-aware models, and the NGS over-expected, scheme/special-teams, projection/draft and ratings/market spines. - CFB (0.0.52–0.0.75): the
0.36-livereconciliation, the participants module, pre-2014 eras, rule-era EP/WP/QBR/FG/fourth-down/two-point models with default-on decision surfaces,odds_override, and the ridge opponent-adjustment audit and retrain (oracle ρ 0.794 → 0.970). - MLB (0.0.51–0.0.64): the MLB Stats API module, then the ~43-endpoint Baseball Savant / Statcast
surface (
mlb_statcast_*). - NBA / WNBA (0.0.72 →):
nba_stats/wnba_stats(128 / 111 wrappers) on curl_cffi Chrome impersonation, the raw JSON store, the possession engine, CTG play context, shot- and tracking-value spines, the model zoo (RAPM, SPM / BPM 2.0, Kalman projections, WAR) and player-impact datasets. - Hockey (0.0.56, 0.0.72): the NHL api-web / EDGE / Stats REST / Records families and the HockeyTech core driving 20 league families with on-ice, Corsi, TOI and xG analytics.
- NCAA MBB / WBB (0.0.72 → 0.1.0): the bigballR / wbigballR port (
ncaa_mbb_*/ncaa_wbb_*), the lineups → stints → possessions → ratings core, prediction and tournament stack, player-value spines, within-team and league-wide RAPM, and loaders for all 24 published NCAA datasets. - Producers (0.0.72–0.0.75):
sportsdataverse.release(byte-parity RDS writer), the tiered validation harness, and thescrape.espn/scrape.ncaa/scrape.statsengines with the proxy pool; at 0.1.0 the top-level namespace exported 4,653 public names.
Breaking changes
- CFB:
load_cfb_rostersnow reads the ESPNespn_cfb_rostersrelease instead of the CFBD-derived cfbfastR-data asset; the CFBD-backed frame is available asload_cfb_rosters_cfbd. (#399) - Config:
MBB_TEAM_LOGO_URLandWBB_TEAM_LOGO_URLare removed fromsportsdataverse.config; both built URLs that could never resolve, and nothing used them. (#9 follow-up) - HTTP: failed release-asset reads are classified by the server: 404 →
NoDataError(season skipped), any other non-200 (a recovery refetch included) → the newAssetFetchError, so a 403 or exhausted retries never reads as an empty season. (#397, #402, #404) - NBA: the remaining 12
nba_statsloaders point at END-year-named assets. (#367) - NBA / WNBA: a read-only raw store is now actually offline: a miss raises
RawStoreMissErrorinstead of silently completing over the network. (#356) - WBB / WNBA: pre-2006 WNBA and pre-2015-16 NCAA WBB pbp no longer use the 4×10-minute quarters
model, so
half,start/end.{quarter,half,game}_seconds_remaining, OT detection (period ≥ 3) and timeout half buckets change; quarters-era output is unchanged (wehoop#39). (#380)
Upgrade notes — for the CFBD-derived roster frame, call load_cfb_rosters_cfbd instead of
load_cfb_rosters. NoESPNDataError remains a true alias of NoDataError, so existing raise /
except NoESPNDataError code keeps working.
Added
- Basketball crosswalk: the R crosswalk engine is ported to Python, with Fox WBB/WNBA extensions and a generated Bart Torvik client. (#340, #347–#349, #354, #359, #360, #363, #364)
- CFB: new
load_cfb_teams(the ESPN CFB group tree per season, FBS down to NAIA group 186, filterable to FBS) andload_cfb_team_info(cfb_team_inforelease);load_cfb_scheduleis re-documented for the unifiedcfb_schedulesdataset (ESPN + CFBD, FBS filter). (#393, #394, #396) - CFB: loaders for the published recruiting datasets. (#335)
- CFB:
to_cfbfastr(cfb/cfb_ncaa_cfbfastr.py) maps NCAA play-by-play to the frozen 104-columnCFBFASTR_SCHEMA;parse_cfb_ncaa_drivesaddsn_plays/yards(signed, null if omitted). (#384) - CFB: the cfbfastR series/first-down decomposition (
firstD_by_*) is ported, plus newcfb_ncaadrive-title and scoring-summary parsers. (#336, #350, #351, #353, #355, #357, #358, #375) - College baseball:
decompose_college_baseball_playssplitsparse_college_baseball_ncaa_pbpso legacy 2012–2023 trees and new captures resolve to the samePBP_SCHEMA;scrape/ncaa/reference.pyadds sport-generic team-list, schedule (newgame_number) and roster parsers. (#390) - HockeyTech: all 20 league families (
pwhl_pbpetc.) flag the twinshotrow of each goal withis_goal_twin = True; drop flagged rows to deduplicate, or countshotrows as-is for boxscore SOG. (#368) - NBA:
nba_statsrevivesvideodetailsasset,videoeventsandvideoeventsasset(125 → 128 wrappers);parse_nba_stats_result_setsreturns{"videoUrls": frame, "playlist": frame}for them. (#391) - NBA / WNBA: capture-live evidence now overrides source deprecation flags in codegen, expanding
nba_stats113 → 125 andwnba_stats95 → 111 wrappers. (#383) - NCAA basketball: loaders for all 24 published NCAA datasets,
load_ncaa_{mbb,wbb}_*forpbp,schedule,player_box,team_box,rosters,team_rosters,team_ids,possessions,lineups,matchup_stints,shotsandrapm_within_team(min_season2010;shots2019). (#387) - NCAA basketball:
mbb_ncaa_rapm_inputturns publishedpossessions+rostersinto player-id-keyed lineup slots, with stable cross-seasonperson_ids and configurable drop-or-pool handling of non-Division-I opponents. (#382) - NCAA basketball: league-wide RAPM,
mbb_ncaa_rapm_league(aggregate_stints,solve_rapm_league,team_aggregate,DEFAULT_RIDGE_LAMBDA = 1000); a different quantity fromncaa_{lg}_rapm_within_team, so never cross-join the two. (#389, with #382, #388) - NCAA basketball:
display_name_to_roster_key(inmbb_ncaa_names) maps a box-score"Surname, First"to the rosterFIRST.MIDDLE.LASTkey; an unsplittable name returns"". (#388) - NCAA basketball: the lineup parse warns when a team parses cleanly but yields no usable stints. (#376)
- NFL:
load_nfl_ratings_weeklyloads thenfl_ratings_weeklyrelease (1999-2025): one row per(season, as_of_week, team_id), fit only on games before weekas_of_week(strictly exclusive). - PFF: new
sportsdataverse/pff.pymints 184 league-scoped aliasespff_<slug>_<rest>(pff_nfl_facet_blocking_summary,pff_ncaa_*,pff_ufl_*,pff_aaf_*); the bare module-scopedpff_*names are untouched. - Scrape:
sportsdataverse.scrape.espn, the shared engine for the NBA / MBB / WNBA / WBB ESPN-rawarchives (write guard,str2bool/season_args, id canonicalizer,LeagueConfig);leagueis a required keyword on every public entry point. - Validation: row-level CFB + NFL pbp checks, penalty/yardage rules, an R↔Python output-parity compare CLI, a season event-rate collapse check, and interceptor-credit recovery with a play-shape drift check. (#337, #339, #341, #342, #344, #346)
- wexp: new
sportsdataverse.wexpwalk-forward pre-game win-expectancy harness (NFL 1999+, CFB 2004+):VintageStore,run_backtest,oracle_market, Elo/ridge/Kalman engines,postgame_we,features(sos_sor_vintages,carry_forward_weights,cfb_scoring_opportunities),variants. - WNBA:
build_wnba_season_wp(asbuild_mbb_season_wp/build_wbb_season_wp) appendspregame_home_prob+home_win_prob(Float64) toload_wnba_pbpframes. (#381)
Changed
- HTTP:
NoESPNDataErroris renamedNoDataError, sincedownload()raises it for any 404 (release assets included); the old name remains a true alias. (#397, #402, #404) - NBA:
load_nba_stats_schedules,load_nba_stats_pbp,load_nba_stats_possessionsandload_nba_stats_game_lineupsnow document that theirseasoncolumn is the asset's END year:load_nba_stats_schedules(seasons=2024)returnsseason == 2025. - NBA: the stats loaders read the Program V release assets. (#361)
- Project: the open-issue backlog was swept: 36 of 38 issues closed after reproduction on
main(#62, #90, #230, #388, #391); #9 (early-season bowl games missing fromload_cfb_schedule) is a producer-side gap and stays open; #392 was filed from the sweep. - WBB / WNBA:
load_wbb_pbp/load_wnba_pbpdocument free-throwtype_text/score_valuesemantics. (#380) - Yahoo: the CFB crosswalk live tests skip when a runner is served an empty payload instead of failing the matrix. (#229)
Deprecated
- NBA:
load_nba_stats_pbp_v3,load_nba_stats_possessions_v3,load_nba_stats_lineups_v3areDeprecationWarningshims (removal in0.1.0) forload_nba_stats_pbp,load_nba_stats_possessionsandload_nba_stats_game_lineups, which read a strict superset;seasonsis unchanged (START year). - PWHL:
pwhl_streakshas never returned data (thestreaksview exists on neither transport) and now emits aDeprecationWarningpointing atpwhl_schedule()/pwhl_standings(). (#238)
Fixed
- Basketball crosswalk: provider fetches fail loudly, ESPN conference labels come from the Core v2
group tree, the college scoreboard sweep uses the Division-I group, Fox title-case mangling is fixed,
mbb_team_crosswalkships a real KenPom default. (#340, #347–#349, #354, #359, #360, #363, #364) - CFB:
cfb_fourth_downend-game clamps and the documented input contract are corrected, andcfb_season_oddsis bit-reproducible underseed=(a.unique()row order had moved tiebreak probabilities by about1/n_simsbetween identical calls). (#392, #398, #400, #401) - CFB:
cfb_season_oddsno longer simulates non-FBS opponents as league-average contenders (571 teams holding 21.2% of the 2023 title odds); the output is FBS teams only (704 → 133 rows). (#333) - CFB:
cfb_season_odds(as_of_date=)now masks scores from games on or after the date (and drops unplayed postseason rows), so a historical run simulates the rest of the season instead of replaying it. (#334) - CFB:
create_box_scoreper-player defense: split sacks credit 0.5 / 0.5 (and half the yardage),fumble_recoveriescounts takeaways only,forced_fumblesgroups byforced_fumble_team, and kickoff returns creditkick_return_team; team totals are unchanged. (#93) - CFB:
load_cfb_passing's declared schema addsint_epaandsack_epa, matching the published asset. (#379) - CFB: stats.ncaa.org yard lines keyed by team nickname (
BEARS38,SPARTANS25) now parse; drive titles on such pages had a null team. (#377) - CFB:
cfb_roster_talentreturned zero rows for every season; it is repaired and re-keyed on the ESPN team id. (#335) - CFB: pregame projections: the games-played attenuation curve is actually wired into
cfb_predict_games, constants are refit on a 2024 holdout, tempo shrinks toward last season, recruit classes are rank-weighted, and returning production counts tackles. (#335) - CFB: penalty enforcement is modeled (nullified touchdowns no longer count), canonical play types are era-stable, penalty team resolution is era-aware, and completions count on penalty plays that stood. (#336, #350, #351, #353, #355, #357, #358, #375)
- CFB: INT pass flag, punt-return yardage, fumble captures and XP suffix fixed;
cfb_ncaaparsers handle 2025-season page variants; multi-season loaders tolerate per-season schema drift. (#336, #350, #351, #353, #355, #357, #358, #375) - CFB:
CFB_BASE_URL404'd on the retiredcfbfastR-data/main/pbppath; it now points at theespn_cfb_pbprelease thatload_cfb_pbpserves. (#9 follow-up) - Docs: on phones the landing-page hero buttons wrap instead of being clipped, and reference
@returntables fit the viewport instead of showing only the column names. - HockeyTech: a dead view (HTTP 200 with
Undefined Tab <view>orInvalidView error) now warns instead of returning a silent empty frame, in all 20 league families. (#238) - HockeyTech:
build_on_iceevaluatesgoalrowsGOAL_EPSILON_S(2) seconds early, so goals no longer get the post-goal line and a wrongstrength_state;goal_epsilon_s=0restores the old behavior. (#369) - HTTP: Ctrl-C during a release-asset read interrupts again instead of being swallowed into an HTTP
request by the
PanicExceptionrecovery. (#397, #402, #404) - MBB: the Torvik loader rejects an HTML error body instead of parsing it as CSV. (#398, #400, #401)
- NBA:
drafthistoryis live forLeagueID=00, not barren. (#362) - NBA / WNBA: every
*v3boxscore wrapper returned a(0, 0)frame; the parser now buildsPlayerStats+TeamStatssets from the nestedboxScore*payload. (#383) - NCAA basketball: sibling player codes are disambiguated instead of rejecting the game, unique
first-name-only matches resolve, codes derive via the box roster, NIU and
Northern Ill.are equivalent, crosswalk sources fail loudly,scheduleleaguev2parses. (#348, #371, #372, #373, #374) - NCAA basketball:
ncaa_{mbb,wbb}_shotsperiodandsec_leftwere null in every season (2019–2026);shot_events_to_framenow derives them era-aware from the game clock. (#386) - NCAA basketball: a guard asserts every
team_aliasespair also resolves throughsame_school(the NIU /Northern Ill.flaw), and near-identical schools such asMiami (FL)/Miami (OH)stay distinct. (#378) - NFL:
NFLPlayProcessno longer raisesKeyError: 'name'for franchises without a mascot (every 2020-2021 Washington Football Team game); the mascot is derived fromdisplayName. (#23) - NHL:
nhl_teams()works again (NHL_TEAM_LOGO_URL404'd) andreturn_as_pandas=Truereturns a DataFrame instead of a bound method. (#9 follow-up) - Packaging: the wheel no longer installs the repo's
dev/andtools/as importable top-level packages (as 0.0.75 and 0.1.0 did); discovery is an allowlist,include = ["sportsdataverse*"]. - Soccer: all 12 ESPN soccer leagues (bundesliga, epl, laliga, ligamx, ligue1, mls, nwsl, seriea,
ucl, uel, wc, wwc) are star-exported, so
espn_mls_scoreboardand its 1,343 siblings reach the top level;nba_stats/wnba_statsdeliberately stay module-scoped. - WBB: the halves period model applies to pre-2016 NCAA women's seasons on the loader side too. (#370)
0.0.75 Release: August 2, 2026
Breaking changes
- CFB: all seven bundled CFB models (
ep_model,wp_spread,wp_naive,qbr_model,fg_model,xpass_model,two_pt_model) are retrained on the repairedcfbfastR-cfb-rawcorpus; feature contracts are unchanged (weights-only), but downstream EPA/WPA values move.
Upgrade notes — No caller change is needed for the CFB retrain, but anything cached from an earlier release should be rebuilt.
Added
- CFB: every bundled CFB
.ubjhas a.card.jsonmodel card recording objective, feature list, training season span, hyperparameters, boost rounds and source frame (previouslyNone). - Scrape: new
sportsdataverse.scrape.ncaa, the shared stats.ncaa.org MBB/WBB hoops sweep engine (discover,capture,parse,rosters,datasets,identity,espn_game_xwalk,bundle,canary,league_configwithMBB/WBB);leagueis a required keyword on every entry point. - Scrape:
scrape.ncaa.parseis re-runnable:--season(repeatable) scopes the sweep and--forcere-parses existing output; without them the stage still skips existing files. - Scrape: new
sportsdataverse.scrape.stats(Phase 1), the shared stats.nba.com / stats.wnba.com sweep engine:proxy,session_transport(curl_cffiChrome impersonation) andobservability; likescrape.ncaa, it is not re-exported at the top-levelsportsdataversenamespace. - Scrape:
scrape.statsPhase 2 adds league-parameterized capture planning:league_config(NBA/WNBA,by_league_id()),endpoints(league-keyed season strings),season_capture,periods(league- and era-aware period windows) andrefill.
Changed
- CI: a new
docs-deployworkflow builds the docs site on pushes tomainthat touchdocs/**and publishes it as a single orphan commit ongh-pages, removing the per-push build from Vercel. - Docs: the documentation site has offline full-text search
(
@easyops-cn/docusaurus-search-local), indexing only the rollingmainversion, with no external service.
Fixed
- Scrape:
scrape.ncaastage CLIs no longer scan an empty tree and report success having done nothing (bundles=0,EXIT=0):--rootdefaults to each repo'sREPO_ROOTvia its shim, library fallbacks raise naming the fix, and the parse stage exits non-zero when it matches no bundles. - Scrape: a real (non-
--check) WNBA refill run no longer raisesModuleNotFoundErroron the nonexistentsportsdataverse.nba.wnba_stats;refillresolves the wrapper module from the config.
0.0.74 Release: August 2, 2026
Breaking changes
- CFB: in all 10
adv_*release tags (republished for 2004–2025),pos_team/def_pos_teamnow hold the team name (String) and the id moves to newpos_team_id/def_pos_team_id(Int64);def_pos_teamis inadv_defensive/adv_defensive_players. Summaries are unaffected. - CFB:
cfb_adjusted_epanow actually opponent-adjusts: the ridge default_RIDGE_LAMBDAdrops from 325 to0.035andRatingsConfig.ridge_lambdafrom 0.05 to0.035. The old fit left raw-EPA order intact (Spearman 0.999982), so adjusted ratings and ranks change substantially. - CFB:
opportunity_runnow means a rush of 4+ yards (yds_rushed >= 4, the cfbfastR definition; was<= 4), soopp_highlight_yards, identically 0 in every published row, now carries values. Publishedespn_cfb_pbpassets carry the old values until republished. - CFB:
opportunity_run,highlight_runandadj_rush_yardagegate on therushflag instead oftype.text == "Rush", so rushing touchdowns and own-fumble-recovery rushes count andadj_rush_yardageis no longer null on them. - CFB: nine CFB loaders now return
team_idasInt64(wasStringinpassing,receiving,rushing,team_summaries(+_weekly),ratings(+_weekly),recruiting_proj;Int32inteam_info), so cross-datasetteam_idjoins match (134/134 teams, was 0). Assets are unchanged.
Upgrade notes — adv_*: read the team id from pos_team_id / def_pos_team_id. Joining
cfb_team_summaries.team_id (String) to adv_team.pos_team_id (Int64) without a cast matches
nothing, silently; the CFB loaders now cast team_id to Int64 on read.
Changed
- Codegen:
releases.yamlgains anid_int64:key; a generated loader then emits a_cast_ids_int64call, which casts only when every value round-trips ("007"or1.5leave the column untouched). - Codegen: the description-coverage ratchet now includes the ~5,850 loader columns in
loader_schemas.yaml; the undescribed remainder is tracked via_DEFERRED_BUCKETS. - Docs: 1,308 more loader return-table columns are described: CFB
team_summaries(+_weekly),adv_team(+_gamelog),adv_situational,cfb_pbpand the four PHF loaders. (#312) - Docs: the CFB descriptions flag ESPN naming traps: bare
EPA_explosive*/EPA_success*columns are play counts, not EPA totals;EPA_overall_offduplicatesEPA_overall_offense; andEPA_explosive_rateis notEPA_explosive / EPA_plays. - Docs: generated loader returns tables gain a
descriptioncolumn, resolved frommanual_column_descriptions.yamlwith the R-package column dictionary as fallback.
Fixed
- CFB: plays carrying ESPN's
-1end.yardsToEndzonesentinel now recover the end yardline fromend.yard; 2016 week 2 (72 of 75 games) had been scored at about −2.6 EPA/play, plus 12 plays in seven other seasons. - CFB:
rushing_power_rateno longer reads 1.0 for every team in every season (2024's real rate is about 0.055): boolean nulls are now filled withFalsebefore aggregating. - CFB: opponent-adjusted fits no longer drop one team per side (the ridge's reference level) from the returned table, nor its games from its opponents' adjusted sets.
- Docs: the returns tables for all 10
adv_*loaders now match the shipped data;load_cfb_adv_passinggainsxComp,CompPct,xCompPct,CPOEand typesrush_epa/pen_epaasFloat64(notNull). - Docs:
load_cfb_adv_defensive_playersdocuments its season-dependent columns: 8 in 2004, 12 for 2005–2013 (+ sacks,sacks_yards,pass_breakups,forced_fumbles), 14 from 2014 (+ interceptions,interceptions_yards); a column absent in a season comes back null.
Data
- CFB:
espn_cfb_adv_team_gamelogis rebuilt for 2004–2025 on the newadv_*shape; it still exposesteam_idplus a readableteam/opponent, so its consumers see no change.
0.0.73 Release: August 1, 2026
Breaking changes
- CFB:
adj_off/adj_def/adj_netinefficiency_ratings/cfb_ratingsare now the netted Radjust_epastatistic (per-game raw EPA minus the opponent's fitted strength, averaged), not the ridge coefficient + intercept; ranks barely move, magnitudes shrink (top ~0.35, was ~0.63). - CFB: rating predictions use constants refit to the new scale (
net_points_scale34.49 → 44.54,margin_sd,total_*;hfa_epaunchanged). - CFB:
adj_st_epais now true EPA/play (each unit's mean EPA/play, field goal, punt and kick return, centered on the league mean and summed) instead of a sum of three z-scores. - CFB:
cfb_ratings()now defaults tofbs_only=True(FBS-vs-FBS games only) anddrop_kneels=True(kneel-downs removed), matching game-on-paper; ratings shift, andcfb_resume/cfb_season_oddsinherit the defaults.
Upgrade notes — Pass fbs_only=False / drop_kneels=False to cfb_ratings() for the previous
unfiltered behavior.
Added
- CFB:
load_cfb_adv_team_gamelog(tagespn_cfb_adv_team_gamelog): opponent-adjusted team efficiency with game context (opponent, home/away, scores, margin, result, date), one row per team-game, 2004–2025. - CFB:
load_cfb_ratings_weeklyandload_cfb_team_summaries_weeklyreturn long format, one asset per season with athrough_weekcolumn; filterthrough_week == Wfor as-of-week-W state. - Models: new repo-root
model_ledger.json, a machine-readable ledger of 73 trained/fitted models across the ecosystem (artifact, training script, trained and available season windows). - NBA: model outputs keyed on numeric ids now also carry resolved player and team names.
- NBA: the possessions / season-compile path reads the committed raw JSON store (over URL, plus season-level captures) in preference to network reads, so season builds reproduce offline.
- NBA: the
stats.nba.comruntime's timeout and retry are tunable.
Changed
- CFB: the roster join behind pre-2014
{type}_player_idgains two fallback tiers below exact match (first-initial + surname, then bare surname), both team-scoped; an ambiguous name stays null. - CFB: the player box score is a second
{type}_player_idsource when ESPN 404s the game roster (376 of 898 games in 2018); 2018 resolution rises from 63.7% to 96.2%.
Fixed
- CFB: pre-2014
{type}_player_namevalues drop the 2004"(TEAM)"suffix (Matt Leinart, notMatt Leinart (USC)) and narrative tails ("Russell Wilson deep out"), so far more resolve to a{type}_player_id(2004: 52.1% → 87.8% of named cells). - CFB:
load_cfb_passing,load_cfb_percentiles,load_cfb_receiving,load_cfb_rushingandload_cfb_team_summariesno longer raiseSeasonNotFoundErrorfor the published 2004–2013 seasons;load_cfb_play_participantsand the two crosswalk loaders keep their real 2014 floor. - Docs: declared returns tables corrected:
seasonisInt64(notFloat64) forload_cfb_passing/_receiving/_rushing/_team_summaries, andload_cfb_passingdeclares the republishedInt32sacked/pass_int. - Docs: the Docusaurus site builds via rspack (
future.v4), resolving the Vercel heap OOM. - NBA: result-set schema inference scans all rows, not the first; a leading run of nulls had inferred the wrong dtype for the whole column.
- NBA: three real-data bugs in the raw-store impact path.
- NFL: the upstream removal of the NGS season aggregate (week 0) is handled with a warning and an xfail sentinel instead of a hard failure.
- NHL: reading release parquets survives the R-arrow
vctrsextension-metadata panic. - RDS:
write_rdsstreams to its sink instead of buffering the whole object, and its temp-file write path keeps the umask-derived file mode.
0.0.72 Release: July 22, 2026
Highlights
- NBA seasons are END-year across the Python API:
compile_nba_season(2024)andnba_availabilitynow mean 2023-24, matchingmost_recent_nba_season()and the ESPN-sourcedload_nba_*datasets. - New
nba_stats/wnba_statsfamilies: 112 stats.nba.com and 95 stats.wnba.com wrappers that return tidy frames through one parser,parse_nba_stats_result_sets. - Model spines across the leagues: ratings, projection, shot-value, tracking, draft and simulation models for NFL, CFB, NBA/WNBA, MBB/WBB, NHL/PWHL and MLB, including nflseedR / cfbseedR standings ports.
- stats.ncaa.org: the bigballR / wbigballR port (
ncaa_mbb_*/ncaa_wbb_*), the college RAPM core, and new football, college baseball and softball play-by-play parsers. - Loaders and release tooling: seven new CFB dataset loaders (including
load_cfb_ratings), loaders for the published model releases, and thesportsdataverse.releasepublishing module.
Breaking changes
- MBB: the
helper_{nba,mbb}_*release-parity producers emit play-by-playidas Int64, not R's Float64: MBB's 18-digit ids overflow R's double and collide in the R-produced releases. (#245) - NBA: the season convention is END-year across the Python API:
compile_nba_season(2024)andnba_availabilitytake the ending year (2024 = 2023-24); the stats.nba.com compile path took the start year. - PWHL:
pwhl_team_game_xg_rates/pwhl_ratings_from_proxygainxg_method("coords"|"quality") and default to the new coordinate xG (fit_pwhl_coord_xg), so output values change for existing callers;LEAGUE_CONSTANTS["pwhl"].margin_sdis re-fit 1.21 → 1.19. - WBB:
idin Python-produced WBB play-by-play (helper_wbb_play_by_play) is exact Int64; the R-produced releases are Float64, which loses precision above 2^53, so adjacent play ids collide.
Upgrade notes — NBA: add 1 to any start year you pass to compile_nba_season or
nba_availability. year_to_season is unchanged and still takes a start year, so call it as
year_to_season(end_year - 1); nba_box_logs is unchanged and takes the "2023-24" string, not an
integer. PWHL: pass xg_method="quality" to pwhl_team_game_xg_rates / pwhl_ratings_from_proxy
to keep the old categorical shot-quality xG.
Added
- CFB: loaders for five published-but-unreachable "Binion Box Score" releases (2014–):
load_cfb_passing,load_cfb_rushing,load_cfb_receiving,load_cfb_percentiles,load_cfb_team_summaries. - CFB:
load_cfb_model_pbploads theespn_cfb_model_pbprelease (EP/WP/QBR-enriched play-by-play, 2004–), which was published but unreachable from Python. - CFB:
load_cfb_ratings(seasons)loads thecfb_ratingsrelease (one row per team-season, 2004–: opponent-adjusted EPA, FEI,games,off_pace, ranks,net_z); seasons with no asset warn and are skipped. - CFB: advanced-efficiency spine:
cfb_advanced_stats(opponent-adjusted efficiency, isoPPP, success rate, EPA/play, havoc),cfb_field_position(fit_field_position_ep/load_fp_curve),cfb_adjusted_tempo, andcfb_advanced_constants. - CFB: recruiting spine:
load_recruit_classes(247 RDB signing classes),blue_chip_ratio,cfb_roster_talent(optionalcomposite_247override),cfb_returning_production, andcfb_recruiting_projection(wins / margin ridge, as-of boundary enforced). - CFB:
cfb_transfer_moves+cfb_transfer_impact(portal moves, net-talent win delta; no team-level win signal on 2018-2023 data) andload_draft_outcomes+cfb_draft_projection(as-of draft probability, expected picks per team). - CFB: cfbseedR-style standings and simulation:
cfb_standings,cfb_playoff_seeds(2025 CFP 12-team seeding, optionalrankings=),cfb_simulations/cfb_compute_results,cfb_games_from_schedule; conference rank andsov/sosare conference-REG-scoped. - CFB:
parse_cfb_ncaa_pbp: stats.ncaa.org football play-by-play, one row per play, cfbfastR-style (drive context, situation,play_type, players, signedyards_gained, kick / turnover / penalty detail,qb_scramble). - CFB:
cfb_ncaa_boxparsers:parse_cfb_ncaa_drives,parse_cfb_ncaa_team_stats(per quarter),parse_cfb_ncaa_player_stats,parse_cfb_ncaa_officials,parse_cfb_ncaa_linescore(+game_date/venue/attendance). - CFB: the advanced box score's passing table aggregates
cp(xCompletion model results) alongside the existing columns. - CFB: On3 recruiting: an 82-endpoint On3 RDB stem that replaces the 4-endpoint
_next/datarankings scrape (industry consensus rankings with NIL valuations and commitment / transfer status). - CFB: 247Sports Recruit Database stem (11 wrappers):
sports247_recruits,sports247_transfers(portal),sports247_coaches,sports247_target_predictions(crystal ball),sports247_sport_years,sports247_tags_autocomplete. - CFB: 247Sports ranking and portal feeds:
sports247_institution_rankings,sports247_teams,sports247_composite_team_ranking_feed,sports247_transfer_portal_team_feed,sports247_transfer_portal_player_feed. - CFB: every 247Sports payload parses via
parse_sports247_result_set, and the runtime mints and refreshes the no-login guest JWT that most 247 routes need. - CFB: 247Sports expansion: the guest-usable
positionsRDB route and a new auth-freesports247_site_pagesstem. - College baseball:
parse_college_baseball_ncaa_pbpand softball twinparse_college_softball_ncaa_pbpsplit stats.ncaa.org pbp into inning context, the batter clause (play_type,hit_trajectory,rbi, …) and runner clauses (runs_scored). - ESPN (cross-league): Core v2 recruiting family
espn_{league}_recruiting_years,espn_{league}_recruiting_players,espn_{league}_recruiting_rankingsfor the 7 NCAA-scope leagues; recruits flatten to a 33-column frame. - MBB:
ncaa_mbb_*(bigballR port over stats.ncaa.org, 33 functions with the WBB twins): pbp with on-floor lineups,_box_scores,_team_schedule,_team_roster,_lineups,_on_off,_possessionsand more, plusresolve_ncaa_team_id/refresh_ncaa_team_ids. - MBB: college RAPM core port (with
wbb_*shims):mbb_lineup_stats(lineup aggregation, on/off),mbb_ratings(Dean Oliver ratings, "Adj Rtg+"),mbb_luck,mbb_rapm(ridge RAPM with priors) andmbb_positions(position classifier,build_position,order_lineup). - MBB: NCAA stint pipeline, runnable end-to-end from saved HTML:
mbb_ncaa_{models,events,possessions,data_quality,names,stints,lineup_enrich,stint_validation}, thembb_ncaa_{roster,boxscore,pbp}_parserparsers, and a strength-adjusted stats engine. - MBB:
mbb_ncaa_fetch, a cache-first, proxy-bound stats.ncaa.org fetch layer (no direct-fetch mode) with anNcaaFetchConfigsingleton configured bySDV_PY_NCAA_*/SDV_PY_PROXYBONANZA_*env vars. - MBB:
lineup_stats_bucket/lineup_stats_buckets(mbb_ncaa_lineup_aggregation) build the 254-fieldLineupStatSetbucket, so a real NCAA game runs parse → enrich → buckets → the ported models. - MBB: hoopR release-parity producers
helper_{nba,mbb}_*lethoopR-nba-data/hoopR-mbb-datacompile their datasets in Python, including new officials andplayer_season_statshelpers. - MBB:
parse_ncaa_bb_officials,parse_ncaa_bb_team_statsandparse_ncaa_bb_linescore(mbb_ncaa_box_tabs) cover the remaining basketball contest-page tabs. - MBB: shot-quality spine:
mbb_shot_data(one shot frame from ESPN shots and NCAA charts, viaespn_shots_to_canonical/shot_events_to_frame),mbb_shot_quality_model/mbb_shot_quality,mbb_shot_selection,mbb_shooter_talent+fit_shrinkage_k. - MBB: player-value spine:
mbb_box_bpm(team-constrained box Plus/Minus),mbb_archetypes(role clusters),mbb_recruiting_projection,mbb_transfer_projection+transfer_cohort,mbb_draft_projection. - MBB:
mbb_team_ratings(AdjO / AdjD / AdjEM / AdjTempo), pregamepredict_margin/win_prob_from_margin/predict_total/mbb_predict_games, and in-gamein_game_features/mbb_in_game_win_prob. - MBB:
mbb_strength_of_schedule(Quad 1–4 résumé, Wins Above Bubble),mbb_bracketology/project_bracket(68-team field and seeds), andmbb_season_sim/mbb_bracket_sim/simulate_game. - MBB:
load_mbb_ratings/load_mbb_player_valueload the published model tags (floor 2006). - MLB: game-state spine:
mlb_run_expectancy_matrix+run_value(...)(RE24, exported atsportsdataverse.mlb), win expectancy + WPA + leverage index, an umpire strike-zone model, team and prop projections. - MLB: pitching spine over Statcast:
mlb_stuff_plus,mlb_command_plus,mlb_pitch_era,mlb_pitch_features,mlb_pitch_sequencing,mlb_pitch_fatigue,mlb_pitch_classify,mlb_pitch_injury. - MLB: fielding / catching / baserunning spine:
mlb_run_values(RE288),mlb_catcher_framing,mlb_catcher_defense,mlb_fielding_oaa,mlb_baserunning,mlb_stolen_base. - NBA:
nba_stats(112nba_stats_<slug>wrappers at stats.nba.com) routed byleague_id:"00"NBA,"20"G-League,"15"Summer League; only capture-confirmed live, non-deprecated endpoints are wrapped. - NBA:
parse_nba_stats_result_sets(raw, result_set=None, *, return_as_pandas=False)returns one frame, or adictfor multi-set payloads, and flattens the shot-location andscoreboardv3shapes. - NBA:
nba_play_context/wnba_play_context(Cleaning the Glass): per-possessionpossession_start_type{,_detail,_ctg},is_transition,is_garbage_time,is_heave_possession; per-shotctg_shot_zone,is_putback,shot_context. - NBA:
lineup_play_context/player_play_context(on/off possessions and points per 5-man unit and per player) andstarters_on_court_counts, which upgradesgarbage_time_basistomargin+starters. - NBA: shot-value spine:
score_shot_xpoints+xpoints_baseline,make_prob_by_context+make_prob_joint,shooter_talent,shot_selection_quality,zone_value_map. - NBA:
nba_shot_valueruns the five shot models (include_context=), withnba_shot_value_lineups;league_idpicks NBA"00", WNBA"10"or G-League"20"(nba_shot_value(..., league_id="20")). - NBA: six tracking over-expected models on
playerdashpt*: rebounding, passer value, drive value, catch-and-shoot vs pull-up, touch value, rim protection; WNBA (league_id="10") shims, G-League degradation path. - NBA: model zoo v1: a validation harness (four external oracles, a meta-oracle, a season
compiler), a trained SPM with the
RatingsModelharness extension, a BPM 2.0 port, and Bayesian adj-RAPM. - NBA: RAPM variants (
nba_rapm_variants):nba_la_rapm(luck-adjusted),nba_four_factor_rapm,nba_decay_rapm; validity against the Ryan Davis oracle runs whenSDV_PY_NBA_ORACLE_DIRis set. - NBA:
external_validity(five published-metric loaders innba_oracle_data.py: RAPM, EPM, LEBRON, DPM, ewins) andwalk_forwardretrodiction, innba_model_validation.py. - NBA:
nba_ratings_panel+ratings_as_of(leakage-free through-date ratings),nba_war+calibrate_pts_per_win/calibrate_replacement_level, and single-game BPM vianba_bpm(granularity="game"). - NBA:
nba_darko, a per-player Kalman filter with an aging curve (AgingCurve/fit_aging_curve) for next-season ratings;darko_forecast_accuracy+ForecastResult; per-seasonAGEvianba_player_ages.py. - NBA:
nba_v3_to_v2_pbp(pbp_v3, box_v3, *, return_as_pandas=False)builds the 61-column v2 pbp frame fromplaybyplayv3+boxscoretraditionalv3(playbyplayv2returns 0 rows), recovering assist / block / steal / sub / jump-ball players. - NBA: a
stats_nbafeed shim lets the v2 frame drive pbpstats' v2 provider (opt in withSDV_PBPSTATS_ROOT);PLAYER1_TEAM_IDis null on team-rebound rows and the"Transition Take"foul subtype is mapped. - NBA: possession event-detail columns (
fg2a/fg2m/fg3a/fg3m/fta/ftm/oreb/tov), a per-shooterbuild_possession_shootingframe, andgame_dateoncompile_nba_seasonoutput (cachePIPELINE_VERSION1 → 2). - NBA: possessions gain
dreb,number_in_period,possession_start_type,count_as_possession; the shooting frame gainsteam_id(cachePIPELINE_VERSION2 → 3). - NBA: quarter-box lineup seeding:
players_on_court_from_quarter_boxscoresandlineup_source="quarter_box"onnba_possessions(auto chain: rotation → quarter_box → pbp). - NBA: opt-in read-through raw JSON store for per-game stats.nba.com payloads
(
{endpoint}/{season}/{game_id}.json): a hit is served from disk, a miss fetches then persists; with nothing set, behavior is unchanged. - NBA: store settings
raw_store_dir=(a root or a per-endpoint mapping) /raw_store_readonly=onnba_possessions,compile_nba_seasonand the fetchers, or envSDV_PY_NBA_RAW_JSON_DIR/SDV_PY_NBA_RAW_JSON_DIR_{ENDPOINT}. - NBA:
load_nba_player_impact(seasons)loads thenba_player_impactrelease (per player-season RAPM / adj-RAPM / SPM / BPM / WAR / Kalman projection, 22 columns); 404-safe with a 1996 floor. - NFL: PFF Premium auth auto-refreshes from a saved Playwright
storage_state(SDV_PY_PFF_STORAGE_STATE, cachedSDV_PY_PFF_STORAGE_STATE_TTLseconds, default 300), as tier 3 aftercookies=andSDV_PY_PFF_*env cookies. - NFL: PFF Premium Stats 2.0 stem
pff_core(premium.pff.com/api/v1, cookie auth, 46 wrappers) withmake_pff_league_moduleshims for nfl / ncaa (cfb) / aaf / ufl;pff_loginis an experimental stub. - NFL:
nfl_season_standings, an nflseedR v2 standings port with the real tiebreaker cascades andtiebreaker_depth(RANDOM<PRE-SOV<SOS<POINTS);nfl_standingsis the api.nfl.com wrapper. - NFL:
nfl_simulations/nfl_compute_results: week-by-week season simulation with a pluggablecompute_results(default: the nflseedR ELO generator), playoffs with reseeding andbyes_per_conf, and a 5-frame summary dict. - NFL: NGS spine:
nfl_ngs_yac_oe(YAC over expected),nfl_ngs_ryoe(rush yards over expected),nfl_ngs_separation_oe,nfl_ngs_man_zone_rates(team man/zone rates), sharednfl_ngs_constants. - NFL: scheme & special-teams spine:
nfl_playcall(run/pass + play-family model, bundlednfl_playcall.ubj),nfl_gamescript,nfl_kicker_rating,nfl_special_teams,nfl_line_grades,nfl_scheme_constants. - NFL: projection & draft spine:
nfl_projection,nfl_usage_projection(shares sum to 1.0),nfl_availability,nfl_draft_model, sharednfl_projection_constants. - NFL: ratings & market spine:
nfl_ratings(opponent-adjusted team ratings),nfl_market(pregame win probability, spread, total),nfl_player_props(yardage distributions),nfl_prediction_constants. - NHL: five microstat value models over api-web pbp + EDGE: faceoff, penalty net, expected
primary / secondary assists, zone entry / exit, EDGE skating (
method="percentile"); PWHL shims (EDGE is NHL-only). - Packaging:
curl_cffi(Chrome TLS impersonation fornba_stats/wnba_statsand 247Sports) is a lazy optional import in thetestsandallextras; without it, a clearImportErrorsays how to install it. - Packaging: PFF
storage_staterefresh needs the new optional Playwright extra:pip install sportsdataverse[pff], thenplaywright install chromium; a missing install raises a clearImportError. - PWHL:
pwhl_xg_proxy, a PWHL game-prediction model: a 2-tier xG proxy from the categoricalshot_quality, feeding the league-agnostic opponent-adjustment + market core. - PWHL:
fit_pwhl_coord_xggainscalibrate_strength=True(default), per-EV/PP/SH Platt recalibrators (PwhlCoordXGModel.strength_calibrators) that shift xG slightly on frames with strength columns. - PWHL:
add_strength_state(pbp, goalie_ids)derivesskaters_home/skaters_away,strength_state(5v5/5v4/6v5) andstrength_state_valid; empty net is not derived (use the goal-levelempty_net). - PWHL:
pwhl_shot_xg()scores every shot into a 21-column_SHOT_XG_SCHEMAframe (model=reuses one fit), andload_pwhl_shifts()/load_pwhl_xg_pbp()load thepwhl_shifts/pwhl_xg_pbptags. - Release: new
sportsdataverse.releasemodule (port of Rsportsdataversedatav0.0.11):sportsdataverse_save()(rds / csv / csv.gz / parquet, type + timestamp metadata) andsportsdataverse_upload()(sidecars,SPORTSDATAVERSE.UPLOAD.*retry config). - Release:
gh_cli_release_upload,gh_cli_release_tags,gh_cli_release_assets,gh_cli_rate_limits,gh_cli_available; one upload per file,qsraisesValueError, no.token(GH_TOKENfalls back toGITHUB_PAT). - Release: native
.rdswriter (sportsdataverse/_rds.py, RDS v2 / XDR) needing no R or new dependency, byte-for-byte equal to R 4.5.3saveRDS(); nested / list columns raiseValueError. - Validation: new
constant_columncheck flags all-null / all-NaN and zero-variance columns as WARNneeds_judgment, minus a per-datasetexpected_constant_columnsallowlist. - Validation: seven CFB modeling-suite datasets are now registered:
cfb_passing,cfb_rushing,cfb_receiving,cfb_percentiles,cfb_team_summaries,cfb_rosters_crosswalk,cfb_rb_eval. - WBB:
ncaa_wbb_*(wbigballR port) with aperiod_modelknob (WBB binds(4, 600, 300)), fixing wbigballR's halves math that misreads regulation WBB as 2-OT; plusparse_ncaa_wbb_*box-tab re-exports. - WBB: shot-quality shims
wbb_shot_data,wbb_shot_quality*,wbb_shot_selection,wbb_shooter_talent(from season 2026, thewbb_shotsrelease floor). - WBB: by-reference shims and women's artifacts for the five player-value models (box-BPM, archetypes, recruiting, transfer, draft projections).
- WBB: prediction shims
wbb_team_ratings,wbb_predict_games,wbb_in_game_win_prob,wbb_strength_of_schedule,wbb_bracketology,wbb_season_sim/wbb_bracket_sim, with women's constants. - WBB:
load_wbb_ratings(floor 2008) /load_wbb_player_value(floor 2014). - WNBA:
wnba_stats(95wnba_stats_<slug>wrappers at stats.wnba.com) and theparse_wnba_stats_result_setsalias. - WNBA:
wnba_shot_value(league_id="10") and re-exports of the five shot-value model functions. - WNBA: WNBA engine fetchers use the same raw store under
SDV_PY_WNBA_RAW_JSON_DIR/SDV_PY_WNBA_RAW_JSON_READONLY(10-prefixed game ids decode as single calendar years).
Changed
- NBA: possession boundaries follow pbpstats
stats_nbais_possession_ending_event(and-1 and FT-trip exceptions, real-rebound and no-turnover filtering, jump balls); technical FTs are inline again. - NFL: known issue, not fixed:
load_nfl_pbp_participationcrashes on multi-season loads (cross-season schema drift); load per season and combine withhow="diagonal_relaxed". - Validation: the weekly validation cron records one run per dataset in the sportsdataverse.org run tracker (one gate per check); a dataset whose release download failed is not recorded.
Deprecated
- CFB: the four On3
_next/datarankings names (on3_player_rankings,on3_industry_player_rankings,on3_team_rankings,on3_industry_team_rankings) are deprecated shims that keep working. - NFL:
calculate_nfl_standingsis deprecated in favor ofnfl_season_standings; the old name emits aDeprecationWarning.
Removed
- Packaging: the unused
pyreadrdependency (runtime deps, themodels/allextras, the conda recipe), which also drops thelibbz2/liblzmaheader requirement on Python 3.9 Linux installs.
Fixed
- CFB:
cfb_ratings()works on the releasedespn_cfb_pbpasset (real calls likecfb_ratings(2023)raisedKeyError); its HFA term is guarded onpos_team/homedtype agreement (a mismatch made every play a road play). - CFB: future-season recruiting projections walk back to the newest teams crosswalk instead of
crashing in
_crosswalk_names_to_espn(which killed thecfb_recruiting_projbackfill on 2026). (#282) - CFB: pbp fixes from
0.36-live: kneel-down flag,cleaned_text/yds_rushed/yds_receivingparsing, box-score volume sort, kickoff fair catch → touchback (2018+), errored-punt end yardline,end_state_missingfill, OT order bysequenceNumber. - CFB: penalty-assessed-on-kickoff plays get the full end-state touchback, so their EPA
neutralizes to 0.0; the
penalty_flagguard now excludes Timeouts. - CFB: interception return yardage no longer counts toward offensive / drive /
total_yards, andstatYardage==0completions are rebuilt from the yardline delta. - CFB: a game ending on a possession-flipping play outside
end_change_vec(notably a safety) no longer reportshome_wp_after = 1.0for the losing team. - CFB: the advanced box score's player-name cleaning strips more invalid cases.
- Codegen: codegen and capture writers emit LF (
newline="\n"), so Windows runs no longer leave endpoint and schema YAMLs dirty with CRLF churn. - Docs: reference-page Returns prose no longer drops the first column and leaves a stray
backtick when a docstring's return description is an inline
col: dtype, ...code span. - HockeyTech:
build_on_iceend intervals are half-open (> end_s), removing impossible ~10-v-10 on-ice states and correcting Corsi / TOI for AHL / OHL / WHL / QMJHL. - HTTP:
download()retries 403/408/429/500/502/503/504 withRetry-After-aware backoff (configurable via the newretry_statuses=), returns the last response once the budget is spent, and no longer caches non-2xx responses. - MBB: the NCAA fetch layer verifies the bm-verify solve: an unsolved
NCAA Statisticsstub forces a re-solve and retry (solve_attempts, default 2), and exhaustion raises so the layer rotates proxies. (#266) - MBB:
raw_game_efficiencyreturns the typed_EFF_SCHEMAempty frame for a season with no boxscore asset instead of raisingColumnNotFoundError(also coversmbb_team_ratings/wbb_team_ratings). (#280) - NBA:
compile_nba_seasonpassesproxy_urlto game discovery too, so a datacenter run no longer compiles zero games with exit 0;proxy_provideris now called N+1 times for an N-game season. (#283) - NBA:
box_featuresmaps the realleaguegamelogcolumnfg3_mtofg3m, fixing aColumnNotFoundErroron the first real-data SPM/BPM run. (#158) - NBA: the raw store never persists an empty
{}payload, which permanently degraded a game to pbp-inferred lineups; empty payloads stay retryable misses (WNBA too). - NBA:
nba_player_positionsreturns one row perplayer_id(traded players were listed once per team, fanning out thepositionsjoin innba_bpm/nba_spm). - NBA:
players_on_court_from_quarter_boxscoresgains an optionalraw_boxname-map source, closing a mid-period name-resolution gap;quarter_boxnow matchesplayers_on_court_from_pbpon the fixtures. - NFL:
load_nfl_ff_playeridsandload_nfl_ff_rankingsretry with exponential backoff on HTTP 429/5xx instead of failing on the first hit. - PWHL:
fit_pwhl_coord_xg/predictraise on a RAW-scale (0–600) frame instead of silently scoring it, andhockeytech._analytics.add_shot_distance_angleassertsgoal_xis in a plausible rink range. - Validation: the R leakage lint reads Rscript output as UTF-8 (UTF-8 R sources were silently
skipped on Windows), and a contract test keeps the workflow's
DATASETS/LINT_TARGETSin step withregistry.py. - WBB: box helpers derive availability from the payload, not ESPN's
boxscoreAvailableflag (false for most pre-2014 games with full stats), closing the 2006–2013 coverage hole; R fixed it the same way in wehoop#64. (#275)
Data
- CFB:
espn_cfb_injurieshas a release but zero assets (ESPN's CFB injuries feed yields nothing), so it has no loader. - CFB: the new
constant_columncheck found all-zerosacked/pass_int/sack_ydscolumns incfb_passing. - PHF: dataset URLs moved from
raw.githubusercontent.compaths to dedicatedsportsdataverse-datarelease tags (phf_pbp,phf_player_boxscores,phf_team_boxscores,phf_schedules); PHF is frozen (2016–2023; 2017–2019 pbp is an upstream gap). (#218)
0.0.71 Release: June 24, 2026
Added
- CFB:
cfb_adjusted_epa()(one row per team: opponent-adjusted off / def / net EPA + ranks) andcfb_adjusted_epa_by_game()(walk-forward, one row per team-game, fit only on prior weeks so leak-free; week 1 is null), a ridge fit on competitive (0.1 ≤ wp_before ≤ 0.9) pass/rush plays. - NFL: the ESPN path (
NFLPlayProcess) gainsqb_epa,wp/vegas_wp(+def_wp/home_wp/away_wp) andxpass/pass_oe; xYAC stays a documented null stub there. - NFL: the nflverse path (
enrich_nfl_pbp) gains the per-play QBR EPA components.
Changed
- NFL: the
xpass, fourth-down andfgmodels gain rule-era one-hots (era0..era4, cuts 2001/2005/2013/2017), and the bundlednfl/models/*are refreshed to the 1999–2025 retrain (two-point on 2010–2025). - NFL: the fourth-down decision surface is on by default in both PBP builders, with each model
scored on its own play-type subset (xpass on scrimmage dropbacks, cp/xyac on pass + air-yards,
fourth-down on
down == 4). - Packaging:
scikit-learnis now a runtime dependency.
Fixed
- NFL:
calculate_xpassbackfills theera0/era1features that_make_cp_mutationsdid not build.
0.0.70 Release: June 24, 2026
Changed
- CFB: bundled
qbr_model,fg_modelandwp_spreadare retrained on the full 2004–2025 corpus reprocessed withcfb_line_oddsmulti-book consensus odds and roster-backed pre-2014 player ids; feature contracts are unchanged (drop-in), and thefourth_downmodel is left unchanged.
0.0.69 Release: June 23, 2026
Added
- CFB:
CFBPlayProcessemits a{type}_player_idfor every{type}_player_name, resolved team-aware against the game roster (identical names on opposing rosters don't collide), all years. - CFB: new
CFBPlayProcess(game_roster=, participants=)constructor params let offline rebuilds pass a stored roster and participants, fetch-free.
Fixed
- CFB: the receiver state-abbreviation strip only removes a trailing standalone token (it had turned "Stewart" into "ewart"), and play-text artifacts ("bea loss of") are nulled before the id join.
0.0.68 Release: June 23, 2026
Added
- CFB:
CFBPlayProcessemitscp/cpoe(100 * (completion - cp), pass plays) andxpass/pass_oe(100 * (pass - xpass), scrimmage rush-or-pass plays) from new bundledcfb/models/cfb_cp_model.ubj/xpass_model.ubj; null where a source column is absent. - CFB: a spread-free win-probability surface,
wp_before_naive/wp_after_naive/wpa_naive(plusdef_/home_/away_analogues), from new bundledcfb/models/wp_naive.ubj. - CFB:
sportsdataverse.cfb.get_4th_down_probs(pbp_df)(cfb4th port) adds go / punt / field-goal WP columns,fourth_down_recommendation(go,punt,field_goal),*_wp_diffandgo_boost;CFBPlayProcess.add_fourth_down_probs()applies it to a processed game's fourth-down rows. - CFB: fourth-down models
fg_model.ubjandpunt_distribution.parquet(bundled) andfd_model.ubj(download-on-demand, cached under~/.cache/sportsdataverse/cfb_models/, override withSDV_PY_CFB_MODEL_DIR). - CFB:
sportsdataverse.cfb.get_2pt_probs(pbp_df)(cfb4th port) addstwo_pt_wp,xp_wp,prob_2pt,two_pt_recommendation(go_for_2,kick_xp) andtwo_pt_wp_diff;CFBPlayProcess.add_2pt_probs()applies it to a processed game's point-after rows. - CFB: new bundled
two_pt_model.ubjsuppliesprob_2pt;prob_xpis the empirical CFB extra-point make rate0.9851. - CFB:
run_processing_pipeline(fourth_down_probs=True, two_pt_probs=True)appends the fourth-down and two-point decision columns by default. - NFL:
calculate_xpassaddsxpassandpass_oeto enriched NFL PBP, andnfl/nfl_fourth_down.pyports nfl4th's go / field-goal / punt WP and recommendation (download-on-demandfd_model/wp_model). - NFL:
load_nfl_espn_qbr(aliasload_espn_qbr) loads ESPN Total QBR:summary_type=season|week, 2006+,source=the nflverseespn_dataor the SDV-nativenfl_espn_qbrrelease.
Changed
- CFB: bundled
qbr_model.ubjis retrained on the full 2004–2025 history, replacing the 2020-lineage model (2021–2025 holdout RMSE 23.2 → 16.1 against ESPN raw QBR). - CFB: rule-era one-hots (
era0..era3, cuts 2006/2013/2020): QBR becomes the 10-feature era model,fg_model.ubjthe 5-feature one, andfd_model.ubjthe 9-feature one, now bundled (was download-on-demand). - CFB: bundled
wp_spread.ubjis retrained on the odds-backfilled frame (~2,167 missing-spread games now carry consensus spreads); same 13-feature contract. - NFL:
get_fg_wp/get_2pt_wpuse a self-trained XGBoost FG model (fg_model.ubj:yardline_100,fg_roof,fg_era) instead of the mgcv-GAM grid; the nfl4th long-kick clamps are unchanged. - NFL:
xpass_model.ubjis bundled undernfl/models/, socalculate_xpassworks offline with no first-use download; output is unchanged.
Fixed
- CFB: the
spread_timesign in_predict_wpis corrected to+pos_team_spread·exp(−4·elapsed_share); favorites had been scored as underdogs inget_go_wp/get_fg_wp/get_punt_wp. - CFB: 2004–2013 games now populate rusher, passer, receiver, sack, fg-kicker, punter, returner and fumble player names from play text (all null before); 2014+ output is unchanged.
0.0.67 Release: June 17, 2026
Added
- NFL:
enrich_nfl_pbp()(lead-diff orchestrator) computes nflverse-native EP / EPA / WP / WPA / CP / xYAC on a real nflverse PBP frame, aligned to nflfastR. - NFL: shared
calculate_epa()/calculate_wpa()insportsdataverse/nfl/ep_wp.py, with the NFL EP/WP constants and column contract centralized insportsdataverse/nfl/model_vars.py.
Changed
- CFB: bundled
ep_model.ubjandwp_spread.ubjare retrained on 2,219,607 plays from 2004–2025 with unchanged recipes and feature order (drop-in); the QBR model is intentionally unchanged. - Codegen: returns-table descriptions live in new
tools/codegen/manual_column_descriptions.yaml(keyed by schema, with a_globalfallback), so they survive re-capture; a test holds the render-blank residual at 0. - Docs: ~3,061 previously blank returns-table descriptions are filled (NFL, MLB, NHL, CFB, the ESPN game summary, NBA/WNBA/MBB/WBB, PWHL and CHL junior hockey, shared schemas).
- Docs: generated docstrings no longer emit raw
>>>doctest prompts (now napoleonQuick start::blocks), and the ~55 hand-written prompts were converted. - Docs: 78 new native returns tables: NHL api-web (9), stats-rest (10), records (37), EDGE (15) and MLB Stats API (8).
- Docs: three new tutorials under
examples/notebooks/(rendered todocs/docs/tutorials/): Soccer, Cricket, and Other ESPN leagues (UFL/XFL/CFL, college baseball/softball, NCAA hockey).
Fixed
- Codegen:
refresh_return_schemasno longer writes 0-column per-league schemas that hid the genericschemas/{name}.yamlreturns table. - NFL: faithful model artifacts replace the CFB 8-feature placeholders under
nfl/models/(ep_model.ubj18 features,wp_spread.ubj12,wp_naive.ubj11,cp_model.ubj18), fixing thexgboost num_feature >= num_col (8 vs 18)mismatch.
0.0.66 Release: June 17, 2026
Fixed
- CFB:
CFBPlayProcess.run_processing_pipeline()no longer raisesColumnNotFoundError: unable to find column "end.team.id"on sparse pre-2010 games (e.g. 2005 game252440154); healthy games' output is unchanged.
0.0.65 Release: June 17, 2026
Breaking changes
- MLB: the 64 generated
mlb_api.pyand 15 hand-writtenmlb_api_extra.pyStats API wrappers are renamedmlb_api_{short}→mlb_{short}, with no aliases.
Upgrade notes — Update call sites from mlb_api_{short} to mlb_{short}; there are no aliases.
Changed
- Namespace: minor/alias leagues are nested under sport-group packages
(
sportsdataverse.soccer.epl,.hockey.ahl,.football.ufl,.baseball.college_baseball); the 8 majors plus pwhl/soccer/cricket stay top-level. - Namespace:
import sportsdataversenow eagerly loads the 12 soccer-alias submodules, anddiscover.function_count()/list_functions()keep flat-leaf keys (function_count(league="ufl")works).
Deprecated
- Namespace: legacy flat league imports (
sportsdataverse.epl,import sportsdataverse.ufl) still resolve but emit aDeprecationWarning.
Fixed
- ESPN: the seven
espn_*_game_rosters(cfb,mbb,nba,nfl,nhl,wbb,wnba) no longer raiseColumnNotFoundError: "logos" not foundon pre-2010 payloads, norTypeError: the truth value of a Series is ambiguousfrom row-wise logo assignment.
0.0.64 Release: June 17, 2026
Breaking changes
- MLB: the pre-0.0.64
statcast_*functions are renamed to themlb_statcast_*convention, with no aliases.
Added
- MLB: the full ~43-endpoint Baseball Savant surface as
mlb_statcast_<family>_<name>(search,leaderboard,gamefeed,player), parsed by default (return_parsed=False/raw=Truefor raw): 37 leaderboards,mlb_statcast_gamefeedandmlb_statcast_schedule. - MLB:
mlb_statcast_search(+_minors,_wbc) auto-chunks the 25,000-row cap and translates friendly filters (season,pitch_type,at_bat_result,batters_lookup, ...) to Savant'shf*params;mlb_statcast_playerparses a page'sserverValssection (defaultstatcast,section=).
Changed
- Docs: returns tables for every frame-returning
mlb_statcast_*function, andexamples/notebooks/09_mlb_intro.ipynbmodernized to the new surface. - Docs: live-captured returns tables for all 11
api.nfl.com(nfl_api) endpoints (standings,rosters,teams_history,team,weeks,weeks_by_date,combine_profiles,draft_picks,injuries,game_summaries,weekly_game_details); no runtime change.
0.0.63 Release: June 16, 2026
Fixed
- ESPN:
espn_wbb/wnba/nba/mbb/nfl/cfb_game_rostersno longer hard-fail withShapeErrorand discard a game whose two teams ship different roster columns (the per-team concat is now diagonal). - HTTP:
dl_utils.downloadfails fast on a definitive 404 (NoESPNDataError) instead of retrying the fullnum_retriesbudget (~51s of backoff); connection, timeout and 5xx errors still retry.
0.0.62 Release: June 16, 2026
Fixed
- ESPN:
espn_wbb_game_rosters,espn_wnba_game_rosters,espn_nba_game_rosters,espn_mbb_game_rosters,espn_nhl_game_rostersandespn_nfl_game_rostersno longer raiseColumnNotFoundErroron older games that omit the team-levelstatistics$ref. - ESPN: the same six builders tolerate one team's
/roster404: the other team's roster is returned, andNoESPNDataErroris raised only when every team is empty.
0.0.61 Release: June 16, 2026
Fixed
- CFB:
espn_cfb_game_rostersno longer raisesColumnNotFoundErroron older (e.g. pre-2021) games that omit the team-levelstatistics$ref. - CFB:
espn_cfb_game_rosterstolerates one team's/roster404 (common for older games and FCS opponents), returning the other team;NoESPNDataErroris raised only when every team is empty.
0.0.60 Release: June 15, 2026
Added
- NFL:
sportsdataverse.nfl.ep_wpgainscalculate_expected_points,calculate_win_probability,calculate_completion_probability(CP + CPOE) andcalculate_xyac(four XYAC sub-models), wired intoNFLPlayProcesswith bundled XGBoost.ubjmodels.
Fixed
- CFB:
espn_cfb_scheduleskips the null-competitor placeholder events in the 2010 and 2014 scoreboards instead of raisingTypeError: 'NoneType' object is not subscriptable.
0.0.59 Release: June 13, 2026
Added
- CFB: 404-safe crosswalk loaders read the
cfb_crosswalkrelease:load_cfb_teams_crosswalk(seasons=)andload_cfb_schedule_crosswalk(seasons=)are per season (min_season2014, published 2014–2025); all acceptreturn_as_pandas=. - CFB:
load_cfb_rosters_crosswalk()is season-less (one current-roster snapshot);cfb_odds_events_crosswalk(The Odds API event id ↔ ESPN game id) stays live-only. - College baseball: NCAA college baseball and softball ESPN families (
espn_college_baseball_*,espn_college_softball_*). - College hockey: NCAA men's and women's college hockey ESPN families (
espn_mch_*,espn_wch_*). - Cricket: league-parameterized
espn_cricket_*(league=)family, with parsers for scoreboard, standings and an 8-section matchcard summary dispatcher (batting, bowling, partnerships). - Soccer: league-parameterized
espn_soccer_*(league=)family plus headline aliases (espn_epl_*,espn_ucl_*,espn_mls_*, ...). - Soccer: full-parity parsers: scoreboard → matches, standings → league table (group column), teams, roster, and an 11-section summary dispatcher (header, lineups, key_events, team_stats, commentary, leaders, standings, head_to_head, last_five, game_info, shootout).
- UFL/XFL/CFL: ESPN families
espn_ufl_*,espn_xfl_*andespn_cfl_*.
0.0.58 Release: June 12, 2026
Added
- Errors: a
SportsDataverseErrorbase class (SeasonNotFoundError/NoESPNDataErrorre-parented under it) and a package logger with aNullHandler; previously silentexceptpaths now log. - MBB: loaders
load_mbb_standings,load_mbb_player_season_stats,load_mbb_team_season_stats,load_mbb_rosters,load_mbb_officialsandload_mbb_game_rosters, each with a returns table. - NBA: loaders
load_nba_player_season_stats,load_nba_team_season_stats,load_nba_draftandload_nba_rosters, each with a returns table. - NFL: a new
NFL_ACCESS_TOKENenv var injects a pre-mintedapi.nfl.combearer token;nfl_clear_token_cache()forces a fresh mint andnfl_token_gen(force_refresh=True)re-mints. - Odds: new
sportsdataverse.oddswrapping The Odds API v4 (oddsapiRtoa_*parity):toa_sports,toa_sports_odds,toa_sports_scores,toa_sports_events,toa_event_odds,toa_event_markets,toa_sports_participants, three*_historyvariants andtoa_usage. - Odds: the odds endpoints return long-format frames (event × bookmaker × market × outcome);
the key comes from the
ODDS_API_KEYenv var orapi_key=. - Packaging: ships a PEP 561
py.typedmarker. - Yahoo: college football wrappers
yahoo_cfb_player_season_stats,yahoo_cfb_team_season_stats, the*_season_stats_legacyvariants,yahoo_cfb_scoreboardand ayahoo_cfb_boxscorescaffold.
Changed
- CI: a new
quality.ymlgate runsruff,ruff format --checkandmypy(with a[tool.mypy] filesratchet) on every PR, and the test workflow emits coverage. - Codegen: output is LF-only on every platform and the ruff format pass is pinned to the
project's ruff; the flat-API codegen gains
getter_module+authsupport. - Deprecation: new centralized
sportsdataverse._deprecation(warn_deprecated,@deprecated) with a documented removal window; the 11 per-type NFL loader aliases migrate to it. - Docs: the NFL docs list a dedicated "NFL.com API" reference grouping (11 functions).
- Docs: an OpenAPI 3.1 description of the NFL.com "Shield" API (
api.nfl.com) is added to the reference repos (sdv-internal-refs/nfl/,sdv-swagger/nfl_api_openapi.yaml). - Fox:
cfb_fox_ext.FOX_DATA_KEYis imported from_fox_layout.DATA_KEY, so the bundled Fox key and itsSDV_PY_FOX_DATA_KEYoverride live in one place. - HTTP:
dl_utils.download()reuses a pooledrequests.Sessionand backs off honoringRetry-After(seconds or HTTP-date, clamped non-negative, 120s ceiling) instead of a fixed sleep. - NFL: the
api.nfl.comwrappers (nfl_standings,nfl_rosters,nfl_injuries, ...) are now generated fromnfl_api.yaml; their signatures gainreturn_parsed/**kwargs. - NFL: the
api.nfl.combearer token is minted once, cached in-process and auto-renewed before its JWTexp, instead of a token POST on every call. - NHL:
load_nhl_pbp,load_nhl_player_boxscore,load_nhl_team_boxscoreandload_nhl_scheduleread the SDV-native releases (nhl_pbp_full,nhl_player_boxscores,nhl_team_boxscores,nhl_schedules) instead offastRhockey-data;min_season2011 → 2010. - Tests: a VCR-style record/replay harness (committed, secret-scrubbed cassettes) exercises the
real
download()→ parser path offline.
Fixed
- Codegen: the
--audit-releasesdrift check keys on the release tag instead of its title, so it no longer flags valid releases as missing. - NFL:
load_nfl_players()reads the nflverse players release (players/players.parquet) on both paths; the default polars path had returned the officials dataset. - NFL: the generated
api.nfl.comwrappers go throughdl_utils.download()(retries, cache, error handling) instead ofrequests.get(), andNoneno longer leaks onto the wire from boolean flags or thenfl_weeksseason/season_typepath params.
0.0.57 Release: June 10, 2026
Added
- Fox: read-only Fox Sports Bifrost wrappers over
api.foxsports.com/bifrost/v1; CFB getsfox_cfb_pbp,fox_cfb_boxscore,fox_cfb_odds,fox_cfb_team_roster,fox_cfb_team_stats,fox_cfb_team_gamelog,fox_cfb_standingsandfox_cfb_league_leaders. - Fox: NBA, MBB and NHL get the same eight wrappers (
fox_<sport>_pbp,_boxscore,_odds,_team_roster,_team_stats,_team_gamelog,_standings,_league_leaders), with period-based play-by-play and a long per-player-stat boxscore. - Fox: MLB gets
fox_mlb_team_roster,fox_mlb_team_stats,fox_mlb_team_gamelog,fox_mlb_standings,fox_mlb_league_leadersandfox_mlb_odds; Fox exposes no MLB play-by-play or boxscore. - Fox:
fox_cfb_play_process(event_id)runs Fox data throughCFBPlayProcess(EPA / WPA / advanced box score) as a backup to ESPN (process=Falsecleans only,raw=Truereturns the adapted summary); the payload is taggedsource="fox". - Fox:
fox_to_espn_summary(fox_data)(sportsdataverse.cfb.cfb_pbp_fox) adapts a Fox payload to the ESPN summary shape; text-derived features degrade vs ESPN, archive-format Fox games are rejected, and a Fox event id is not an ESPN game id.
0.0.56 Release: June 9, 2026
Breaking changes
- ESPN: ~40 always-erroring generated wrappers across 8 leagues are removed: the season-less
espn_*_coachesandespn_*_calendar_{offseason,regular_season,postseason,ondays}. Useespn_*_season_coaches, the coach-detail endpoints (espn_*_coach, ...) orespn_*_calendar.
Added
- HockeyTech: AHL, OHL, WHL and QMJHL families (
sportsdataverse.{ahl,ohl,whl,qmjhl}): schedule, pbp, standings, teams, team_roster, player_stats, leaders, game_summary, season_id andmost_recent_<lg>_season, over one sharedsportsdataverse.hockeytechcore. - HockeyTech:
<lg>_game_shifts,<lg>_player_toi,<lg>_game_corsi(on-ice Corsi/Fenwick) and an enriched<lg>_pbpfor all five leagues; the feed has no missed shots, so every analytics output carriescorsi_includes_missed = False. - NFL: token-free Next Gen Stats wrappers:
nfl_ngs_statboard,nfl_ngs_statboard_leaders,nfl_ngs_leaders,nfl_ngs_league_schedule[_current],nfl_ngs_league_teams,nfl_ngs_gamecenter_overview,nfl_ngs_microsite_chart[_players],nfl_ngs_play_is_highlight. - NFL:
api.nfl.com/football/v2+/experiencewrappers:nfl_standings,nfl_rosters,nfl_teams_history,nfl_team,nfl_weeks,nfl_weeks_by_date,nfl_combine_profiles,nfl_draft_picks,nfl_injuries,nfl_game_summaries,nfl_weekly_game_details. - NFL:
nfl_game_pbp(game_id)(one row per play, withgame_id/home_team/visitor_team) andnfl_week_games(season, season_type, week)(one row per game) parse the raw game dicts. - NFL: NFL.com auth defaults to the public
WEB_DESKTOPweb-client credentials, overridable via theNFL_CLIENT_KEY/NFL_CLIENT_SECRETenv vars or function args. - NHL: loader aliases
load_nhl_team_box,load_nhl_player_box,load_nhl_skater_boxandload_nhl_goalie_box(forload_nhl_team_boxscore,_player_boxscore,_skater_boxscores,_goalie_boxscores), plusload_nhl_games(), the games-in-data-repo manifest. - PWHL: live wrappers at fastRhockey parity:
pwhl_schedule,pwhl_scorebar,pwhl_game_info,pwhl_game_summary,pwhl_pbp,pwhl_player_box,pwhl_teams,pwhl_team_roster,pwhl_standings,pwhl_playoff_bracket,pwhl_season_id,most_recent_pwhl_season. - PWHL: live player and stats wrappers:
pwhl_player_info,pwhl_player_stats,pwhl_player_game_log,pwhl_player_search,pwhl_stats,pwhl_leaders,pwhl_streaks,pwhl_transactions. - PWHL: loader aliases
load_pwhl_team_box,load_pwhl_player_box,load_pwhl_skater_box,load_pwhl_goalie_boxandload_pwhl_schedule(for the*_boxscores/load_pwhl_schedulesloaders), plusload_pwhl_games(), the games-in-data-repo manifest.
Changed
- Docs: autodoc returns tables for all 23 new NFL functions.
- Docs: each league
index.mdhas a Python ↔ R parity table linking every function to its sister R package equivalent (cfbfastR / hoopR / wehoop / baseballr / fastRhockey). - Docs: the NFL parity table maps the
load_nfl_*loaders to their nflreadr names (e.g.load_nfl_pbp→load_pbp,load_nfl_schedule→load_schedules); NFL rows go from 26 to 49. - Docs: NFL returns-table description fill rises from ~36% to ~85%, mined from nflreadr and nflfastR field dictionaries, which also backfills shared CFB and MLB columns.
- Docs:
CFBPlayProcessandNFLPlayProcesspages document all 7 public methods, constructor parameter descriptions are backfilled from__init__, andCFBPlayProcessgains a class docstring. - Docs: the example notebooks grow to ten (
05_wbb_introand08_wnba_introsplit out, new09_mlb_introand10_pwhl_intro, an ESPN-NHL section in the NHL notebook). - Docs: notebooks render with real outputs to an on-site Tutorials section
(
docs/docs/tutorials/, viatools/codegen/render_notebooks.py), re-executed weekly.
Fixed
- Docs: the example notebooks execute clean end-to-end again (schema and usage drift such as
home_display_name/away_display_name,espn_cfb_schedule(dates=)andfull_name). - Docs: the parity tables no longer drop functions from
additional.mdor 404 their parity links (the "already documented" check no longer counts the index). - Docs: every autodoc heading carries a stable
{#name}anchor, fixing theespn_nhl_teamslink inecosystem.md. - Docs: examples whose reST literal-block intro wraps across lines no longer leak prose into the
code block (fixes the
NflConfigandespn_wbb_team_statsexamples). - Docs:
ecosystem.mdlinks all seven example notebooks, and each leagueindex.mdgains an Examples section linking the quickstart and that sport's intro notebook. - NFL:
nfl_game_schedule/nfl_game_detailswork again, rebuilt onnfl_token_gen()and/identity/v3/tokenafter NFL.com retired/v1/reroute(404 →JSONDecodeError).
0.0.55 Release: June 8, 2026
Changed
- Docs: Autodoc "Additional functions" pages render full Parameters tables (name, type, default, description), Returns and runnable Example blocks parsed from each docstring.
- Docs: Endpoint reference pages gained a Description column on the parameter table; shared query params carry authored descriptions.
- Docs: Function Returns are
col_name | type | descriptiontables: endpoint pages from per-sport schemas, autodoc DataFrame functions from the newgenerate.py --autodoc-schemaspass. - Docs: Return-table column descriptions are filled by column name from the cfbfastR / hoopR /
wehoop / baseballr
@returndocs (tools/codegen/r_column_descriptions.yaml); curated ones win. - NBA/WNBA:
espn_nba_game_rosters/espn_wnba_game_rostersframes now include ateam_alternate_ids_sdrcolumn when ESPN ships it.
Fixed
- ESPN:
espn_mbb_game_rosters/espn_wbb_game_rosters/espn_nfl_game_rostersno longer raise aShapeErrorwhen ESPN ships extra*_$reffields; columns are now renamed by source key. - NHL:
espn_nhl_scheduleno longer fails with'NoneType' object has no attribute 'get'when called with default args.
0.0.54 Release: June 8, 2026
Breaking changes
- Wrappers: Parser-backed wrappers now default to
return_parsed=Trueand return a tidy polars DataFrame instead of the rawDict; wrappers without a registered parser still returnDict.
Upgrade notes — pass return_parsed=False to get the raw Dict back; return_as_pandas=True
switches polars to pandas. The sportsdataverse.parsed.{league} mirror modules are unaffected.
Added
- MLB: Full
statsapi.mlb.comcoverage: 38 more endpoints (home run derby, all-star ballots, free agents, game pace, team coaches/personnel, schedule variants, etc.); 28 ship with fixtures and return schemas, and the auth-gated MLBAM feeds (analytics/guids/color) are wrapped for if access exists.
Changed
- Docs: Native API pages (
nhl_api_web/nhl_edge/nhl_records/nhl_stats_rest/mlb_api) gained accurate return schemas, introspected and gated bygenerate.py --check. - Docs: ~180 hand-written wrappers, loaders, statcast and utility functions are now rendered into per-league "Additional functions" reference pages from their live signatures and docstrings.
- Docs: New
generate.py --coverageaudit fails--checkwhen an in-scope exported function is undocumented (allowlist:tools/codegen/coverage_allowlist.yaml).
Deprecated
- Parsed modules:
sportsdataverse.parsed.{league}is deprecated: importing aparsed.*module emits aDeprecationWarning(it still works and will be removed in a future release). Migrate tofrom sportsdataverse.{league} import <fn>.
Fixed
- Docs:
@returntables are derived per league by running the real parsers on per-sport fixtures (generate.py --schemas), so MLB/NHL pages no longer show basketball boxscore columns.
0.0.53 Release: June 8, 2026
Highlights
- ESPN wrappers are generated from declarative endpoint YAML with real signatures and docstrings, and
NHL gets a full 115-function
espn_nhl_*surface. espn_*names follow the hoopR / wehoop / cfbfastR taxonomy (athlete -> player,event -> game).- NHL api-web wrappers drop the
webqualifier (nhl_web_boxscore -> nhl_boxscore); all five native API families are now generated. - 92 release-backed
load_*loaders, including the new PWHL league (sportsdataverse.pwhl). - CFB advanced box score: correct team attribution, ESPN-sourced totals and new defensive and specialist sections.
Breaking changes
- CFB: The standalone
espn_cfb_pbp(game_id=...)is gone in the post-rename API; useCFBPlayProcess(gameId=...).espn_cfb_pbp()followed by.run_processing_pipeline(). - CFB:
espn_cfb_*also getsseason_*cleanups vs cfbfastR (futures/groups/recruits/week_rankings;powerindex -> team_powerindex); the exceptions live intools/codegen/espn_rename_map.yaml. - ESPN: Generated
espn_*names follow the cfbfastR / hoopR / wehoop taxonomy in all eight leagues (behavior unchanged), per underscore token:athlete -> player(athlete_vs_athlete -> player_vs_player,athletes_index -> players_index,season_athletes -> season_players). - ESPN:
event -> gamein every position: bareevent -> game,events -> games,event_* -> game_*,season_week_events -> season_week_games. - ESPN: Combined mappings run first:
event_competitor* -> game_team*,event_competition -> game_competition,event_competition_* -> game_*; compound tokens are kept (athlete_eventlog -> player_eventlog). - ESPN: Internal:
sportsdataverse._common_espnno longer exposes the factory (make_league_module,_bind, the_*_WRAPPERStables) or the private_site_v2_*/_core_v2_*core functions. - MBB/WBB: Removed
espn_mbb_bracketology()/espn_wbb_bracketology(), the_common_ncaa.pymodule andregister_ncaa_bracketology(); the ephemeral, non-league endpoint is no longer carried. - NHL: api-web wrappers drop the
webqualifier where the clean name is free (26 functions), e.g.nhl_web_boxscore -> nhl_boxscore,nhl_web_standings -> nhl_standings,nhl_web_roster -> nhl_roster,nhl_web_scoreboard -> nhl_scoreboard; URL, params and parser are identical. - NHL:
nhl_web_pbpandnhl_web_schedulekeep their names (they collide with hand-written composites); the full rename map istools/codegen/rename_map.yaml. - NHL: Removed the deprecated
sportsdataverse.nhl.nhl_apimodule (it targeted the retiredstatsapi.web.nhl.com); usenhl_api_web/nhl_pbpinstead. - WBB/WNBA:
espn_wbb_player_stats/espn_wnba_player_statsnow return one core-v2 seasonDataFrameinstead of adictof web-v3 category frames; the web-v3 payload moved toespn_wbb_player_stats_v3/espn_wnba_player_stats_v3. - WBB/WNBA: The hand-written parsed
espn_{wbb,wnba}_event_officialsis renamedespn_{wbb,wnba}_game_officials(core-api officials with ids); the generated raw wrapper of that name is suppressed.
Upgrade notes — tests that intercept the generated wrappers must mock
sportsdataverse._codegen_runtime.download (not _common_espn._get): the shared _get / _csv
helpers now live in sportsdataverse._codegen_runtime, and _common_espn re-exports them.
Added
- CFB:
create_box_score()(andrun_processing_pipeline()'sadvBoxScore) gains adefensive_playerssection: per-defendersacks,pass_breakups,interceptions,forced_fumbles,fumble_recoveries(plus yards), keyed bydef_pos_team+player_name. - CFB: New
specialistsbox-score section:field_goals,punts,kick_returns,punt_returns(plus yards) keyed bypos_team+player_name; both new sections degrade to[]when empty. - CFB: New
espn_teamandespn_playersbox-score sections surface ESPN's official box verbatim (turnovers, fumbles lost, interceptions, yards, penalties, first downs, player stat lines). - CFB: New per-play attribution columns
kicking_team,return_team,fumbling_team,recovery_team,recovery_team_2,penalized_team, and per-side turnover flagsis_pos_team_turnover/is_def_pos_team_turnover(one play can turn over for both teams). - CFB: New
is_blocked_punt_turnover/is_blocked_fg_turnoverflags for blocked kicks the defense recovers, kept out ofis_turnover/is_st_turnover, which match ESPN's giveaway count. - ESPN: Every league exposes a bare
espn_<league>_player_stats(core-v2 season line: one wide row of{category}_{stat}+team_*columns) withseason_type("regular"/"postseason") andtotalparams, plusespn_<league>_player_stats_v3(web-v3 comprehensive). - Loaders: The release manifest grows from 24 to 92 loaders (WNBA
espn_wnba_*+wnba_stats_*, the full NHLnhl_*family incl. EDGE/lite/boxscores, WBB, NBA, MBB), each with a@returntable;load_cfb_betting_lines,get_cfb_teamsandnhl_teamsare kept. - NHL: New
espn_nhl_*surface (115 functions): the full ESPN Site v2 / Web v3 / Core v2 surface, andfind()now works for NHL. - PWHL: New
sportsdataverse.pwhlleague with 15 release-backed loaders (e.g.load_pwhl_pbp).
Changed
- CFB: The box-score
turnoverlist is ordered[home, away]and every row carriesteam_id; key byteam_idrather than list position. - CFB: The
turnoversection takesturnovers/Int/fumbles_lostfrom the ESPN box (espn_sourced=True); the play-by-play derivation stays under*_pbpkeys as a fallback. - CFB: ESPN's native per-play
isTurnover/isPenaltypass through as columns (populated back to 2018) as cross-checks, not sources of truth:isTurnoveris coarser andisPenaltyflags only primary-penalty plays. - CFB: Pre-2014 era support: in a 2004-2019 sweep every game with play-by-play yields valid EPA/WPA and a full advanced box score; games without PBP still exit early.
- CFB: Era notes in the architecture reference: before 2014 player names come from text only,
ESPN's win-probability array is empty before ~2016 (
wpais computed in-house), PBP is sparse before 2008. - Codegen:
generate.py --check(and thesdv-codegenpre-commit hook) fail when committed wrappers or generated docs drift from the endpoint metadata; the defaultbuildwrites them. - Codegen: New
generate.py --audit-releasescompares the loader manifest with the live release list and reports tags without a loader and orphans; tags not yet shipping parquet stay absent. - Docs:
generate.py --docsrenders the reference tree intodocs/docs/{league}/(per-leagueindex.md, a page per ESPN API and native family,reference/loaders.md,reference/parameters.md), replacing the legacy Sphinx apidoc dumps. - Docs: Each function gets an 8-section block (summary, endpoint URL, a valid example URL, a
parameter table, a
@returntable, a runnable example, a validated date) under its emitted name. - Docs: Loader docstrings carry
|col_name|type|@returntables introspected from each parquet footer (tools/codegen/schemas/loader_schemas.yaml,generate.py --loader-schemas). - Docs:
docs/sidebars.tsmakes each league a clickable category with an autogenerated reference subtree and adds a top-level "Parameter reference" entry. - Docs: Example notebooks are CI-executed with
nbmake(weeklylive-tests-cron, non-blocking);02_cfb_introwas rewritten to theCFBPlayProcessflow. - Docs: New Ecosystem & philosophy page: design
philosophy, naming paradigm, Python ↔ R sister mapping, nflverse / PySport, the data repositories
and a 1:1 function map;
intro.mdand all seven notebooks link to it. - Docs: The ESPN cross-league architecture
page now describes declarative codegen instead of the retired
make_league_module()factory. - Docs: The generated docs are the live default at
/docs/(lastVersion: 'current', labelledmain) and refresh on every deploy; the legacy docs stay archived at/docs/0.0.50/. - Docs: The site builds on Vercel on push to
main; at each releasecd docs && yarn version:docs <x.y.z>freezes a per-release archive. - Docs: The home page (
docs/src/pages/index.tsx) now covers Basketball / Football / Baseball / Hockey, each card naming its R sister, with an "Ecosystem & philosophy" call-to-action. - ESPN: Wrappers are generated from
tools/codegen/endpoints/*.yamlintosportsdataverse/<league>/<league>_espn_ext.pyinstead of registered at import time: real parameter names, type hints and docstrings, with byte-identical URLs and query strings. - ESPN: Renames that would clash with a hand-written sibling are skipped (
teams_site,espn_cfb_season_{team,awards,coaches}); one-to-many splits such assummaryremain for curation (docs/superpowers/specs/espn-r-naming-worksheet.md). - ESPN: When names collide across different endpoints, one keeps the bare name and the newer one is
version-qualified: web-v3
/athletes/{id}/statsbecomesespn_*_player_stats_v3only when a hand-written bareplayer_statsexists. - MLB:
mlb_apiis now generated and keeps itsmlb_api_*names (non-breaking, 41 names);passthrough_queryforwardshydrate/fields. - NHL:
nhl_edge(35) andnhl_stats_rest(21) are now generated and keep theirnhl_edge_*/nhl_stats_rest_*names;**filters(cayenneExp/sort/limit, …) still pass through andreturn_parsedis wired where a parser exists. - NHL:
nhl_recordsis now generated and keeps itsnhl_records_*names (non-breaking, 50 functions).
Removed
- Packaging: The legacy Sphinx pipeline (
create_docs.sh+Sphinx-docs/) is deleted, and thesphinx/sphinx-markdown-builder/sphinx-materialdev dependencies are dropped from thedocsextra/group and theallextra.
Fixed
- CFB: Special-teams turnovers (muffed punts, kickoff-return fumbles, blocked-kick recoveries) are
now counted, and overturned plays (
"(Original Play: …)") are stripped so a reversed fumble is not. - CFB: Turnover margins / luck are keyed by team identity and can no longer be swapped or sign-flipped between teams.
- CFB: Fumble recoveries are credited to the recovering team, punt returns to the returning team,
and penalty yards to the penalized team (new
penalty_yards; legacytotal_pen_yardskept). - CFB: The real play just before an "End of period/half/game" marker is no longer dropped by dedup, so end-of-half turnovers such as a Hail Mary interception are kept.
- CFB:
run_processing_pipeline()joinsespn_cfb_play_participants, so player names no longer carry team prefixes (e.g."BYU Dayan Ghanwoloku"); setjoin_participants = Falseto skip it. - CFB: An interception whose returner later fumbled is no longer relabeled
"Fumble Recovery (Opponent)"; it stays"Interception Return"and keeps itsintflag. - CFB: A sack-fumble the offense recovers is
Fumble Recovery (Own)again, and a punt-return fumble the punting team recovers isPunt Team Fumble Recovery; EPA is recomputed to match. - CFB: A blocked field goal ESPN types as
Extra Point Missedis relabeledBlocked Field Goal[ Touchdown], correcting its EPA; genuine blocked PATs are untouched. - CFB: Pre-2014
2pt Conversionrows resolve viascoringPlaytoTwo-Point Conversion Good/Two-Point Conversion Missedand score through the two-point path. - CFB: 2004
Unknownrows are relabeled from their text: period/game markers ->End Period, misclassified kicks ->Field Goal Missed/Extra Point Missed/… Good. - CFB: Pre-2014
Kickoff Return (Defense)(onside kick recovered) becomesKickoff. - CFB: Separate extra-point rows in the few pre-2005 games that ship a real down get the no-down
sentinel (
down/distance = -1).
0.0.52 Release: June 3, 2026
Added
- CFB: New
CFBPlayProcess(odds_override=...): a dict ofgameSpread,overUnder,homeFavorite,gameSpreadAvailableis used as-is, so offline rebuilds never hit the network or default odds; a missing key or non-dict raisesValueError. No override = unchanged behavior. - CFB: New
CFBPlayProcess.odds_source("summary_pickcenter","core_odds_api","default"or"injected"), also written into the returned payload forrun_processing_pipeline()/run_cleaning_pipeline()consumers.
Changed
- CFB:
CFBPlayProcess(gameId=..., raw=True).espn_cfb_pbp()keeps the summaryinjuriesandgameNoteskeys (default[]); all previously returned keys are unchanged.
0.0.51 Release: May 30, 2026
Highlights
- New
sportsdataverse.mlbmodule (175 functions): ESPN, the MLB Stats API and Baseball Savant. - NHL moves to
api-web.nhle.com/v1/and gains EDGE, Stats REST and Records modules. - 804 new cross-league ESPN wrappers ported from hoopR / wehoop / cfbfastR across eight leagues.
- A polars / pandas parser layer with opt-in
return_parsed=Trueon every ESPN wrapper and a 21-sectionsummarydispatcher. - Quality-of-life helpers:
find_team/find_athlete/find_event,parsed.*, a tiered response cache and thesdvCLI.
Breaking changes
- NHL: The deprecated
statsapi.web.nhl.comhost is gone, replaced bynhl_web_*wrappers onapi-web.nhle.com/v1/;nhl_api.pykeeps a small set of backward-compatible aliases that warn and delegate tonhl_api_web.
Added
- Cache: New
sportsdataverse.cachetiered TTL response cache consulted bydl_utils.download: modesoff(default),memory,filesystemviasdv.set_cache_mode(...); on-disk under~/.cache/sportsdataverse/, overridden by$SDV_PY_CACHE_DIR. - Cache: Six TTL tiers picked from the URL: IMMUTABLE 30d, REFERENCE 7d, SLOW 24h, MODERATE 1h (default), FAST 5m, LIVE never cached; past-date scoreboards are IMMUTABLE, future dates LIVE.
- Cache: Per-call
cache_ttl=ondownload()overrides the tier; invalidate withsdv.clear_cache(),sdv.clear_cache(pattern="*roster*")orsdv.clear_cache(url="https://..."). - CLI: New
sdvconsole script:sdv find-team,sdv find-event,sdv list-functions,sdv function-count,sdv cache mode|stats|clear;--jsonemits raw JSON; exit codes 0 = success, 1 = no match, 2 = runtime error. - Discovery: New
list_functions/function_countinsportsdataverse.discover(re-exported at the top level): a searchable function index withsearch=,league=,parsers_only=andwrappers_only=. - ESPN: Cross-league port from hoopR / wehoop / cfbfastR: 804 new wrappers across NBA, MBB, WNBA,
WBB, CFB, NFL, MLB and NHL from ~80 core functions in
_common_espn.pykeyed on(sport, league). - ESPN:
make_league_module(sport, league, prefix, globals(), include_ncaa=, include_football=, include_mlb=)registers wrappers with real__name__/__qualname__/__doc__forhelp(), IDE completion andinspect.signature(). - ESPN: NCAA leagues (
mbb,wbb,cfb) gainrankings,season_recruitsandseason_week_rankings; football (nfl,cfb) gainsseason_qbrandseason_qbr_week. - ESPN: New
_common_espn_parsers.py: 20 league-agnostic parsers (scoreboard, teams, standings, groups, athlete overview/stats/gamelog/splits, leaders, coaches, draft, team schedule/roster, news, injuries, Core v2 lists, …), polars by default or pandas withreturn_as_pandas=True. - ESPN: Parsers return zero-row frames for empty / malformed payloads and snake_case columns; the
ENDPOINT_PARSERSregistry andparser_for(short_name)map wrapper short names to parsers. - ESPN: Every ESPN wrapper, including the bracketology helpers, accepts opt-in
return_parsed=True/return_as_pandas=True(all 121 short names are inENDPOINT_PARSERS); the rawDictdefault is unchanged. - ESPN: New generic
parse_single_entityflattens single-resource Core v2 payloads to one row;parse_itemsnow also covers ~30 more list-shape endpoints ({items: [...]}/{entries: [...]}). - ESPN: New
parse_summary(payload, section=None)dispatcher for the Site v2summarypayload in every league: a dict of all sub-frames, or one frame withsection=; registrySUMMARY_SECTION_PARSERS. - ESPN: Summary sub-parsers
parse_summary_boxscore_player,parse_summary_boxscore_team,parse_summary_plays,parse_summary_winprobability(joins to plays onplay_id) andparse_summary_leaders. - ESPN: Metadata sub-parsers
parse_summary_game_info,parse_summary_officials,parse_summary_header,parse_summary_season_series,parse_summary_against_the_spread,parse_summary_standings,parse_summary_broadcasts. - ESPN: Metadata sub-parsers
parse_summary_format,parse_summary_pickcenter,parse_summary_odds,parse_summary_article,parse_summary_injuries,parse_summary_news. - Lookup: New
find_team/find_athlete/find_eventname-to-ID resolvers insportsdataverse.find(top-level re-export): case-insensitive substring match,multi=True, and a team-list cache cleared withclear_team_cache(league=None). - MBB/WBB: New
espn_mbb_bracketology(season, iteration=None)/espn_wbb_bracketology(...)for the seasonalsports.core.api.espn.com/v2/tournament/{22,23}/seasons/{y}/bracketologyendpoint (live roughly January-March, 404 otherwise). - MLB: New
sportsdataverse.mlbmodule (175 functions, 8 submodules): 113 ESPN cross-league wrappers + 5 ESPN originals, 40 MLB Stats API wrappers and 17 Baseball Savant / Statcast wrappers. - MLB:
mlb_api.py(40 functions) wrapsstatsapi.mlb.com:sportId=1is MLB,leagueId103= AL /104= NL,gameTypeslugsR/F/D/L/W/S/A/E/PO; player ids share Savant's MLBAM id space. - MLB:
mlb_statcast.py(17 functions):statcast_searchraisesRuntimeErrorat the 25,000-row/statcast_search/csvcap (raise_on_truncation=True);statcast_search_chunkedauto-chunks multi-week ranges. - MLB: The MLB-only
espn_mlb_athlete_hotzonesjoins the universal ESPN surface (make_league_module(..., include_mlb=True)). - MLB: New
sportsdataverse.mlb.mlb_api_parsers:parse_mlb_api_schedule,parse_mlb_api_teams,parse_mlb_api_team_roster,parse_mlb_api_standings(standings_*prefixed) andparse_mlb_api_person_stats(alsomlb_api_team_stats). - MLB: Generic
parse_mlb_api_listhandles the other list-shape endpoints;MLB_API_ENDPOINT_PARSERS(26 entries) andparser_for_mlb_api(fn_name), which falls back toparse_mlb_api_list. - NFL/CFB: New
parse_summary_drives/parse_summary_scoring_plays, andparse_summary_drive_plays, which unrollsdrives.previous[].plays[]to one row per play withdrive_id+drive_sequence; zero rows for non-football leagues. - NHL:
nhl_api_web.py(26nhl_web_*functions) covers the modern game-feed API athttps://api-web.nhle.com/v1/, grounded infastRhockey/data-raw/nhl_api_web_openapi.yaml. - NHL:
nhl_edge.py(35 functions) wraps NHL EDGE player tracking (api-web.nhle.com/v1/edge/*); the 12*_top_10paths 404 as of 2026-05-23 and are kept, withparse_edge_top10, for later. - NHL:
nhl_stats_rest.py(21 functions) wrapsapi.nhle.com/stats/rest/with verbatim Cayenne filter expressions viacayenneExp/factCayenneExp. - NHL:
nhl_records.py(50 functions) wrapsrecords.nhl.com/site/api/: awards, coaches, franchises, skaters, goalies, draft, all-star, HOF, GMs, attendance, fastest goals, team records. - NHL: New
nhl_edge_parsers.py:parse_edge_top10,parse_edge_detail,parse_edge_shot_location,parse_edge_zone_time, fallbackparse_edge_payload, and sub-frame parsersparse_edge_sog_details,parse_edge_sog_summary,parse_edge_hardest_shots. - NHL:
EDGE_ENDPOINT_PARSERSregisters 33 of the 35 EDGE wrappers (the rest fall through viaparser_for_edge);EDGE_SUBFRAME_PARSERSmaps each detail wrapper to its sub-frame parsers. - NHL: New
parse_nhl_stats_rest/parse_nhl_recordshandle every Stats REST / Records wrapper ({data: [...]}envelope); the meta endpointsconfig/componentSeason/pinggive zero rows. - NHL:
NHL_STATS_REST_ENDPOINT_PARSERS(17 entries);parser_for_nhl_stats_restandparser_for_nhl_recordsalways return a callable, neverNone. - NHL: New
nhl_api_web_parsersgame-center parsersparse_nhl_web_pbp,parse_nhl_web_boxscore(home_away,position_group),parse_nhl_web_landingand dispatcherparse_nhl_web_right_rail(6 sub-frames). - NHL: Schedule / score parsers
parse_nhl_web_schedule,parse_nhl_web_score,parse_nhl_web_scoreboard(scoreboard_date),parse_nhl_web_club_schedule(club_*context). - NHL: Standings / team / player parsers
parse_nhl_web_standings,parse_nhl_web_standings_season,parse_nhl_web_club_stats({skaters, goalies}),parse_nhl_web_roster,parse_nhl_web_player_landing,parse_nhl_web_player_game_log. - NHL:
parse_nhl_web_leaders(category-tagged) andparse_nhl_web_draft_picks;NHL_API_WEB_ENDPOINT_PARSERS(24 entries);parser_for_nhl_api_web(fn_name)returnsNoneforplayoff_series,player_spotlight,draft_rankings,draft_rankings_now(callers null-check). - Parsed modules: New
sportsdataverse.parsed.*(parsed.nba,parsed.wnba,parsed.mbb,parsed.wbb,parsed.cfb,parsed.nfl,parsed.mlb,parsed.nhl) mirrors every league's wrappers but returns a polarsDataFrameby default; the raw modules keep returningDict.
Changed
- CI:
.github/workflows/live-tests-cron.ymlruns the live suite every Monday 13:00 UTC (and onworkflow_dispatch); a failure opens, or comments on, alive-tests:drifttracking issue. - Docs: New
docs/quality-of-life.md(before/after recipes) and an intro "Quickstart" with NBA / MLB / NHL one-liners that shows theparsed.*import path first. - Docs: README and
docs/docs/intro.mdgain "Supported leagues and data sources" (per-league wrapper counts) and "Polars / pandas parser layer" sections. - Docs: New pages
docs/architecture/espn-cross-league.md,docs/architecture/building-blocks.md,docs/parsers/index.mdanddocs/parsers/fixtures.md(an index of the captured payloads). - Docs: New MLB pages
docs/mlb/index.md,docs/mlb/parsers.mdanddocs/mlb/statcast.md(truncation handling, Statcast coverage windows, MLBAM id chaining with the Stats API). - Docs: New NHL pages
docs/nhl/api-web.md(with a parser deep-dive),docs/nhl/edge.md,edge-parsers.md,stats-rest.mdandrecords.md, cross-linked, each with a "Parser layer" section. - Docs:
espn_nhl_pbp's docstring (and a caution indocs/nhl/api-web.md) explains it is not interchangeable withnhl_web_pbp/parse_nhl_web_pbp(different id spaces and schemas). - Docs:
docs/sidebars.tsgroups leagues by sport family, with Architecture and Parsers expanded; parser and wrapper module docstrings carry aDocumentation:link to their docs page. - Docs:
CLAUDE.mdgains "ESPN Cross-League Architecture (0.0.51+)" and "Parser Layer (0.0.51+)" sections. - Errors:
NoESPNDataError404 messages add aSuggestion:line from the URL, e.g.find_team(name, league='nfl'),find_athlete(name, league='mlb', team=<team>)orfind_event(date, league='nba', home=..., away=...), reading the league from both ESPN URL shapes. - Packaging:
pyproject.tomlkeywordsgrow from 6 to 21 (leagues, data sources, concepts) for PyPI search. - Tests: Offline parser suites (
tests/test_espn_universal_parsers.py,test_mlb_api_parsers.py,test_nhl_aux_parsers.py,test_nhl_api_web_parsers.py,test_nhl_edge_parsers.py) run on captured fixtures, each fixture directory with a provenance README; regression tests lock 121/121 coverage. - Tests:
tests/test_espn_live.py(56 live tests) is gated bySDV_PY_LIVE_TESTS=1, withtests/conftest.pyas the single source of that gate plus a sharedload_fixture(category, stem). - Tests: New offline
tests/test_qol.py,tests/test_cache.py,tests/test_errors_suggest.pyandtests/test_cli.py; importingparsed.*must not mutate the raw module's default. - Tooling: New
sync-docs-changelogpre-commit hook copiesCHANGELOG.mdtodocs/src/pages/CHANGELOG.mdand stages it;nhl/nhl_loaders.pyusesisinstance(seasons, int)(no behavior change).
Fixed
- ESPN:
parse_team_rosterhandles the position-grouped roster shape (MLB / NFL / NHL / CFB), so those rosters unroll to one row per player with aposition_groupcolumn instead of ~5-6 group rows.
0.0.50 Release: May 7, 2026
Highlights
- A near-drop-in nflreadpy-parity surface in
sportsdataverse.nfl: new and unified loaders, a caching layer, runtime config, static datasets, 25load_*aliases and current-season / current-week helpers. - 11 new ESPN scrape modules across
wbbandwnba(team rosters, season player and team stats, standings, draft, event officials), each with full@overloadtyping. - The
0.36-live→mainpolars 1.x reconciliation across all seven*_pbp.pymodules (~165 sites). - PEP 621
pyproject.tomlpackaging (no moresetup.py), conda-installable viarecipe/meta.yaml. - A new
cfb_play_participantsmodule behind CFB player attribution.
Breaking changes
- Packaging:
setup.pyis removed; all metadata lives in PEP 621[project]inpyproject.toml, andpython -m buildis the only supported build path. - Packaging: Python 3.9–3.14 only (3.6 / 3.7 / 3.8 dropped); minimum versions raised
(
polars>=1.0,<2.0,pyarrow>=14.0,numpy>=1.23,pandas>=2.0, etc.). - Polars:
cfb/cfb_pbp.py,nfl/nfl_pbp.py,mbb/mbb_pbp.py,nba/nba_pbp.py,nhl/nhl_pbp.py,wbb/wbb_pbp.pyandwnba/wnba_pbp.pymoved from the polars 0.18 API to 1.x (~165 sites).
Upgrade notes — the polars 1.x translations applied: groupby → group_by, with_row_count →
with_row_index, apply → map_elements (with explicit return_dtype), struct list-arg → varargs,
shift_and_fill → shift, cumsum → cum_sum, str.strip → str.strip_chars, str.n_chars →
str.len_chars, outer-join → full + coalesce, write_json kwargs; for global containment (the
1.x is_in same-datatype deprecation) use is_in(col.implode()) instead of is_in(col).
Added
- CFB: New
cfb_play_participantsmodule reads ESPN's per-play participants endpoint and resolves sidecar-missing athletes via$ref(default-onresolve_missing=True);__add_player_colsdelegates to it and keeps all 19 legacy_player_namecolumns via an alias mapping. - CFB: Hybrid scalar + list player columns (
{type}_player_nameplus{type}_player_names), so multi-entry types like split sacks are no longer collapsed to a single name. - CFB: New
cleaned_textcolumn normalizes ESPN play descriptions and is the single source for downstream feature and player-name extraction. - Conda: New
recipe/meta.yaml(noarch: python, mirrors[project.dependencies]) andrecipe/README.mdfor localconda build recipe/and conda-forgestaged-recipessubmission. - NFL: Six new loaders:
load_nfl_team_stats,load_nfl_ftn_charting,load_nfl_trades,load_nfl_ff_playerids,load_nfl_ff_rankings,load_nfl_ff_opportunity. - NFL: Unified
load_nfl_nextgen_stats(stat_type=...)andload_nfl_pfr_advstats(stat_type=, summary_level=)consolidate the per-type / per-summary variants. - NFL: 25 nflreadpy-parity aliases inside
sportsdataverse.nfl(load_pbp↔load_nfl_pbp, etc.), identity-equivalent with no overhead. - NFL:
load_nfl_ff_rankingsgainskind=as the preferred parameter;type=is kept for nflreadpy parity. - NFL: New
get_current_nfl_season()/get_current_nfl_week()helpers innfl/utils_date.py. - NFL: New
sportsdataverse.nfl.cache(memory and filesystem backends, TTL) on all 23 canonical loaders and the 11 deprecated aliases via@cached_loader;clear_cache()invalidates, andreturn_as_pandas=Trueconverts the single stored polars frame on read. - NFL: New
NflConfigwithupdate_config()/get_config()/reset_config()and env varsSDV_PY_NFL_CACHE,SDV_PY_NFL_CACHE_DIR,SDV_PY_NFL_CACHE_DURATION,SDV_PY_NFL_VERBOSE,SDV_PY_NFL_TIMEOUT,SDV_PY_NFL_USER_AGENT. - NFL: Inline-bundled static datasets
team_abbr_mapping(143 entries;OAK -> LV,SD -> LAC,STL -> LA),team_abbr_mapping_norelocate(143, history preserved),player_name_mapping(136). - WBB/WNBA: New
wbb_team_roster/wnba_team_roster(one row per athlete per(team_id, season), stable schema when empty) andwbb_standings/wnba_standings(WBB defaults togroup=50). - WBB/WNBA: New
wbb_player_stats/wnba_player_statsandwbb_team_stats/wnba_team_stats: multi-table dicts keyedAverages/Totals/Misc(always present), plusOtherwhen needed. - WBB/WNBA: New
wnba_draft(one row per pick) andwbb_event_officials/wnba_event_officials(one row per official).
Changed
- CFB: Targeted regex fallbacks remain for
sack_player_name2,fg_block_player_name,punt_block_player_nameandinterception_player_name, where ESPN's sidecar has documented gaps. - Conda: New
.github/workflows/conda-build.ymlbuilds, installs and smoke-imports the recipe on PRs touchingrecipe/orpyproject.tomland on every release. - Docs: ~190 public callables ship a multi-block napoleon
Example:section (quick start, parameter combinations, a pipeline step,See Also:companion links), replacing the old one-line examples. - Docs: Seven intro / intermediate notebooks under
examples/notebooks/(01_quickstart.ipynbthrough07_nhl_intro.ipynb), outputs cleared;.gitignoretracksexamples/notebooks/*.ipynb. - Docs: The Sphinx build is warning-free under
sphinx-build -W(sphinx.ext.napoleon, avisit_abbreviationshim, docstring list fixes, newautomoduleentries,setup.rstremoved). - Docs: New
CONTRIBUTING.md,CLAUDE.md,.github/copilot-instructions.md, a PR template (with a no-AI-co-author checkbox) and issue templates (bug_report.yml,feature_request.yml,data_quality.yml). - Packaging: The license is an SPDX expression (
license = "MIT",license-files = ["LICENSE"]) for Metadata 2.4. - Packaging: The wheel excludes
tests*,Sphinx-docs*,docs*,examples*,archive*,recipe*,dev*; package data still shipscfb/models/*+nfl/models/*;MANIFEST.intrimmed. - Packaging:
psutilis optional indecorators.py(lazy import). - Packaging: The version jumps to
0.0.50(rather than0.0.41) to signal scope; still alpha. - Tests: New
tests/wbb/,tests/wnba/,tests/conftest.py(@skip_if_no_live,SDV_PY_LIVE_TESTS=1) andtests/README.md; NFL test files renamed descriptively;pytest.inifilters thenspkg.pthandpkg_resourceswarnings. - Tests: Pickcenter regression tests for CFB and NFL: a 2024+ game must not fall back to the
(2.5, 55.5, True, False)defaults, and a pre-2024 game keeps the legacypickcenterpath. - Tooling: Ruff (lint, import sort, pyupgrade, format) replaces black + isort + pycln + flake8, with
line-length = 120andE712ignored forpl.col(...) == True/False; isort only addsfrom __future__ import annotations. - Tooling: New pre-commit hooks:
pre-commit-hooks,pygrep-hooks,add-trailing-comma,sync-pre-commit-deps,check-jsonschema,actionlint,yamlfmt,doctoc,markdownlint-cli2.
Deprecated
- NFL: Per-type Next Gen Stats and PFR advanced-stats loaders emit
DeprecationWarningand forward toload_nfl_nextgen_stats(stat_type=...)/load_nfl_pfr_advstats(stat_type=, summary_level=); no removal yet.
Fixed
- CFB: Kneel-downs are flagged and excluded from
scrimmage_play. - CFB: Yardage parsing rewritten: pass-yards regex tightened (
(?<=for)→(?<=[\s,]for)), a full punt rewrite and a fair-catch fix. - CFB: Feature edge cases: end-state, the NCG 2025 GW play /
drive.idhardcode,lead_halfat end of half, OOB punts, FG classification, andend.TimeSecsRemnow leads as WPA inputs expect. - CFB: WPA end-of-game and onside-kick branches rewritten, with
penalty_assessed_on_kickoffplumbed through penalty setup, EPA and WPA. - CFB: Duplicate
yds_punteddefinition removed. - CFB/NFL: Havoc / turnover box:
def_intfield name fixed, deterministic group order, andturnover_boxemits a cli warning instead of silently padding an empty dict. - HTTP:
download()retries iteratively, initializesresponse = None, and re-raises the last exception when the retry budget is exhausted. - NFL:
load_nfl_schedulereadsnflverse-data/releases/download/schedules/games.parquet(1999–2025) instead of the stalesched_{season}.rds, which 404'd on every season. - NFL: With an empty
pickcenter(all 2024+ games), odds come from the modern core.../oddsendpoint instead of the(2.5, 55.5, True, False)defaults; e.g. the 2024 CFP semifinal is now(-3.5, 67.5, True, True). - NFL:
__helper_nfl_pbp_featureshandles ESPN returningoverUnderas a Python float. - Packaging:
pkg_resources.resource_filename→importlib.resources.files()incfb_pbp.pyandnfl_pbp.py, so setuptools 81+ no longer warns at import (or breaks it).
0.0.40 Release: December 6, 2025
Changed
- MBB/WBB:
mbb_calendarandwbb_calendarinclude all games, even when top 25 teams are not competing.
0.0.38-39 Release: August 28, 2023
Changed
- CFB:
cfb_pbpfunctions improve the WP calculation and player parsing.
0.0.36-37 Release: July 9, 2023
Breaking changes
- Polars: Most dataframe operations now use
polars; many functions return a polars DataFrame and takereturn_as_pandas(defaultFalse).
Upgrade notes — pass return_as_pandas=True to get a pandas DataFrame instead of a polars one.
Added
- CFB:
load_cfb_betting_lines()(2006 through 2019 only). - ESPN:
espn_cfb_game_rosters(),espn_nba_game_rosters(),espn_nfl_game_rosters(),espn_nhl_game_rosters(),espn_wbb_game_rosters()andespn_wnba_game_rosters(). - HTTP:
**kwargspass through todl_utils.download():headers,proxy,timeout(default 30s),num_retries(default 15),logger(defaultNone).
0.0.34-35 Release: May 7-9, 2023
Breaking changes
- CFB:
sportsdataverse.cfb.espn_cfb_schedule()results are flattened somewhat, now including some nested data frame and list columns.
Changed
- Loaders: Loader locations use sportsdataverse-data releases and nflverse releases.
- Packaging: Imports reconfigured.
- Packaging: Improved compliance with pandas upgrades.
0.0.18 Release: July 25, 2022
Breaking changes
- CFB:
sportsdataverse.cfb.cfb_teams()is renamedsportsdataverse.cfb.espn_cfb_teams()to avoid an edge case issue when running the function.
Added
- ESPN:
ondaysparameter on the ESPN calendar functions.
0.0.17 Release: July 9, 2022
Breaking changes
- CFB:
sportsdataverse.cfb.cfb_teams()is renamedsportsdataverse.cfb.get_cfb_teams()to avoid an edge case issue when running the function.
Added
- MLB: MLBAM API functionality; see the docs for how to use the new functions.
Changed
- Loaders: Functions that load multiple files show progress bars.
Fixed
- NFL:
sportsdataverse.nfl.load_nfl_schedule()no longer causes a 404 error.
0.0.15 Release: May 8, 2022
Changed
- All leagues: Schedule and teams functions refactored.
- All leagues: More robust home/away mappings simplify assignment.
0.0.14 Release: March 16, 2022
Changed
- All leagues: Schedule and teams functions refactored.
- All leagues: More robust home/away mappings simplify assignment.
0.0.12 Release: February 24, 2022
Added
- PBP: A
rawparameter on the pbp functions returns the object as it comes in, without any transformation.
Changed
- PBP: Minor refactor of all the pbp functions, normalizing behavior.
Fixed
- Config: Some config file corrections.
0.0.5 Release: October 20, 2021
Changed
- Package: Original notes: "f'in round", "findin' out".