Skip to main content

Changelog archive

Releases before 0.1.5. The newest are on the Changelog.

0.1.4 Release: September 1, 2026​

Added​

  • CFB: create_box_score adds AirYds, aDOT, CompAirYds, YAC and AirYdsPct to the pass and receiver sections; 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) and penalty_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_pbp grows 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 -1 marker, kick returns read against the wrong possession team, an all-zero end state); EP_between no longer folds across a score, a no-effect penalty has no penalty EPA, yds_sacked is right for 2004-07. (#408, #411, #413)
  • CFB: wp_after no 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, USC for South Carolina, OSU for 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) raised ColumnNotFoundError on every call since load_cfb_rosters moved to ESPN in 0.1.1 (#399); it now keys on team_id and 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_version now 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_name columns where ESPN has no participant; such a play still forms its own C.Parker box-score row beside Carson Parker. (#407)

0.1.2 Release: August 27, 2026​

Fixed​

  • CFB: create_box_score no longer returns an empty advBoxScore["pass"] for every game when join_participants=True (no passers on Game on Paper); athlete_name is 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 (new AssetFetchError); NoESPNDataError remains an alias of NoDataError.
  • CFB datasets: new load_cfb_teams and load_cfb_team_info; load_cfb_rosters now reads ESPN rosters (breaking; load_cfb_rosters_cfbd keeps the CFBD frame).
  • NCAA basketball: loaders for all 24 published ncaa_* datasets, plus the league-wide RAPM solver and its input adapter.
  • New sportsdataverse.wexp win-expectancy harness (NFL + CFB) and the shared sportsdataverse.scrape.espn -raw archive 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.py modules), 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 (ep 0.996, wp 0.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-live reconciliation, 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 the scrape.espn / scrape.ncaa / scrape.stats engines with the proxy pool; at 0.1.0 the top-level namespace exported 4,653 public names.

Breaking changes​

  • CFB: load_cfb_rosters now reads the ESPN espn_cfb_rosters release instead of the CFBD-derived cfbfastR-data asset; the CFBD-backed frame is available as load_cfb_rosters_cfbd. (#399)
  • Config: MBB_TEAM_LOGO_URL and WBB_TEAM_LOGO_URL are removed from sportsdataverse.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 new AssetFetchError, so a 403 or exhausted retries never reads as an empty season. (#397, #402, #404)
  • NBA: the remaining 12 nba_stats loaders point at END-year-named assets. (#367)
  • NBA / WNBA: a read-only raw store is now actually offline: a miss raises RawStoreMissError instead 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) and load_cfb_team_info (cfb_team_info release); load_cfb_schedule is re-documented for the unified cfb_schedules dataset (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-column CFBFASTR_SCHEMA; parse_cfb_ncaa_drives adds n_plays / yards (signed, null if omitted). (#384)
  • CFB: the cfbfastR series/first-down decomposition (firstD_by_*) is ported, plus new cfb_ncaa drive-title and scoring-summary parsers. (#336, #350, #351, #353, #355, #357, #358, #375)
  • College baseball: decompose_college_baseball_plays splits parse_college_baseball_ncaa_pbp so legacy 2012–2023 trees and new captures resolve to the same PBP_SCHEMA; scrape/ncaa/reference.py adds sport-generic team-list, schedule (new game_number) and roster parsers. (#390)
  • HockeyTech: all 20 league families (pwhl_pbp etc.) flag the twin shot row of each goal with is_goal_twin = True; drop flagged rows to deduplicate, or count shot rows as-is for boxscore SOG. (#368)
  • NBA: nba_stats revives videodetailsasset, videoevents and videoeventsasset (125 → 128 wrappers); parse_nba_stats_result_sets returns {"videoUrls": frame, "playlist": frame} for them. (#391)
  • NBA / WNBA: capture-live evidence now overrides source deprecation flags in codegen, expanding nba_stats 113 → 125 and wnba_stats 95 → 111 wrappers. (#383)
  • NCAA basketball: loaders for all 24 published NCAA datasets, load_ncaa_{mbb,wbb}_* for pbp, schedule, player_box, team_box, rosters, team_rosters, team_ids, possessions, lineups, matchup_stints, shots and rapm_within_team (min_season 2010; shots 2019). (#387)
  • NCAA basketball: mbb_ncaa_rapm_input turns published possessions + rosters into player-id-keyed lineup slots, with stable cross-season person_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 from ncaa_{lg}_rapm_within_team, so never cross-join the two. (#389, with #382, #388)
  • NCAA basketball: display_name_to_roster_key (in mbb_ncaa_names) maps a box-score "Surname, First" to the roster FIRST.MIDDLE.LAST key; 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_weekly loads the nfl_ratings_weekly release (1999-2025): one row per (season, as_of_week, team_id), fit only on games before week as_of_week (strictly exclusive).
  • PFF: new sportsdataverse/pff.py mints 184 league-scoped aliases pff_<slug>_<rest> (pff_nfl_facet_blocking_summary, pff_ncaa_*, pff_ufl_*, pff_aaf_*); the bare module-scoped pff_* names are untouched.
  • Scrape: sportsdataverse.scrape.espn, the shared engine for the NBA / MBB / WNBA / WBB ESPN -raw archives (write guard, str2bool / season_args, id canonicalizer, LeagueConfig); league is 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.wexp walk-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 (as build_mbb_season_wp / build_wbb_season_wp) appends pregame_home_prob + home_win_prob (Float64) to load_wnba_pbp frames. (#381)

Changed​

  • HTTP: NoESPNDataError is renamed NoDataError, since download() 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_possessions and load_nba_stats_game_lineups now document that their season column is the asset's END year: load_nba_stats_schedules(seasons=2024) returns season == 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 from load_cfb_schedule) is a producer-side gap and stays open; #392 was filed from the sweep.
  • WBB / WNBA: load_wbb_pbp / load_wnba_pbp document free-throw type_text / score_value semantics. (#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_v3 are DeprecationWarning shims (removal in 0.1.0) for load_nba_stats_pbp, load_nba_stats_possessions and load_nba_stats_game_lineups, which read a strict superset; seasons is unchanged (START year).
  • PWHL: pwhl_streaks has never returned data (the streaks view exists on neither transport) and now emits a DeprecationWarning pointing at pwhl_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_crosswalk ships a real KenPom default. (#340, #347–#349, #354, #359, #360, #363, #364)
  • CFB: cfb_fourth_down end-game clamps and the documented input contract are corrected, and cfb_season_odds is bit-reproducible under seed= (a .unique() row order had moved tiebreak probabilities by about 1/n_sims between identical calls). (#392, #398, #400, #401)
  • CFB: cfb_season_odds no 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_score per-player defense: split sacks credit 0.5 / 0.5 (and half the yardage), fumble_recoveries counts takeaways only, forced_fumbles groups by forced_fumble_team, and kickoff returns credit kick_return_team; team totals are unchanged. (#93)
  • CFB: load_cfb_passing's declared schema adds int_epa and sack_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_talent returned 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_ncaa parsers handle 2025-season page variants; multi-season loaders tolerate per-season schema drift. (#336, #350, #351, #353, #355, #357, #358, #375)
  • CFB: CFB_BASE_URL 404'd on the retired cfbfastR-data/main/pbp path; it now points at the espn_cfb_pbp release that load_cfb_pbp serves. (#9 follow-up)
  • Docs: on phones the landing-page hero buttons wrap instead of being clipped, and reference @return tables fit the viewport instead of showing only the column names.
  • HockeyTech: a dead view (HTTP 200 with Undefined Tab <view> or InvalidView error) now warns instead of returning a silent empty frame, in all 20 league families. (#238)
  • HockeyTech: build_on_ice evaluates goal rows GOAL_EPSILON_S (2) seconds early, so goals no longer get the post-goal line and a wrong strength_state; goal_epsilon_s=0 restores the old behavior. (#369)
  • HTTP: Ctrl-C during a release-asset read interrupts again instead of being swallowed into an HTTP request by the PanicException recovery. (#397, #402, #404)
  • MBB: the Torvik loader rejects an HTML error body instead of parsing it as CSV. (#398, #400, #401)
  • NBA: drafthistory is live for LeagueID=00, not barren. (#362)
  • NBA / WNBA: every *v3 boxscore wrapper returned a (0, 0) frame; the parser now builds PlayerStats + TeamStats sets from the nested boxScore* 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, scheduleleaguev2 parses. (#348, #371, #372, #373, #374)
  • NCAA basketball: ncaa_{mbb,wbb}_shots period and sec_left were null in every season (2019–2026); shot_events_to_frame now derives them era-aware from the game clock. (#386)
  • NCAA basketball: a guard asserts every team_aliases pair also resolves through same_school (the NIU / Northern Ill. flaw), and near-identical schools such as Miami (FL) / Miami (OH) stay distinct. (#378)
  • NFL: NFLPlayProcess no longer raises KeyError: 'name' for franchises without a mascot (every 2020-2021 Washington Football Team game); the mascot is derived from displayName. (#23)
  • NHL: nhl_teams() works again (NHL_TEAM_LOGO_URL 404'd) and return_as_pandas=True returns a DataFrame instead of a bound method. (#9 follow-up)
  • Packaging: the wheel no longer installs the repo's dev/ and tools/ 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_scoreboard and its 1,343 siblings reach the top level; nba_stats / wnba_stats deliberately 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 repaired cfbfastR-cfb-raw corpus; 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 .ubj has a .card.json model card recording objective, feature list, training season span, hyperparameters, boost rounds and source frame (previously None).
  • 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_config with MBB / WBB); league is a required keyword on every entry point.
  • Scrape: scrape.ncaa.parse is re-runnable: --season (repeatable) scopes the sweep and --force re-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_cffi Chrome impersonation) and observability; like scrape.ncaa, it is not re-exported at the top-level sportsdataverse namespace.
  • Scrape: scrape.stats Phase 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) and refill.

Changed​

  • CI: a new docs-deploy workflow builds the docs site on pushes to main that touch docs/** and publishes it as a single orphan commit on gh-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 rolling main version, with no external service.

Fixed​

  • Scrape: scrape.ncaa stage CLIs no longer scan an empty tree and report success having done nothing (bundles=0, EXIT=0): --root defaults to each repo's REPO_ROOT via 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 raises ModuleNotFoundError on the nonexistent sportsdataverse.nba.wnba_stats; refill resolves 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_team now hold the team name (String) and the id moves to new pos_team_id / def_pos_team_id (Int64); def_pos_team is in adv_defensive / adv_defensive_players. Summaries are unaffected.
  • CFB: cfb_adjusted_epa now actually opponent-adjusts: the ridge default _RIDGE_LAMBDA drops from 325 to 0.035 and RatingsConfig.ridge_lambda from 0.05 to 0.035. The old fit left raw-EPA order intact (Spearman 0.999982), so adjusted ratings and ranks change substantially.
  • CFB: opportunity_run now means a rush of 4+ yards (yds_rushed >= 4, the cfbfastR definition; was <= 4), so opp_highlight_yards, identically 0 in every published row, now carries values. Published espn_cfb_pbp assets carry the old values until republished.
  • CFB: opportunity_run, highlight_run and adj_rush_yardage gate on the rush flag instead of type.text == "Rush", so rushing touchdowns and own-fumble-recovery rushes count and adj_rush_yardage is no longer null on them.
  • CFB: nine CFB loaders now return team_id as Int64 (was String in passing, receiving, rushing, team_summaries(+_weekly), ratings(+_weekly), recruiting_proj; Int32 in team_info), so cross-dataset team_id joins 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.yaml gains an id_int64: key; a generated loader then emits a _cast_ids_int64 call, which casts only when every value round-trips ("007" or 1.5 leave 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_pbp and 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_off duplicates EPA_overall_offense; and EPA_explosive_rate is not EPA_explosive / EPA_plays.
  • Docs: generated loader returns tables gain a description column, resolved from manual_column_descriptions.yaml with the R-package column dictionary as fallback.

Fixed​

  • CFB: plays carrying ESPN's -1 end.yardsToEndzone sentinel now recover the end yardline from end.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_rate no longer reads 1.0 for every team in every season (2024's real rate is about 0.055): boolean nulls are now filled with False before 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_passing gains xComp, CompPct, xCompPct, CPOE and types rush_epa / pen_epa as Float64 (not Null).
  • Docs: load_cfb_adv_defensive_players documents 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_gamelog is rebuilt for 2004–2025 on the new adv_* shape; it still exposes team_id plus a readable team / opponent, so its consumers see no change.

0.0.73 Release: August 1, 2026​

Breaking changes​

  • CFB: adj_off / adj_def / adj_net in efficiency_ratings / cfb_ratings are now the netted R adjust_epa statistic (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_scale 34.49 → 44.54, margin_sd, total_*; hfa_epa unchanged).
  • CFB: adj_st_epa is 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 to fbs_only=True (FBS-vs-FBS games only) and drop_kneels=True (kneel-downs removed), matching game-on-paper; ratings shift, and cfb_resume / cfb_season_odds inherit 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 (tag espn_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_weekly and load_cfb_team_summaries_weekly return long format, one asset per season with a through_week column; filter through_week == W for 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.com runtime's timeout and retry are tunable.

Changed​

  • CFB: the roster join behind pre-2014 {type}_player_id gains 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_id source 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_name values drop the 2004 "(TEAM)" suffix (Matt Leinart, not Matt 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_rushing and load_cfb_team_summaries no longer raise SeasonNotFoundError for the published 2004–2013 seasons; load_cfb_play_participants and the two crosswalk loaders keep their real 2014 floor.
  • Docs: declared returns tables corrected: season is Int64 (not Float64) for load_cfb_passing / _receiving / _rushing / _team_summaries, and load_cfb_passing declares the republished Int32 sacked / 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 vctrs extension-metadata panic.
  • RDS: write_rds streams 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) and nba_availability now mean 2023-24, matching most_recent_nba_season() and the ESPN-sourced load_nba_* datasets.
  • New nba_stats / wnba_stats families: 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 the sportsdataverse.release publishing module.

Breaking changes​

  • MBB: the helper_{nba,mbb}_* release-parity producers emit play-by-play id as 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) and nba_availability take 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_proxy gain xg_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_sd is re-fit 1.21 → 1.19.
  • WBB: id in 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_pbp loads the espn_cfb_model_pbp release (EP/WP/QBR-enriched play-by-play, 2004–), which was published but unreachable from Python.
  • CFB: load_cfb_ratings(seasons) loads the cfb_ratings release (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, and cfb_advanced_constants.
  • CFB: recruiting spine: load_recruit_classes (247 RDB signing classes), blue_chip_ratio, cfb_roster_talent (optional composite_247 override), cfb_returning_production, and cfb_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) and load_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, optional rankings=), cfb_simulations / cfb_compute_results, cfb_games_from_schedule; conference rank and sov / sos are 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, signed yards_gained, kick / turnover / penalty detail, qb_scramble).
  • CFB: cfb_ncaa_box parsers: 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/data rankings 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 positions RDB route and a new auth-free sports247_site_pages stem.
  • College baseball: parse_college_baseball_ncaa_pbp and softball twin parse_college_softball_ncaa_pbp split 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_rankings for 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, _possessions and more, plus resolve_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) and mbb_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}, the mbb_ncaa_{roster,boxscore,pbp}_parser parsers, 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 an NcaaFetchConfig singleton configured by SDV_PY_NCAA_* / SDV_PY_PROXYBONANZA_* env vars.
  • MBB: lineup_stats_bucket / lineup_stats_buckets (mbb_ncaa_lineup_aggregation) build the 254-field LineupStatSet bucket, so a real NCAA game runs parse → enrich → buckets → the ported models.
  • MBB: hoopR release-parity producers helper_{nba,mbb}_* let hoopR-nba-data / hoopR-mbb-data compile their datasets in Python, including new officials and player_season_stats helpers.
  • MBB: parse_ncaa_bb_officials, parse_ncaa_bb_team_stats and parse_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, via espn_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), pregame predict_margin / win_prob_from_margin / predict_total / mbb_predict_games, and in-game in_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), and mbb_season_sim / mbb_bracket_sim / simulate_game.
  • MBB: load_mbb_ratings / load_mbb_player_value load the published model tags (floor 2006).
  • MLB: game-state spine: mlb_run_expectancy_matrix + run_value(...) (RE24, exported at sportsdataverse.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 (112 nba_stats_<slug> wrappers at stats.nba.com) routed by league_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 a dict for multi-set payloads, and flattens the shot-location and scoreboardv3 shapes.
  • NBA: nba_play_context / wnba_play_context (Cleaning the Glass): per-possession possession_start_type{,_detail,_ctg}, is_transition, is_garbage_time, is_heave_possession; per-shot ctg_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) and starters_on_court_counts, which upgrades garbage_time_basis to margin+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_value runs the five shot models (include_context=), with nba_shot_value_lineups; league_id picks 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 RatingsModel harness 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 when SDV_PY_NBA_ORACLE_DIR is set.
  • NBA: external_validity (five published-metric loaders in nba_oracle_data.py: RAPM, EPM, LEBRON, DPM, ewins) and walk_forward retrodiction, in nba_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 via nba_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-season AGE via nba_player_ages.py.
  • NBA: nba_v3_to_v2_pbp(pbp_v3, box_v3, *, return_as_pandas=False) builds the 61-column v2 pbp frame from playbyplayv3 + boxscoretraditionalv3 (playbyplayv2 returns 0 rows), recovering assist / block / steal / sub / jump-ball players.
  • NBA: a stats_nba feed shim lets the v2 frame drive pbpstats' v2 provider (opt in with SDV_PBPSTATS_ROOT); PLAYER1_TEAM_ID is 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-shooter build_possession_shooting frame, and game_date on compile_nba_season output (cache PIPELINE_VERSION 1 → 2).
  • NBA: possessions gain dreb, number_in_period, possession_start_type, count_as_possession; the shooting frame gains team_id (cache PIPELINE_VERSION 2 → 3).
  • NBA: quarter-box lineup seeding: players_on_court_from_quarter_boxscores and lineup_source="quarter_box" on nba_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= on nba_possessions, compile_nba_season and the fetchers, or env SDV_PY_NBA_RAW_JSON_DIR / SDV_PY_NBA_RAW_JSON_DIR_{ENDPOINT}.
  • NBA: load_nba_player_impact(seasons) loads the nba_player_impact release (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, cached SDV_PY_PFF_STORAGE_STATE_TTL seconds, default 300), as tier 3 after cookies= and SDV_PY_PFF_* env cookies.
  • NFL: PFF Premium Stats 2.0 stem pff_core (premium.pff.com/api/v1, cookie auth, 46 wrappers) with make_pff_league_module shims for nfl / ncaa (cfb) / aaf / ufl; pff_login is an experimental stub.
  • NFL: nfl_season_standings, an nflseedR v2 standings port with the real tiebreaker cascades and tiebreaker_depth (RANDOM < PRE-SOV < SOS < POINTS); nfl_standings is the api.nfl.com wrapper.
  • NFL: nfl_simulations / nfl_compute_results: week-by-week season simulation with a pluggable compute_results (default: the nflseedR ELO generator), playoffs with reseeding and byes_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), shared nfl_ngs_constants.
  • NFL: scheme & special-teams spine: nfl_playcall (run/pass + play-family model, bundled nfl_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, shared nfl_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 for nba_stats / wnba_stats and 247Sports) is a lazy optional import in the tests and all extras; without it, a clear ImportError says how to install it.
  • Packaging: PFF storage_state refresh needs the new optional Playwright extra: pip install sportsdataverse[pff], then playwright install chromium; a missing install raises a clear ImportError.
  • PWHL: pwhl_xg_proxy, a PWHL game-prediction model: a 2-tier xG proxy from the categorical shot_quality, feeding the league-agnostic opponent-adjustment + market core.
  • PWHL: fit_pwhl_coord_xg gains calibrate_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) derives skaters_home / skaters_away, strength_state (5v5 / 5v4 / 6v5) and strength_state_valid; empty net is not derived (use the goal-level empty_net).
  • PWHL: pwhl_shot_xg() scores every shot into a 21-column _SHOT_XG_SCHEMA frame (model= reuses one fit), and load_pwhl_shifts() / load_pwhl_xg_pbp() load the pwhl_shifts / pwhl_xg_pbp tags.
  • Release: new sportsdataverse.release module (port of R sportsdataversedata v0.0.11): sportsdataverse_save() (rds / csv / csv.gz / parquet, type + timestamp metadata) and sportsdataverse_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, qs raises ValueError, no .token (GH_TOKEN falls back to GITHUB_PAT).
  • Release: native .rds writer (sportsdataverse/_rds.py, RDS v2 / XDR) needing no R or new dependency, byte-for-byte equal to R 4.5.3 saveRDS(); nested / list columns raise ValueError.
  • Validation: new constant_column check flags all-null / all-NaN and zero-variance columns as WARN needs_judgment, minus a per-dataset expected_constant_columns allowlist.
  • 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 a period_model knob (WBB binds (4, 600, 300)), fixing wbigballR's halves math that misreads regulation WBB as 2-OT; plus parse_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, the wbb_shots release 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 (95 wnba_stats_<slug> wrappers at stats.wnba.com) and the parse_wnba_stats_result_sets alias.
  • 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_nba is_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_participation crashes on multi-season loads (cross-season schema drift); load per season and combine with how="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/data rankings names (on3_player_rankings, on3_industry_player_rankings, on3_team_rankings, on3_industry_team_rankings) are deprecated shims that keep working.
  • NFL: calculate_nfl_standings is deprecated in favor of nfl_season_standings; the old name emits a DeprecationWarning.

Removed​

  • Packaging: the unused pyreadr dependency (runtime deps, the models / all extras, the conda recipe), which also drops the libbz2 / liblzma header requirement on Python 3.9 Linux installs.

Fixed​

  • CFB: cfb_ratings() works on the released espn_cfb_pbp asset (real calls like cfb_ratings(2023) raised KeyError); its HFA term is guarded on pos_team / home dtype 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 the cfb_recruiting_proj backfill on 2026). (#282)
  • CFB: pbp fixes from 0.36-live: kneel-down flag, cleaned_text / yds_rushed / yds_receiving parsing, box-score volume sort, kickoff fair catch → touchback (2018+), errored-punt end yardline, end_state_missing fill, OT order by sequenceNumber.
  • CFB: penalty-assessed-on-kickoff plays get the full end-state touchback, so their EPA neutralizes to 0.0; the penalty_flag guard now excludes Timeouts.
  • CFB: interception return yardage no longer counts toward offensive / drive / total_yards, and statYardage==0 completions are rebuilt from the yardline delta.
  • CFB: a game ending on a possession-flipping play outside end_change_vec (notably a safety) no longer reports home_wp_after = 1.0 for 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_ice end 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 with Retry-After-aware backoff (configurable via the new retry_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 Statistics stub forces a re-solve and retry (solve_attempts, default 2), and exhaustion raises so the layer rotates proxies. (#266)
  • MBB: raw_game_efficiency returns the typed _EFF_SCHEMA empty frame for a season with no boxscore asset instead of raising ColumnNotFoundError (also covers mbb_team_ratings / wbb_team_ratings). (#280)
  • NBA: compile_nba_season passes proxy_url to game discovery too, so a datacenter run no longer compiles zero games with exit 0; proxy_provider is now called N+1 times for an N-game season. (#283)
  • NBA: box_features maps the real leaguegamelog column fg3_m to fg3m, fixing a ColumnNotFoundError on 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_positions returns one row per player_id (traded players were listed once per team, fanning out the positions join in nba_bpm / nba_spm).
  • NBA: players_on_court_from_quarter_boxscores gains an optional raw_box name-map source, closing a mid-period name-resolution gap; quarter_box now matches players_on_court_from_pbp on the fixtures.
  • NFL: load_nfl_ff_playerids and load_nfl_ff_rankings retry with exponential backoff on HTTP 429/5xx instead of failing on the first hit.
  • PWHL: fit_pwhl_coord_xg / predict raise on a RAW-scale (0–600) frame instead of silently scoring it, and hockeytech._analytics.add_shot_distance_angle asserts goal_x is 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_TARGETS in step with registry.py.
  • WBB: box helpers derive availability from the payload, not ESPN's boxscoreAvailable flag (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_injuries has a release but zero assets (ESPN's CFB injuries feed yields nothing), so it has no loader.
  • CFB: the new constant_column check found all-zero sacked / pass_int / sack_yds columns in cfb_passing.
  • PHF: dataset URLs moved from raw.githubusercontent.com paths to dedicated sportsdataverse-data release 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) and cfb_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) gains qb_epa, wp / vegas_wp (+ def_wp / home_wp / away_wp) and xpass / 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 and fg models gain rule-era one-hots (era0..era4, cuts 2001/2005/2013/2017), and the bundled nfl/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-learn is now a runtime dependency.

Fixed​

  • NFL: calculate_xpass backfills the era0 / era1 features that _make_cp_mutations did not build.

0.0.70 Release: June 24, 2026​

Changed​

  • CFB: bundled qbr_model, fg_model and wp_spread are retrained on the full 2004–2025 corpus reprocessed with cfb_line_odds multi-book consensus odds and roster-backed pre-2014 player ids; feature contracts are unchanged (drop-in), and the fourth_down model is left unchanged.

0.0.69 Release: June 23, 2026​

Added​

  • CFB: CFBPlayProcess emits a {type}_player_id for 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: CFBPlayProcess emits cp / cpoe (100 * (completion - cp), pass plays) and xpass / pass_oe (100 * (pass - xpass), scrimmage rush-or-pass plays) from new bundled cfb/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 (plus def_ / home_ / away_ analogues), from new bundled cfb/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_diff and go_boost; CFBPlayProcess.add_fourth_down_probs() applies it to a processed game's fourth-down rows.
  • CFB: fourth-down models fg_model.ubj and punt_distribution.parquet (bundled) and fd_model.ubj (download-on-demand, cached under ~/.cache/sportsdataverse/cfb_models/, override with SDV_PY_CFB_MODEL_DIR).
  • CFB: sportsdataverse.cfb.get_2pt_probs(pbp_df) (cfb4th port) adds two_pt_wp, xp_wp, prob_2pt, two_pt_recommendation (go_for_2, kick_xp) and two_pt_wp_diff; CFBPlayProcess.add_2pt_probs() applies it to a processed game's point-after rows.
  • CFB: new bundled two_pt_model.ubj supplies prob_2pt; prob_xp is the empirical CFB extra-point make rate 0.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_xpass adds xpass and pass_oe to enriched NFL PBP, and nfl/nfl_fourth_down.py ports nfl4th's go / field-goal / punt WP and recommendation (download-on-demand fd_model / wp_model).
  • NFL: load_nfl_espn_qbr (alias load_espn_qbr) loads ESPN Total QBR: summary_type= season|week, 2006+, source= the nflverse espn_data or the SDV-native nfl_espn_qbr release.

Changed​

  • CFB: bundled qbr_model.ubj is 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.ubj the 5-feature one, and fd_model.ubj the 9-feature one, now bundled (was download-on-demand).
  • CFB: bundled wp_spread.ubj is 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_wp use 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.ubj is bundled under nfl/models/, so calculate_xpass works offline with no first-use download; output is unchanged.

Fixed​

  • CFB: the spread_time sign in _predict_wp is corrected to +pos_team_spread·exp(−4·elapsed_share); favorites had been scored as underdogs in get_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() in sportsdataverse/nfl/ep_wp.py, with the NFL EP/WP constants and column contract centralized in sportsdataverse/nfl/model_vars.py.

Changed​

  • CFB: bundled ep_model.ubj and wp_spread.ubj are 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 _global fallback), 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 napoleon Quick 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 to docs/docs/tutorials/): Soccer, Cricket, and Other ESPN leagues (UFL/XFL/CFL, college baseball/softball, NCAA hockey).

Fixed​

  • Codegen: refresh_return_schemas no longer writes 0-column per-league schemas that hid the generic schemas/{name}.yaml returns table.
  • NFL: faithful model artifacts replace the CFB 8-feature placeholders under nfl/models/ (ep_model.ubj 18 features, wp_spread.ubj 12, wp_naive.ubj 11, cp_model.ubj 18), fixing the xgboost num_feature >= num_col (8 vs 18) mismatch.

0.0.66 Release: June 17, 2026​

Fixed​

  • CFB: CFBPlayProcess.run_processing_pipeline() no longer raises ColumnNotFoundError: unable to find column "end.team.id" on sparse pre-2010 games (e.g. 2005 game 252440154); healthy games' output is unchanged.

0.0.65 Release: June 17, 2026​

Breaking changes​

  • MLB: the 64 generated mlb_api.py and 15 hand-written mlb_api_extra.py Stats API wrappers are renamed mlb_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 sportsdataverse now eagerly loads the 12 soccer-alias submodules, and discover.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 a DeprecationWarning.

Fixed​

  • ESPN: the seven espn_*_game_rosters (cfb, mbb, nba, nfl, nhl, wbb, wnba) no longer raise ColumnNotFoundError: "logos" not found on pre-2010 payloads, nor TypeError: the truth value of a Series is ambiguous from row-wise logo assignment.

0.0.64 Release: June 17, 2026​

Breaking changes​

  • MLB: the pre-0.0.64 statcast_* functions are renamed to the mlb_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=True for raw): 37 leaderboards, mlb_statcast_gamefeed and mlb_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's hf* params; mlb_statcast_player parses a page's serverVals section (default statcast, section=).

Changed​

  • Docs: returns tables for every frame-returning mlb_statcast_* function, and examples/notebooks/09_mlb_intro.ipynb modernized 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_rosters no longer hard-fail with ShapeError and discard a game whose two teams ship different roster columns (the per-team concat is now diagonal).
  • HTTP: dl_utils.download fails fast on a definitive 404 (NoESPNDataError) instead of retrying the full num_retries budget (~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_rosters and espn_nfl_game_rosters no longer raise ColumnNotFoundError on older games that omit the team-level statistics $ref.
  • ESPN: the same six builders tolerate one team's /roster 404: the other team's roster is returned, and NoESPNDataError is raised only when every team is empty.

0.0.61 Release: June 16, 2026​

Fixed​

  • CFB: espn_cfb_game_rosters no longer raises ColumnNotFoundError on older (e.g. pre-2021) games that omit the team-level statistics $ref.
  • CFB: espn_cfb_game_rosters tolerates one team's /roster 404 (common for older games and FCS opponents), returning the other team; NoESPNDataError is raised only when every team is empty.

0.0.60 Release: June 15, 2026​

Added​

  • NFL: sportsdataverse.nfl.ep_wp gains calculate_expected_points, calculate_win_probability, calculate_completion_probability (CP + CPOE) and calculate_xyac (four XYAC sub-models), wired into NFLPlayProcess with bundled XGBoost .ubj models.

Fixed​

  • CFB: espn_cfb_schedule skips the null-competitor placeholder events in the 2010 and 2014 scoreboards instead of raising TypeError: 'NoneType' object is not subscriptable.

0.0.59 Release: June 13, 2026​

Added​

  • CFB: 404-safe crosswalk loaders read the cfb_crosswalk release: load_cfb_teams_crosswalk(seasons=) and load_cfb_schedule_crosswalk(seasons=) are per season (min_season 2014, published 2014–2025); all accept return_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_* and espn_cfl_*.

0.0.58 Release: June 12, 2026​

Added​

  • Errors: a SportsDataverseError base class (SeasonNotFoundError / NoESPNDataError re-parented under it) and a package logger with a NullHandler; previously silent except paths now log.
  • MBB: loaders load_mbb_standings, load_mbb_player_season_stats, load_mbb_team_season_stats, load_mbb_rosters, load_mbb_officials and load_mbb_game_rosters, each with a returns table.
  • NBA: loaders load_nba_player_season_stats, load_nba_team_season_stats, load_nba_draft and load_nba_rosters, each with a returns table.
  • NFL: a new NFL_ACCESS_TOKEN env var injects a pre-minted api.nfl.com bearer token; nfl_clear_token_cache() forces a fresh mint and nfl_token_gen(force_refresh=True) re-mints.
  • Odds: new sportsdataverse.odds wrapping The Odds API v4 (oddsapiR toa_* parity): toa_sports, toa_sports_odds, toa_sports_scores, toa_sports_events, toa_event_odds, toa_event_markets, toa_sports_participants, three *_history variants and toa_usage.
  • Odds: the odds endpoints return long-format frames (event × bookmaker × market × outcome); the key comes from the ODDS_API_KEY env var or api_key=.
  • Packaging: ships a PEP 561 py.typed marker.
  • Yahoo: college football wrappers yahoo_cfb_player_season_stats, yahoo_cfb_team_season_stats, the *_season_stats_legacy variants, yahoo_cfb_scoreboard and a yahoo_cfb_boxscore scaffold.

Changed​

  • CI: a new quality.yml gate runs ruff, ruff format --check and mypy (with a [tool.mypy] files ratchet) 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 + auth support.
  • 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_KEY is imported from _fox_layout.DATA_KEY, so the bundled Fox key and its SDV_PY_FOX_DATA_KEY override live in one place.
  • HTTP: dl_utils.download() reuses a pooled requests.Session and backs off honoring Retry-After (seconds or HTTP-date, clamped non-negative, 120s ceiling) instead of a fixed sleep.
  • NFL: the api.nfl.com wrappers (nfl_standings, nfl_rosters, nfl_injuries, ...) are now generated from nfl_api.yaml; their signatures gain return_parsed / **kwargs.
  • NFL: the api.nfl.com bearer token is minted once, cached in-process and auto-renewed before its JWT exp, instead of a token POST on every call.
  • NHL: load_nhl_pbp, load_nhl_player_boxscore, load_nhl_team_boxscore and load_nhl_schedule read the SDV-native releases (nhl_pbp_full, nhl_player_boxscores, nhl_team_boxscores, nhl_schedules) instead of fastRhockey-data; min_season 2011 → 2010.
  • Tests: a VCR-style record/replay harness (committed, secret-scrubbed cassettes) exercises the real download() → parser path offline.

Fixed​

  • Codegen: the --audit-releases drift 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.com wrappers go through dl_utils.download() (retries, cache, error handling) instead of requests.get(), and None no longer leaks onto the wire from boolean flags or the nfl_weeks season / season_type path params.

0.0.57 Release: June 10, 2026​

Added​

  • Fox: read-only Fox Sports Bifrost wrappers over api.foxsports.com/bifrost/v1; CFB gets fox_cfb_pbp, fox_cfb_boxscore, fox_cfb_odds, fox_cfb_team_roster, fox_cfb_team_stats, fox_cfb_team_gamelog, fox_cfb_standings and fox_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_leaders and fox_mlb_odds; Fox exposes no MLB play-by-play or boxscore.
  • Fox: fox_cfb_play_process(event_id) runs Fox data through CFBPlayProcess (EPA / WPA / advanced box score) as a backup to ESPN (process=False cleans only, raw=True returns the adapted summary); the payload is tagged source="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_*_coaches and espn_*_calendar_{offseason,regular_season,postseason,ondays}. Use espn_*_season_coaches, the coach-detail endpoints (espn_*_coach, ...) or espn_*_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 and most_recent_<lg>_season, over one shared sportsdataverse.hockeytech core.
  • HockeyTech: <lg>_game_shifts, <lg>_player_toi, <lg>_game_corsi (on-ice Corsi/Fenwick) and an enriched <lg>_pbp for all five leagues; the feed has no missed shots, so every analytics output carries corsi_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 + /experience wrappers: 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, with game_id / home_team / visitor_team) and nfl_week_games(season, season_type, week) (one row per game) parse the raw game dicts.
  • NFL: NFL.com auth defaults to the public WEB_DESKTOP web-client credentials, overridable via the NFL_CLIENT_KEY / NFL_CLIENT_SECRET env vars or function args.
  • NHL: loader aliases load_nhl_team_box, load_nhl_player_box, load_nhl_skater_box and load_nhl_goalie_box (for load_nhl_team_boxscore, _player_boxscore, _skater_boxscores, _goalie_boxscores), plus load_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_box and load_pwhl_schedule (for the *_boxscores / load_pwhl_schedules loaders), plus load_pwhl_games(), the games-in-data-repo manifest.

Changed​

  • Docs: autodoc returns tables for all 23 new NFL functions.
  • Docs: each league index.md has 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: CFBPlayProcess and NFLPlayProcess pages document all 7 public methods, constructor parameter descriptions are backfilled from __init__, and CFBPlayProcess gains a class docstring.
  • Docs: the example notebooks grow to ten (05_wbb_intro and 08_wnba_intro split out, new 09_mlb_intro and 10_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/, via tools/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=) and full_name).
  • Docs: the parity tables no longer drop functions from additional.md or 404 their parity links (the "already documented" check no longer counts the index).
  • Docs: every autodoc heading carries a stable {#name} anchor, fixing the espn_nhl_teams link in ecosystem.md.
  • Docs: examples whose reST literal-block intro wraps across lines no longer leak prose into the code block (fixes the NflConfig and espn_wbb_team_stats examples).
  • Docs: ecosystem.md links all seven example notebooks, and each league index.md gains an Examples section linking the quickstart and that sport's intro notebook.
  • NFL: nfl_game_schedule / nfl_game_details work again, rebuilt on nfl_token_gen() and /identity/v3/token after 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 | description tables: endpoint pages from per-sport schemas, autodoc DataFrame functions from the new generate.py --autodoc-schemas pass.
  • Docs: Return-table column descriptions are filled by column name from the cfbfastR / hoopR / wehoop / baseballr @return docs (tools/codegen/r_column_descriptions.yaml); curated ones win.
  • NBA/WNBA: espn_nba_game_rosters / espn_wnba_game_rosters frames now include a team_alternate_ids_sdr column when ESPN ships it.

Fixed​

  • ESPN: espn_mbb_game_rosters / espn_wbb_game_rosters / espn_nfl_game_rosters no longer raise a ShapeError when ESPN ships extra *_$ref fields; columns are now renamed by source key.
  • NHL: espn_nhl_schedule no 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=True and return a tidy polars DataFrame instead of the raw Dict; wrappers without a registered parser still return Dict.

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.com coverage: 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 by generate.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 --coverage audit fails --check when an in-scope exported function is undocumented (allowlist: tools/codegen/coverage_allowlist.yaml).

Deprecated​

  • Parsed modules: sportsdataverse.parsed.{league} is deprecated: importing a parsed.* module emits a DeprecationWarning (it still works and will be removed in a future release). Migrate to from sportsdataverse.{league} import <fn>.

Fixed​

  • Docs: @return tables 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 web qualifier (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; use CFBPlayProcess(gameId=...).espn_cfb_pbp() followed by .run_processing_pipeline().
  • CFB: espn_cfb_* also gets season_* cleanups vs cfbfastR (futures / groups / recruits / week_rankings; powerindex -> team_powerindex); the exceptions live in tools/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 -> game in every position: bare event -> 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_espn no longer exposes the factory (make_league_module, _bind, the _*_WRAPPERS tables) or the private _site_v2_* / _core_v2_* core functions.
  • MBB/WBB: Removed espn_mbb_bracketology() / espn_wbb_bracketology(), the _common_ncaa.py module and register_ncaa_bracketology(); the ephemeral, non-league endpoint is no longer carried.
  • NHL: api-web wrappers drop the web qualifier 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_pbp and nhl_web_schedule keep their names (they collide with hand-written composites); the full rename map is tools/codegen/rename_map.yaml.
  • NHL: Removed the deprecated sportsdataverse.nhl.nhl_api module (it targeted the retired statsapi.web.nhl.com); use nhl_api_web / nhl_pbp instead.
  • WBB/WNBA: espn_wbb_player_stats / espn_wnba_player_stats now return one core-v2 season DataFrame instead of a dict of web-v3 category frames; the web-v3 payload moved to espn_wbb_player_stats_v3 / espn_wnba_player_stats_v3.
  • WBB/WNBA: The hand-written parsed espn_{wbb,wnba}_event_officials is renamed espn_{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() (and run_processing_pipeline()'s advBoxScore) gains a defensive_players section: per-defender sacks, pass_breakups, interceptions, forced_fumbles, fumble_recoveries (plus yards), keyed by def_pos_team + player_name.
  • CFB: New specialists box-score section: field_goals, punts, kick_returns, punt_returns (plus yards) keyed by pos_team + player_name; both new sections degrade to [] when empty.
  • CFB: New espn_team and espn_players box-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 flags is_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_turnover flags for blocked kicks the defense recovers, kept out of is_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) with season_type ("regular" / "postseason") and total params, plus espn_<league>_player_stats_v3 (web-v3 comprehensive).
  • Loaders: The release manifest grows from 24 to 92 loaders (WNBA espn_wnba_* + wnba_stats_*, the full NHL nhl_* family incl. EDGE/lite/boxscores, WBB, NBA, MBB), each with a @return table; load_cfb_betting_lines, get_cfb_teams and nhl_teams are kept.
  • NHL: New espn_nhl_* surface (115 functions): the full ESPN Site v2 / Web v3 / Core v2 surface, and find() now works for NHL.
  • PWHL: New sportsdataverse.pwhl league with 15 release-backed loaders (e.g. load_pwhl_pbp).

Changed​

  • CFB: The box-score turnover list is ordered [home, away] and every row carries team_id; key by team_id rather than list position.
  • CFB: The turnover section takes turnovers / Int / fumbles_lost from the ESPN box (espn_sourced=True); the play-by-play derivation stays under *_pbp keys as a fallback.
  • CFB: ESPN's native per-play isTurnover / isPenalty pass through as columns (populated back to 2018) as cross-checks, not sources of truth: isTurnover is coarser and isPenalty flags 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 (wpa is computed in-house), PBP is sparse before 2008.
  • Codegen: generate.py --check (and the sdv-codegen pre-commit hook) fail when committed wrappers or generated docs drift from the endpoint metadata; the default build writes them.
  • Codegen: New generate.py --audit-releases compares 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 --docs renders the reference tree into docs/docs/{league}/ (per-league index.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 @return table, a runnable example, a validated date) under its emitted name.
  • Docs: Loader docstrings carry |col_name|type| @return tables introspected from each parquet footer (tools/codegen/schemas/loader_schemas.yaml, generate.py --loader-schemas).
  • Docs: docs/sidebars.ts makes 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 (weekly live-tests-cron, non-blocking); 02_cfb_intro was rewritten to the CFBPlayProcess flow.
  • 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.md and 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', labelled main) 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 release cd 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/*.yaml into sportsdataverse/<league>/<league>_espn_ext.py instead 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 as summary remain 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}/stats becomes espn_*_player_stats_v3 only when a hand-written bare player_stats exists.
  • MLB: mlb_api is now generated and keeps its mlb_api_* names (non-breaking, 41 names); passthrough_query forwards hydrate / fields.
  • NHL: nhl_edge (35) and nhl_stats_rest (21) are now generated and keep their nhl_edge_* / nhl_stats_rest_* names; **filters (cayenneExp / sort / limit, …) still pass through and return_parsed is wired where a parser exists.
  • NHL: nhl_records is now generated and keeps its nhl_records_* names (non-breaking, 50 functions).

Removed​

  • Packaging: The legacy Sphinx pipeline (create_docs.sh + Sphinx-docs/) is deleted, and the sphinx / sphinx-markdown-builder / sphinx-material dev dependencies are dropped from the docs extra/group and the all extra.

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; legacy total_pen_yards kept).
  • 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() joins espn_cfb_play_participants, so player names no longer carry team prefixes (e.g. "BYU Dayan Ghanwoloku"); set join_participants = False to skip it.
  • CFB: An interception whose returner later fumbled is no longer relabeled "Fumble Recovery (Opponent)"; it stays "Interception Return" and keeps its int flag.
  • CFB: A sack-fumble the offense recovers is Fumble Recovery (Own) again, and a punt-return fumble the punting team recovers is Punt Team Fumble Recovery; EPA is recomputed to match.
  • CFB: A blocked field goal ESPN types as Extra Point Missed is relabeled Blocked Field Goal[ Touchdown], correcting its EPA; genuine blocked PATs are untouched.
  • CFB: Pre-2014 2pt Conversion rows resolve via scoringPlay to Two-Point Conversion Good / Two-Point Conversion Missed and score through the two-point path.
  • CFB: 2004 Unknown rows 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) becomes Kickoff.
  • 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 of gameSpread, overUnder, homeFavorite, gameSpreadAvailable is used as-is, so offline rebuilds never hit the network or default odds; a missing key or non-dict raises ValueError. No override = unchanged behavior.
  • CFB: New CFBPlayProcess.odds_source ("summary_pickcenter", "core_odds_api", "default" or "injected"), also written into the returned payload for run_processing_pipeline() / run_cleaning_pipeline() consumers.

Changed​

  • CFB: CFBPlayProcess(gameId=..., raw=True).espn_cfb_pbp() keeps the summary injuries and gameNotes keys (default []); all previously returned keys are unchanged.

0.0.51 Release: May 30, 2026​

Highlights

  • New sportsdataverse.mlb module (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=True on every ESPN wrapper and a 21-section summary dispatcher.
  • Quality-of-life helpers: find_team / find_athlete / find_event, parsed.*, a tiered response cache and the sdv CLI.

Breaking changes​

  • NHL: The deprecated statsapi.web.nhl.com host is gone, replaced by nhl_web_* wrappers on api-web.nhle.com/v1/; nhl_api.py keeps a small set of backward-compatible aliases that warn and delegate to nhl_api_web.

Added​

  • Cache: New sportsdataverse.cache tiered TTL response cache consulted by dl_utils.download: modes off (default), memory, filesystem via sdv.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= on download() overrides the tier; invalidate with sdv.clear_cache(), sdv.clear_cache(pattern="*roster*") or sdv.clear_cache(url="https://...").
  • CLI: New sdv console script: sdv find-team, sdv find-event, sdv list-functions, sdv function-count, sdv cache mode|stats|clear; --json emits raw JSON; exit codes 0 = success, 1 = no match, 2 = runtime error.
  • Discovery: New list_functions / function_count in sportsdataverse.discover (re-exported at the top level): a searchable function index with search=, league=, parsers_only= and wrappers_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.py keyed on (sport, league).
  • ESPN: make_league_module(sport, league, prefix, globals(), include_ncaa=, include_football=, include_mlb=) registers wrappers with real __name__ / __qualname__ / __doc__ for help(), IDE completion and inspect.signature().
  • ESPN: NCAA leagues (mbb, wbb, cfb) gain rankings, season_recruits and season_week_rankings; football (nfl, cfb) gains season_qbr and season_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 with return_as_pandas=True.
  • ESPN: Parsers return zero-row frames for empty / malformed payloads and snake_case columns; the ENDPOINT_PARSERS registry and parser_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 in ENDPOINT_PARSERS); the raw Dict default is unchanged.
  • ESPN: New generic parse_single_entity flattens single-resource Core v2 payloads to one row; parse_items now also covers ~30 more list-shape endpoints ({items: [...]} / {entries: [...]}).
  • ESPN: New parse_summary(payload, section=None) dispatcher for the Site v2 summary payload in every league: a dict of all sub-frames, or one frame with section=; registry SUMMARY_SECTION_PARSERS.
  • ESPN: Summary sub-parsers parse_summary_boxscore_player, parse_summary_boxscore_team, parse_summary_plays, parse_summary_winprobability (joins to plays on play_id) and parse_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_event name-to-ID resolvers in sportsdataverse.find (top-level re-export): case-insensitive substring match, multi=True, and a team-list cache cleared with clear_team_cache(league=None).
  • MBB/WBB: New espn_mbb_bracketology(season, iteration=None) / espn_wbb_bracketology(...) for the seasonal sports.core.api.espn.com/v2/tournament/{22,23}/seasons/{y}/bracketology endpoint (live roughly January-March, 404 otherwise).
  • MLB: New sportsdataverse.mlb module (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) wraps statsapi.mlb.com: sportId=1 is MLB, leagueId 103 = AL / 104 = NL, gameType slugs R/F/D/L/W/S/A/E/PO; player ids share Savant's MLBAM id space.
  • MLB: mlb_statcast.py (17 functions): statcast_search raises RuntimeError at the 25,000-row /statcast_search/csv cap (raise_on_truncation=True); statcast_search_chunked auto-chunks multi-week ranges.
  • MLB: The MLB-only espn_mlb_athlete_hotzones joins 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) and parse_mlb_api_person_stats (also mlb_api_team_stats).
  • MLB: Generic parse_mlb_api_list handles the other list-shape endpoints; MLB_API_ENDPOINT_PARSERS (26 entries) and parser_for_mlb_api(fn_name), which falls back to parse_mlb_api_list.
  • NFL/CFB: New parse_summary_drives / parse_summary_scoring_plays, and parse_summary_drive_plays, which unrolls drives.previous[].plays[] to one row per play with drive_id + drive_sequence; zero rows for non-football leagues.
  • NHL: nhl_api_web.py (26 nhl_web_* functions) covers the modern game-feed API at https://api-web.nhle.com/v1/, grounded in fastRhockey/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_10 paths 404 as of 2026-05-23 and are kept, with parse_edge_top10, for later.
  • NHL: nhl_stats_rest.py (21 functions) wraps api.nhle.com/stats/rest/ with verbatim Cayenne filter expressions via cayenneExp / factCayenneExp.
  • NHL: nhl_records.py (50 functions) wraps records.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, fallback parse_edge_payload, and sub-frame parsers parse_edge_sog_details, parse_edge_sog_summary, parse_edge_hardest_shots.
  • NHL: EDGE_ENDPOINT_PARSERS registers 33 of the 35 EDGE wrappers (the rest fall through via parser_for_edge); EDGE_SUBFRAME_PARSERS maps each detail wrapper to its sub-frame parsers.
  • NHL: New parse_nhl_stats_rest / parse_nhl_records handle every Stats REST / Records wrapper ({data: [...]} envelope); the meta endpoints config / componentSeason / ping give zero rows.
  • NHL: NHL_STATS_REST_ENDPOINT_PARSERS (17 entries); parser_for_nhl_stats_rest and parser_for_nhl_records always return a callable, never None.
  • NHL: New nhl_api_web_parsers game-center parsers parse_nhl_web_pbp, parse_nhl_web_boxscore (home_away, position_group), parse_nhl_web_landing and dispatcher parse_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) and parse_nhl_web_draft_picks; NHL_API_WEB_ENDPOINT_PARSERS (24 entries); parser_for_nhl_api_web(fn_name) returns None for playoff_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 polars DataFrame by default; the raw modules keep returning Dict.

Changed​

  • CI: .github/workflows/live-tests-cron.yml runs the live suite every Monday 13:00 UTC (and on workflow_dispatch); a failure opens, or comments on, a live-tests:drift tracking issue.
  • Docs: New docs/quality-of-life.md (before/after recipes) and an intro "Quickstart" with NBA / MLB / NHL one-liners that shows the parsed.* import path first.
  • Docs: README and docs/docs/intro.md gain "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.md and docs/parsers/fixtures.md (an index of the captured payloads).
  • Docs: New MLB pages docs/mlb/index.md, docs/mlb/parsers.md and docs/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.md and records.md, cross-linked, each with a "Parser layer" section.
  • Docs: espn_nhl_pbp's docstring (and a caution in docs/nhl/api-web.md) explains it is not interchangeable with nhl_web_pbp / parse_nhl_web_pbp (different id spaces and schemas).
  • Docs: docs/sidebars.ts groups leagues by sport family, with Architecture and Parsers expanded; parser and wrapper module docstrings carry a Documentation: link to their docs page.
  • Docs: CLAUDE.md gains "ESPN Cross-League Architecture (0.0.51+)" and "Parser Layer (0.0.51+)" sections.
  • Errors: NoESPNDataError 404 messages add a Suggestion: line from the URL, e.g. find_team(name, league='nfl'), find_athlete(name, league='mlb', team=<team>) or find_event(date, league='nba', home=..., away=...), reading the league from both ESPN URL shapes.
  • Packaging: pyproject.toml keywords grow 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 by SDV_PY_LIVE_TESTS=1, with tests/conftest.py as the single source of that gate plus a shared load_fixture(category, stem).
  • Tests: New offline tests/test_qol.py, tests/test_cache.py, tests/test_errors_suggest.py and tests/test_cli.py; importing parsed.* must not mutate the raw module's default.
  • Tooling: New sync-docs-changelog pre-commit hook copies CHANGELOG.md to docs/src/pages/CHANGELOG.md and stages it; nhl/nhl_loaders.py uses isinstance(seasons, int) (no behavior change).

Fixed​

  • ESPN: parse_team_roster handles the position-grouped roster shape (MLB / NFL / NHL / CFB), so those rosters unroll to one row per player with a position_group column 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, 25 load_* aliases and current-season / current-week helpers.
  • 11 new ESPN scrape modules across wbb and wnba (team rosters, season player and team stats, standings, draft, event officials), each with full @overload typing.
  • The 0.36-live → main polars 1.x reconciliation across all seven *_pbp.py modules (~165 sites).
  • PEP 621 pyproject.toml packaging (no more setup.py), conda-installable via recipe/meta.yaml.
  • A new cfb_play_participants module behind CFB player attribution.

Breaking changes​

  • Packaging: setup.py is removed; all metadata lives in PEP 621 [project] in pyproject.toml, and python -m build is 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.py and wnba/wnba_pbp.py moved 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_participants module reads ESPN's per-play participants endpoint and resolves sidecar-missing athletes via $ref (default-on resolve_missing=True); __add_player_cols delegates to it and keeps all 19 legacy _player_name columns via an alias mapping.
  • CFB: Hybrid scalar + list player columns ({type}_player_name plus {type}_player_names), so multi-entry types like split sacks are no longer collapsed to a single name.
  • CFB: New cleaned_text column 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]) and recipe/README.md for local conda build recipe/ and conda-forge staged-recipes submission.
  • 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=...) and load_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_rankings gains kind= as the preferred parameter; type= is kept for nflreadpy parity.
  • NFL: New get_current_nfl_season() / get_current_nfl_week() helpers in nfl/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, and return_as_pandas=True converts the single stored polars frame on read.
  • NFL: New NflConfig with update_config() / get_config() / reset_config() and env vars SDV_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) and wbb_standings / wnba_standings (WBB defaults to group=50).
  • WBB/WNBA: New wbb_player_stats / wnba_player_stats and wbb_team_stats / wnba_team_stats: multi-table dicts keyed Averages / Totals / Misc (always present), plus Other when needed.
  • WBB/WNBA: New wnba_draft (one row per pick) and wbb_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_name and interception_player_name, where ESPN's sidecar has documented gaps.
  • Conda: New .github/workflows/conda-build.yml builds, installs and smoke-imports the recipe on PRs touching recipe/ or pyproject.toml and 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.ipynb through 07_nhl_intro.ipynb), outputs cleared; .gitignore tracks examples/notebooks/*.ipynb.
  • Docs: The Sphinx build is warning-free under sphinx-build -W (sphinx.ext.napoleon, a visit_abbreviation shim, docstring list fixes, new automodule entries, setup.rst removed).
  • 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 ships cfb/models/* + nfl/models/*; MANIFEST.in trimmed.
  • Packaging: psutil is optional in decorators.py (lazy import).
  • Packaging: The version jumps to 0.0.50 (rather than 0.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) and tests/README.md; NFL test files renamed descriptively; pytest.ini filters the nspkg.pth and pkg_resources warnings.
  • 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 legacy pickcenter path.
  • Tooling: Ruff (lint, import sort, pyupgrade, format) replaces black + isort + pycln + flake8, with line-length = 120 and E712 ignored for pl.col(...) == True/False; isort only adds from __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 DeprecationWarning and forward to load_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.id hardcode, lead_half at end of half, OOB punts, FG classification, and end.TimeSecsRem now leads as WPA inputs expect.
  • CFB: WPA end-of-game and onside-kick branches rewritten, with penalty_assessed_on_kickoff plumbed through penalty setup, EPA and WPA.
  • CFB: Duplicate yds_punted definition removed.
  • CFB/NFL: Havoc / turnover box: def_int field name fixed, deterministic group order, and turnover_box emits a cli warning instead of silently padding an empty dict.
  • HTTP: download() retries iteratively, initializes response = None, and re-raises the last exception when the retry budget is exhausted.
  • NFL: load_nfl_schedule reads nflverse-data/releases/download/schedules/games.parquet (1999–2025) instead of the stale sched_{season}.rds, which 404'd on every season.
  • NFL: With an empty pickcenter (all 2024+ games), odds come from the modern core .../odds endpoint 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_features handles ESPN returning overUnder as a Python float.
  • Packaging: pkg_resources.resource_filename → importlib.resources.files() in cfb_pbp.py and nfl_pbp.py, so setuptools 81+ no longer warns at import (or breaks it).

0.0.40 Release: December 6, 2025​

Changed​

  • MBB/WBB: mbb_calendar and wbb_calendar include all games, even when top 25 teams are not competing.

0.0.38-39 Release: August 28, 2023​

Changed​

  • CFB: cfb_pbp functions 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 take return_as_pandas (default False).

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() and espn_wnba_game_rosters().
  • HTTP: **kwargs pass through to dl_utils.download(): headers, proxy, timeout (default 30s), num_retries (default 15), logger (default None).

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 renamed sportsdataverse.cfb.espn_cfb_teams() to avoid an edge case issue when running the function.

Added​

  • ESPN: ondays parameter on the ESPN calendar functions.

0.0.17 Release: July 9, 2022​

Breaking changes​

  • CFB: sportsdataverse.cfb.cfb_teams() is renamed sportsdataverse.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 raw parameter 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".