cfb-data 0.5.0__tar.gz → 0.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cfb_data-0.6.0/PKG-INFO +305 -0
- cfb_data-0.6.0/README.md +264 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/__init__.py +16 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_executor.py +101 -7
- cfb_data-0.6.0/cfb_data/cfb_data/_observability.py +111 -0
- cfb_data-0.6.0/cfb_data/cfb_data/_reference_enums.py +790 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_transport.py +166 -13
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_coordinator.py +494 -33
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/client.py +13 -1
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/enums.py +13 -0
- cfb_data-0.6.0/cfb_data/cfb_data/observability.py +632 -0
- cfb_data-0.6.0/cfb_data/cfb_data.egg-info/PKG-INFO +305 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data.egg-info/SOURCES.txt +3 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/pyproject.toml +1 -1
- cfb_data-0.5.0/PKG-INFO +0 -482
- cfb_data-0.5.0/README.md +0 -441
- cfb_data-0.5.0/cfb_data/cfb_data.egg-info/PKG-INFO +0 -482
- {cfb_data-0.5.0 → cfb_data-0.6.0}/LICENSE +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_catalog/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_catalog/merge.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_catalog/models.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_catalog/projection.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_catalog/sources.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_dataframes.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_parquet.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_request_rules.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_requests.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_tabular.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/adjusted_metrics/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/adjusted_metrics/models/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/adjusted_metrics/models/pydantic/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/adjusted_metrics/models/pydantic/requests.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/adjusted_metrics/models/pydantic/responses.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/adjusted_metrics/resource.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/base/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/base/types.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/betting/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/betting/models/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/betting/models/pydantic/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/betting/models/pydantic/requests.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/betting/models/pydantic/responses.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/betting/resource.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_backend.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_catalog.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_catalog_codecs.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_identity_codecs.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_key.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_models.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_null.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_redis.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_sqlite.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_sqlite_sql.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/config.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/policy.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/acquire_refresh_lease.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/begin_immediate.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/catalog_counts.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/cleanup_responses.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/delete_coverage_failure.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/delete_response.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/delete_team_aliases.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/enable_foreign_keys.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/enable_wal.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/find_athletes.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/find_conference_by_id.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/find_conference_by_name.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/find_fresh_coverage.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/find_game_by_id.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/find_games.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/find_team_by_id.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/find_team_by_name.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/find_venue_by_id.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/find_venue_by_name.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/get_response.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/get_response_size.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/get_schema_version.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/initialize_schema_version.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/release_refresh_lease.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/renew_refresh_lease.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/schema.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/select_catalog_observations.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/set_busy_timeout.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/set_synchronous_normal.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_athlete.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_athlete_team_season.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_catalog_observation.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_coach.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_coach_team_season.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_conference.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_conference_affiliation.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_coverage.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_coverage_failure.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_drive.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_game.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_play.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_playoff_matchup.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_recruit.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_response.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_team.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_team_alias.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_team_season.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_venue.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_vocabulary.sql +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/coaches/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/coaches/models/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/coaches/models/pydantic/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/coaches/models/pydantic/requests.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/coaches/models/pydantic/responses.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/coaches/resource.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/conferences/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/conferences/models/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/conferences/models/pydantic/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/conferences/models/pydantic/identity.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/conferences/models/pydantic/requests.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/conferences/models/pydantic/responses.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/conferences/resource.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/draft/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/draft/models/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/draft/models/pydantic/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/draft/models/pydantic/requests.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/draft/models/pydantic/responses.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/draft/resource.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/drives/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/drives/models/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/drives/models/pydantic/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/drives/models/pydantic/requests.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/drives/models/pydantic/responses.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/drives/resource.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/errors.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/games/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/games/models/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/games/models/pydantic/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/games/models/pydantic/identity.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/games/models/pydantic/requests.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/games/models/pydantic/responses.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/games/resource.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/identities/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/identities/_normalization.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/identities/contracts.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/identities/resource.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/info/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/info/models/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/info/models/pydantic/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/info/models/pydantic/requests.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/info/models/pydantic/responses.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/info/resource.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/metrics/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/metrics/models/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/metrics/models/pydantic/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/metrics/models/pydantic/requests.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/metrics/models/pydantic/responses.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/metrics/resource.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/players/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/players/models/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/players/models/pydantic/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/players/models/pydantic/identity.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/players/models/pydantic/requests.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/players/models/pydantic/responses.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/players/resource.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/playoffs/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/playoffs/models/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/playoffs/models/pydantic/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/playoffs/models/pydantic/requests.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/playoffs/models/pydantic/responses.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/playoffs/resource.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/plays/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/plays/models/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/plays/models/pydantic/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/plays/models/pydantic/requests.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/plays/models/pydantic/responses.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/plays/resource.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/py.typed +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/rankings/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/rankings/models/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/rankings/models/pydantic/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/rankings/models/pydantic/requests.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/rankings/models/pydantic/responses.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/rankings/resource.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/ratings/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/ratings/models/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/ratings/models/pydantic/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/ratings/models/pydantic/requests.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/ratings/models/pydantic/responses.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/ratings/resource.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/recruiting/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/recruiting/models/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/recruiting/models/pydantic/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/recruiting/models/pydantic/requests.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/recruiting/models/pydantic/responses.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/recruiting/resource.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/retry.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/stats/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/stats/models/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/stats/models/pydantic/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/stats/models/pydantic/requests.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/stats/models/pydantic/responses.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/stats/resource.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/teams/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/teams/models/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/teams/models/pydantic/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/teams/models/pydantic/identity.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/teams/models/pydantic/requests.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/teams/models/pydantic/responses.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/teams/resource.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/venues/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/venues/models/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/venues/models/pydantic/__init__.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/venues/models/pydantic/identity.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/venues/models/pydantic/responses.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/venues/resource.py +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data.egg-info/dependency_links.txt +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data.egg-info/requires.txt +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data.egg-info/top_level.txt +0 -0
- {cfb_data-0.5.0 → cfb_data-0.6.0}/setup.cfg +0 -0
cfb_data-0.6.0/PKG-INFO
ADDED
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cfb-data
|
|
3
|
+
Version: 0.6.0
|
|
4
|
+
Summary: Async validated CollegeFootballData access for pandas and Polars
|
|
5
|
+
Author: Ryan Anderson
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Documentation, https://ryanpaulanderson.github.io/cfb-data/
|
|
8
|
+
Project-URL: Repository, https://github.com/ryanpaulanderson/cfb-data
|
|
9
|
+
Project-URL: Issues, https://github.com/ryanpaulanderson/cfb-data/issues
|
|
10
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Requires-Python: >=3.12
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: aiohttp<4,>=3.13
|
|
19
|
+
Requires-Dist: aiosqlite<1,>=0.22
|
|
20
|
+
Requires-Dist: jinja2<4,>=3.1
|
|
21
|
+
Requires-Dist: pandas<4,>=3.0
|
|
22
|
+
Requires-Dist: pydantic<3,>=2.12
|
|
23
|
+
Requires-Dist: pyarrow<26,>=25
|
|
24
|
+
Provides-Extra: polars
|
|
25
|
+
Requires-Dist: polars<2,>=1.43.2; extra == "polars"
|
|
26
|
+
Provides-Extra: redis
|
|
27
|
+
Requires-Dist: redis<8,>=7.1; extra == "redis"
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: build<2,>=1.5; extra == "dev"
|
|
30
|
+
Requires-Dist: furo>=2025.12.19; extra == "dev"
|
|
31
|
+
Requires-Dist: mypy<3,>=2.3; extra == "dev"
|
|
32
|
+
Requires-Dist: myst-parser<6,>=5.1; extra == "dev"
|
|
33
|
+
Requires-Dist: pre-commit<5,>=4.5; extra == "dev"
|
|
34
|
+
Requires-Dist: pyarrow-stubs<21,>=20.0.0.20260625; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest<10,>=9; extra == "dev"
|
|
36
|
+
Requires-Dist: pytest-asyncio<2,>=1.3; extra == "dev"
|
|
37
|
+
Requires-Dist: ruff<0.17,>=0.15.22; extra == "dev"
|
|
38
|
+
Requires-Dist: sphinx<10,>=9.1; extra == "dev"
|
|
39
|
+
Requires-Dist: twine<8,>=7; extra == "dev"
|
|
40
|
+
Dynamic: license-file
|
|
41
|
+
|
|
42
|
+
# College Football Data Python Toolkit
|
|
43
|
+
|
|
44
|
+
`cfb-data` 0.6.0 is a pre-alpha Python toolkit for exploring the public
|
|
45
|
+
[CollegeFootballData API](https://collegefootballdata.com/). Most calls return
|
|
46
|
+
eager pandas DataFrames that are ready for analysis. Polars is available as an
|
|
47
|
+
option, and a few naturally nested results return Pydantic models.
|
|
48
|
+
|
|
49
|
+
This project is aimed at data professionals, statisticians, students, and fans
|
|
50
|
+
who want to spend their time analyzing college football rather than writing an
|
|
51
|
+
HTTP client or cleaning up inconsistent response shapes.
|
|
52
|
+
|
|
53
|
+
## What can I use it for?
|
|
54
|
+
|
|
55
|
+
- Pull games, plays, drives, ratings, rosters, recruiting, betting, draft, and
|
|
56
|
+
other CFBD data into Python.
|
|
57
|
+
- Explore one team or season in a notebook.
|
|
58
|
+
- Build repeatable pandas or Polars analyses across several endpoints.
|
|
59
|
+
- Cache responses locally so rerunning an analysis does not repeat every API
|
|
60
|
+
call.
|
|
61
|
+
- Resolve team, venue, game, and athlete names and IDs when joining data.
|
|
62
|
+
|
|
63
|
+
The package validates requests and responses before building a DataFrame. That
|
|
64
|
+
work happens inside the client; using it does not require knowing Pydantic,
|
|
65
|
+
Arrow, HTTP retry logic, or the cache implementation.
|
|
66
|
+
|
|
67
|
+
## Install
|
|
68
|
+
|
|
69
|
+
Python 3.12 and 3.13 are supported. pandas and PyArrow are included:
|
|
70
|
+
|
|
71
|
+
```shell
|
|
72
|
+
python -m pip install cfb-data
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
For Polars:
|
|
76
|
+
|
|
77
|
+
```shell
|
|
78
|
+
python -m pip install "cfb-data[polars]"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
For Redis caching:
|
|
82
|
+
|
|
83
|
+
```shell
|
|
84
|
+
python -m pip install "cfb-data[redis]"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
SQLite caching is included in the normal installation.
|
|
88
|
+
|
|
89
|
+
## Make a first request
|
|
90
|
+
|
|
91
|
+
Get an API key from [CollegeFootballData](https://collegefootballdata.com/) and
|
|
92
|
+
put it in the environment:
|
|
93
|
+
|
|
94
|
+
```shell
|
|
95
|
+
export CFBD_API_KEY="your-api-key"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Then fetch a team's games and start using ordinary pandas operations:
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
import asyncio
|
|
102
|
+
|
|
103
|
+
from cfb_data import CFBDClient
|
|
104
|
+
from cfb_data.enums import teams
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
async def main() -> None:
|
|
108
|
+
async with CFBDClient() as client:
|
|
109
|
+
games = await client.games.list(year=2024, team=teams.Michigan)
|
|
110
|
+
|
|
111
|
+
completed = games.dropna(subset=["home_points", "away_points"])
|
|
112
|
+
high_scoring = completed.assign(
|
|
113
|
+
total_points=completed["home_points"] + completed["away_points"]
|
|
114
|
+
).sort_values("total_points", ascending=False)
|
|
115
|
+
|
|
116
|
+
columns = ["week", "home_team", "away_team", "total_points"]
|
|
117
|
+
print(high_scoring[columns].head())
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
asyncio.run(main())
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The `async with` block lets related calls share one HTTP session and closes it
|
|
124
|
+
when the block ends. Async is limited to gathering and validating data; the
|
|
125
|
+
pandas calculation starts synchronously after the completed frame is returned.
|
|
126
|
+
|
|
127
|
+
## Find the data you need
|
|
128
|
+
|
|
129
|
+
Methods are grouped by subject:
|
|
130
|
+
|
|
131
|
+
| Namespace | Examples |
|
|
132
|
+
| --- | --- |
|
|
133
|
+
| `client.games` | Schedules, results, records, scoreboards, weather, box scores |
|
|
134
|
+
| `client.plays` and `client.drives` | Play-by-play, drive summaries, play types |
|
|
135
|
+
| `client.teams`, `client.players`, `client.coaches` | Teams, rosters, player search, coaches |
|
|
136
|
+
| `client.stats`, `client.metrics`, `client.ratings` | Team and player stats, PPA, win probability, Elo, SP+, FPI |
|
|
137
|
+
| `client.rankings`, `client.betting` | Polls and betting lines |
|
|
138
|
+
| `client.recruiting`, `client.draft` | Recruits, transfer portal, NFL draft data |
|
|
139
|
+
| `client.playoffs`, `client.adjusted_metrics` | CFP brackets and adjusted team/player metrics |
|
|
140
|
+
|
|
141
|
+
The [endpoint reference](docs/cfbd_api/README.md) lists every method, filter,
|
|
142
|
+
access tier, and returned shape.
|
|
143
|
+
|
|
144
|
+
For notebook-sized examples that answer common questions, see [Common notebook
|
|
145
|
+
recipes](docs/guides/common-recipes.md). It covers IDs versus full DataFrames,
|
|
146
|
+
minimal cache hydration, season summaries, joins, and concurrent async calls.
|
|
147
|
+
|
|
148
|
+
## Pass filters
|
|
149
|
+
|
|
150
|
+
For one-off calls, use snake-case keyword filters:
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
from cfb_data.enums import conferences
|
|
154
|
+
|
|
155
|
+
async with CFBDClient() as client:
|
|
156
|
+
games = await client.games.list(
|
|
157
|
+
year=2024,
|
|
158
|
+
season_type="regular",
|
|
159
|
+
conference=conferences.BIGTEN,
|
|
160
|
+
)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Use a request model when the same validated filters are shared or reused:
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
from cfb_data import CFBDClient, GamesRequest, SeasonType
|
|
167
|
+
from cfb_data.enums import conferences, teams
|
|
168
|
+
|
|
169
|
+
request = GamesRequest(
|
|
170
|
+
year=2024,
|
|
171
|
+
season_type=SeasonType.regular,
|
|
172
|
+
team=teams.Michigan,
|
|
173
|
+
conference=conferences.BIGTEN,
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
async with CFBDClient() as client:
|
|
177
|
+
games = await client.games.list(request)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Unknown filters and invalid combinations fail before an API call. See
|
|
181
|
+
[Requests and allowed values](docs/guides/requests.md) for common patterns.
|
|
182
|
+
The `teams` and `conferences` string enums provide autocomplete-friendly names
|
|
183
|
+
that exactly match season-specific API values while remaining directly
|
|
184
|
+
comparable with returned DataFrame strings.
|
|
185
|
+
|
|
186
|
+
## Choose pandas or Polars
|
|
187
|
+
|
|
188
|
+
pandas is the default. Selecting Polars only changes client construction:
|
|
189
|
+
|
|
190
|
+
```python
|
|
191
|
+
from cfb_data import CFBDClient
|
|
192
|
+
|
|
193
|
+
async with CFBDClient(dataframe_backend="polars") as client:
|
|
194
|
+
calendar = await client.games.calendar(year=2024)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
The two backends preserve the same columns, row order, nulls, and logical
|
|
198
|
+
values. pandas keeps nested values as Python dictionaries and lists; Polars
|
|
199
|
+
uses native `Struct` and `List[Struct]` columns.
|
|
200
|
+
|
|
201
|
+
See [Work with results](docs/guides/results.md) for analysis examples and
|
|
202
|
+
nested data, or [Advanced result details](docs/advanced/result-details.md) for
|
|
203
|
+
the exact dtype and Arrow behavior.
|
|
204
|
+
|
|
205
|
+
## Avoid repeated API calls
|
|
206
|
+
|
|
207
|
+
You do not need a cache for quick experiments. Add one when a notebook or
|
|
208
|
+
script repeatedly requests the same data while the analysis changes.
|
|
209
|
+
|
|
210
|
+
SQLite is the easiest option:
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
from cfb_data import CFBDClient, SQLiteCacheConfig
|
|
214
|
+
from cfb_data.enums import teams
|
|
215
|
+
|
|
216
|
+
async with CFBDClient(cache=SQLiteCacheConfig()) as client:
|
|
217
|
+
games = await client.games.list(year=2025)
|
|
218
|
+
repeated = await client.games.list(year=2025) # reused locally
|
|
219
|
+
michigan = await client.identities.teams.resolve(teams.Michigan)
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Redis is also a good local option if you already run it or want several
|
|
223
|
+
notebooks, scripts, or processes to share one cache:
|
|
224
|
+
|
|
225
|
+
```python
|
|
226
|
+
from cfb_data import CFBDClient, RedisCacheConfig
|
|
227
|
+
|
|
228
|
+
cache = RedisCacheConfig(url="redis://127.0.0.1:6379/0")
|
|
229
|
+
|
|
230
|
+
async with CFBDClient(cache=cache) as client:
|
|
231
|
+
games = await client.games.list(year=2025)
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Add a bounded in-memory collector when you want to see whether calls reached
|
|
235
|
+
the API or were served from cache:
|
|
236
|
+
|
|
237
|
+
```python
|
|
238
|
+
from cfb_data import CFBDClient, RetrievalStats, SQLiteCacheConfig
|
|
239
|
+
|
|
240
|
+
stats = RetrievalStats()
|
|
241
|
+
|
|
242
|
+
async with CFBDClient(cache=SQLiteCacheConfig(), observer=stats) as client:
|
|
243
|
+
await client.games.list(year=2025)
|
|
244
|
+
await client.games.list(year=2025)
|
|
245
|
+
|
|
246
|
+
snapshot = stats.snapshot()
|
|
247
|
+
print(snapshot.http_attempts) # actual client-side HTTP attempts
|
|
248
|
+
print(snapshot.fresh_cache_hits) # fresh initial cache hits
|
|
249
|
+
print(snapshot.fresh_hit_rate)
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
See [Cache responses and look up
|
|
253
|
+
identities](docs/guides/cache-and-identities.md) for use cases, the included
|
|
254
|
+
local Redis setup, cache modes, observability, identity examples, and
|
|
255
|
+
troubleshooting.
|
|
256
|
+
|
|
257
|
+
## Troubleshooting
|
|
258
|
+
|
|
259
|
+
| What you see | Start here |
|
|
260
|
+
| --- | --- |
|
|
261
|
+
| API key or access error | Check `CFBD_API_KEY` and the endpoint's Patreon tier. |
|
|
262
|
+
| Invalid filter or selector | Compare the call with the [endpoint reference](docs/cfbd_api/README.md). |
|
|
263
|
+
| Rate-limit error | Wait before retrying; consider SQLite or Redis for repeated calls. |
|
|
264
|
+
| Unexpected pandas dtype or nested value | See [Work with results](docs/guides/results.md). |
|
|
265
|
+
| Cache or identity lookup error | See [Cache troubleshooting](docs/guides/cache-and-identities.md#troubleshooting). |
|
|
266
|
+
| Another library exception | See [Troubleshooting requests](docs/guides/errors-and-retries.md). |
|
|
267
|
+
|
|
268
|
+
## Documentation
|
|
269
|
+
|
|
270
|
+
The [complete documentation](https://ryanpaulanderson.github.io/cfb-data/)
|
|
271
|
+
is organized in layers:
|
|
272
|
+
|
|
273
|
+
- **Start and use:** installation, examples, requests, results, caching, and
|
|
274
|
+
troubleshooting, including [common notebook
|
|
275
|
+
recipes](docs/guides/common-recipes.md).
|
|
276
|
+
- **Advanced details:** exact enum values, dtypes, TTLs, retries, and storage
|
|
277
|
+
behavior.
|
|
278
|
+
- **Project internals:** architecture decisions and contributor-facing design.
|
|
279
|
+
|
|
280
|
+
The [product constitution](docs/product-constitution.md) is the concise north
|
|
281
|
+
star used to evaluate product and engineering decisions.
|
|
282
|
+
|
|
283
|
+
The project is pre-alpha, and the documentation describes the current version.
|
|
284
|
+
|
|
285
|
+
## Development
|
|
286
|
+
|
|
287
|
+
```shell
|
|
288
|
+
git clone https://github.com/ryanpaulanderson/cfb-data.git
|
|
289
|
+
cd cfb-data
|
|
290
|
+
make install
|
|
291
|
+
make hooks
|
|
292
|
+
make format
|
|
293
|
+
make docs
|
|
294
|
+
make check
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Contributor standards, testing, release details, and architecture expectations
|
|
298
|
+
live in [`CONTRIBUTING.md`](CONTRIBUTING.md) and [`AGENTS.md`](AGENTS.md). They
|
|
299
|
+
are intentionally separate from the steps required to use the library.
|
|
300
|
+
|
|
301
|
+
## License
|
|
302
|
+
|
|
303
|
+
This project is licensed under the MIT License. See [`LICENSE`](LICENSE).
|
|
304
|
+
|
|
305
|
+
This project is not affiliated with CollegeFootballData.com.
|
cfb_data-0.6.0/README.md
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# College Football Data Python Toolkit
|
|
2
|
+
|
|
3
|
+
`cfb-data` 0.6.0 is a pre-alpha Python toolkit for exploring the public
|
|
4
|
+
[CollegeFootballData API](https://collegefootballdata.com/). Most calls return
|
|
5
|
+
eager pandas DataFrames that are ready for analysis. Polars is available as an
|
|
6
|
+
option, and a few naturally nested results return Pydantic models.
|
|
7
|
+
|
|
8
|
+
This project is aimed at data professionals, statisticians, students, and fans
|
|
9
|
+
who want to spend their time analyzing college football rather than writing an
|
|
10
|
+
HTTP client or cleaning up inconsistent response shapes.
|
|
11
|
+
|
|
12
|
+
## What can I use it for?
|
|
13
|
+
|
|
14
|
+
- Pull games, plays, drives, ratings, rosters, recruiting, betting, draft, and
|
|
15
|
+
other CFBD data into Python.
|
|
16
|
+
- Explore one team or season in a notebook.
|
|
17
|
+
- Build repeatable pandas or Polars analyses across several endpoints.
|
|
18
|
+
- Cache responses locally so rerunning an analysis does not repeat every API
|
|
19
|
+
call.
|
|
20
|
+
- Resolve team, venue, game, and athlete names and IDs when joining data.
|
|
21
|
+
|
|
22
|
+
The package validates requests and responses before building a DataFrame. That
|
|
23
|
+
work happens inside the client; using it does not require knowing Pydantic,
|
|
24
|
+
Arrow, HTTP retry logic, or the cache implementation.
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
Python 3.12 and 3.13 are supported. pandas and PyArrow are included:
|
|
29
|
+
|
|
30
|
+
```shell
|
|
31
|
+
python -m pip install cfb-data
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
For Polars:
|
|
35
|
+
|
|
36
|
+
```shell
|
|
37
|
+
python -m pip install "cfb-data[polars]"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
For Redis caching:
|
|
41
|
+
|
|
42
|
+
```shell
|
|
43
|
+
python -m pip install "cfb-data[redis]"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
SQLite caching is included in the normal installation.
|
|
47
|
+
|
|
48
|
+
## Make a first request
|
|
49
|
+
|
|
50
|
+
Get an API key from [CollegeFootballData](https://collegefootballdata.com/) and
|
|
51
|
+
put it in the environment:
|
|
52
|
+
|
|
53
|
+
```shell
|
|
54
|
+
export CFBD_API_KEY="your-api-key"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Then fetch a team's games and start using ordinary pandas operations:
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
import asyncio
|
|
61
|
+
|
|
62
|
+
from cfb_data import CFBDClient
|
|
63
|
+
from cfb_data.enums import teams
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
async def main() -> None:
|
|
67
|
+
async with CFBDClient() as client:
|
|
68
|
+
games = await client.games.list(year=2024, team=teams.Michigan)
|
|
69
|
+
|
|
70
|
+
completed = games.dropna(subset=["home_points", "away_points"])
|
|
71
|
+
high_scoring = completed.assign(
|
|
72
|
+
total_points=completed["home_points"] + completed["away_points"]
|
|
73
|
+
).sort_values("total_points", ascending=False)
|
|
74
|
+
|
|
75
|
+
columns = ["week", "home_team", "away_team", "total_points"]
|
|
76
|
+
print(high_scoring[columns].head())
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
asyncio.run(main())
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The `async with` block lets related calls share one HTTP session and closes it
|
|
83
|
+
when the block ends. Async is limited to gathering and validating data; the
|
|
84
|
+
pandas calculation starts synchronously after the completed frame is returned.
|
|
85
|
+
|
|
86
|
+
## Find the data you need
|
|
87
|
+
|
|
88
|
+
Methods are grouped by subject:
|
|
89
|
+
|
|
90
|
+
| Namespace | Examples |
|
|
91
|
+
| --- | --- |
|
|
92
|
+
| `client.games` | Schedules, results, records, scoreboards, weather, box scores |
|
|
93
|
+
| `client.plays` and `client.drives` | Play-by-play, drive summaries, play types |
|
|
94
|
+
| `client.teams`, `client.players`, `client.coaches` | Teams, rosters, player search, coaches |
|
|
95
|
+
| `client.stats`, `client.metrics`, `client.ratings` | Team and player stats, PPA, win probability, Elo, SP+, FPI |
|
|
96
|
+
| `client.rankings`, `client.betting` | Polls and betting lines |
|
|
97
|
+
| `client.recruiting`, `client.draft` | Recruits, transfer portal, NFL draft data |
|
|
98
|
+
| `client.playoffs`, `client.adjusted_metrics` | CFP brackets and adjusted team/player metrics |
|
|
99
|
+
|
|
100
|
+
The [endpoint reference](docs/cfbd_api/README.md) lists every method, filter,
|
|
101
|
+
access tier, and returned shape.
|
|
102
|
+
|
|
103
|
+
For notebook-sized examples that answer common questions, see [Common notebook
|
|
104
|
+
recipes](docs/guides/common-recipes.md). It covers IDs versus full DataFrames,
|
|
105
|
+
minimal cache hydration, season summaries, joins, and concurrent async calls.
|
|
106
|
+
|
|
107
|
+
## Pass filters
|
|
108
|
+
|
|
109
|
+
For one-off calls, use snake-case keyword filters:
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from cfb_data.enums import conferences
|
|
113
|
+
|
|
114
|
+
async with CFBDClient() as client:
|
|
115
|
+
games = await client.games.list(
|
|
116
|
+
year=2024,
|
|
117
|
+
season_type="regular",
|
|
118
|
+
conference=conferences.BIGTEN,
|
|
119
|
+
)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Use a request model when the same validated filters are shared or reused:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from cfb_data import CFBDClient, GamesRequest, SeasonType
|
|
126
|
+
from cfb_data.enums import conferences, teams
|
|
127
|
+
|
|
128
|
+
request = GamesRequest(
|
|
129
|
+
year=2024,
|
|
130
|
+
season_type=SeasonType.regular,
|
|
131
|
+
team=teams.Michigan,
|
|
132
|
+
conference=conferences.BIGTEN,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
async with CFBDClient() as client:
|
|
136
|
+
games = await client.games.list(request)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Unknown filters and invalid combinations fail before an API call. See
|
|
140
|
+
[Requests and allowed values](docs/guides/requests.md) for common patterns.
|
|
141
|
+
The `teams` and `conferences` string enums provide autocomplete-friendly names
|
|
142
|
+
that exactly match season-specific API values while remaining directly
|
|
143
|
+
comparable with returned DataFrame strings.
|
|
144
|
+
|
|
145
|
+
## Choose pandas or Polars
|
|
146
|
+
|
|
147
|
+
pandas is the default. Selecting Polars only changes client construction:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
from cfb_data import CFBDClient
|
|
151
|
+
|
|
152
|
+
async with CFBDClient(dataframe_backend="polars") as client:
|
|
153
|
+
calendar = await client.games.calendar(year=2024)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The two backends preserve the same columns, row order, nulls, and logical
|
|
157
|
+
values. pandas keeps nested values as Python dictionaries and lists; Polars
|
|
158
|
+
uses native `Struct` and `List[Struct]` columns.
|
|
159
|
+
|
|
160
|
+
See [Work with results](docs/guides/results.md) for analysis examples and
|
|
161
|
+
nested data, or [Advanced result details](docs/advanced/result-details.md) for
|
|
162
|
+
the exact dtype and Arrow behavior.
|
|
163
|
+
|
|
164
|
+
## Avoid repeated API calls
|
|
165
|
+
|
|
166
|
+
You do not need a cache for quick experiments. Add one when a notebook or
|
|
167
|
+
script repeatedly requests the same data while the analysis changes.
|
|
168
|
+
|
|
169
|
+
SQLite is the easiest option:
|
|
170
|
+
|
|
171
|
+
```python
|
|
172
|
+
from cfb_data import CFBDClient, SQLiteCacheConfig
|
|
173
|
+
from cfb_data.enums import teams
|
|
174
|
+
|
|
175
|
+
async with CFBDClient(cache=SQLiteCacheConfig()) as client:
|
|
176
|
+
games = await client.games.list(year=2025)
|
|
177
|
+
repeated = await client.games.list(year=2025) # reused locally
|
|
178
|
+
michigan = await client.identities.teams.resolve(teams.Michigan)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Redis is also a good local option if you already run it or want several
|
|
182
|
+
notebooks, scripts, or processes to share one cache:
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
from cfb_data import CFBDClient, RedisCacheConfig
|
|
186
|
+
|
|
187
|
+
cache = RedisCacheConfig(url="redis://127.0.0.1:6379/0")
|
|
188
|
+
|
|
189
|
+
async with CFBDClient(cache=cache) as client:
|
|
190
|
+
games = await client.games.list(year=2025)
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Add a bounded in-memory collector when you want to see whether calls reached
|
|
194
|
+
the API or were served from cache:
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
from cfb_data import CFBDClient, RetrievalStats, SQLiteCacheConfig
|
|
198
|
+
|
|
199
|
+
stats = RetrievalStats()
|
|
200
|
+
|
|
201
|
+
async with CFBDClient(cache=SQLiteCacheConfig(), observer=stats) as client:
|
|
202
|
+
await client.games.list(year=2025)
|
|
203
|
+
await client.games.list(year=2025)
|
|
204
|
+
|
|
205
|
+
snapshot = stats.snapshot()
|
|
206
|
+
print(snapshot.http_attempts) # actual client-side HTTP attempts
|
|
207
|
+
print(snapshot.fresh_cache_hits) # fresh initial cache hits
|
|
208
|
+
print(snapshot.fresh_hit_rate)
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
See [Cache responses and look up
|
|
212
|
+
identities](docs/guides/cache-and-identities.md) for use cases, the included
|
|
213
|
+
local Redis setup, cache modes, observability, identity examples, and
|
|
214
|
+
troubleshooting.
|
|
215
|
+
|
|
216
|
+
## Troubleshooting
|
|
217
|
+
|
|
218
|
+
| What you see | Start here |
|
|
219
|
+
| --- | --- |
|
|
220
|
+
| API key or access error | Check `CFBD_API_KEY` and the endpoint's Patreon tier. |
|
|
221
|
+
| Invalid filter or selector | Compare the call with the [endpoint reference](docs/cfbd_api/README.md). |
|
|
222
|
+
| Rate-limit error | Wait before retrying; consider SQLite or Redis for repeated calls. |
|
|
223
|
+
| Unexpected pandas dtype or nested value | See [Work with results](docs/guides/results.md). |
|
|
224
|
+
| Cache or identity lookup error | See [Cache troubleshooting](docs/guides/cache-and-identities.md#troubleshooting). |
|
|
225
|
+
| Another library exception | See [Troubleshooting requests](docs/guides/errors-and-retries.md). |
|
|
226
|
+
|
|
227
|
+
## Documentation
|
|
228
|
+
|
|
229
|
+
The [complete documentation](https://ryanpaulanderson.github.io/cfb-data/)
|
|
230
|
+
is organized in layers:
|
|
231
|
+
|
|
232
|
+
- **Start and use:** installation, examples, requests, results, caching, and
|
|
233
|
+
troubleshooting, including [common notebook
|
|
234
|
+
recipes](docs/guides/common-recipes.md).
|
|
235
|
+
- **Advanced details:** exact enum values, dtypes, TTLs, retries, and storage
|
|
236
|
+
behavior.
|
|
237
|
+
- **Project internals:** architecture decisions and contributor-facing design.
|
|
238
|
+
|
|
239
|
+
The [product constitution](docs/product-constitution.md) is the concise north
|
|
240
|
+
star used to evaluate product and engineering decisions.
|
|
241
|
+
|
|
242
|
+
The project is pre-alpha, and the documentation describes the current version.
|
|
243
|
+
|
|
244
|
+
## Development
|
|
245
|
+
|
|
246
|
+
```shell
|
|
247
|
+
git clone https://github.com/ryanpaulanderson/cfb-data.git
|
|
248
|
+
cd cfb-data
|
|
249
|
+
make install
|
|
250
|
+
make hooks
|
|
251
|
+
make format
|
|
252
|
+
make docs
|
|
253
|
+
make check
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Contributor standards, testing, release details, and architecture expectations
|
|
257
|
+
live in [`CONTRIBUTING.md`](CONTRIBUTING.md) and [`AGENTS.md`](AGENTS.md). They
|
|
258
|
+
are intentionally separate from the steps required to use the library.
|
|
259
|
+
|
|
260
|
+
## License
|
|
261
|
+
|
|
262
|
+
This project is licensed under the MIT License. See [`LICENSE`](LICENSE).
|
|
263
|
+
|
|
264
|
+
This project is not affiliated with CollegeFootballData.com.
|
|
@@ -34,12 +34,14 @@ from .draft.models.pydantic.requests import DraftPicksRequest
|
|
|
34
34
|
from .drives.models.pydantic.requests import DrivesRequest
|
|
35
35
|
from .enums import (
|
|
36
36
|
Classification,
|
|
37
|
+
ConferenceName,
|
|
37
38
|
MediaType,
|
|
38
39
|
PlayoffCompetition,
|
|
39
40
|
PlayoffRound,
|
|
40
41
|
RankingPoll,
|
|
41
42
|
RecruitClassification,
|
|
42
43
|
SeasonType,
|
|
44
|
+
TeamName,
|
|
43
45
|
TransferEligibility,
|
|
44
46
|
UserUsageApi,
|
|
45
47
|
)
|
|
@@ -92,6 +94,13 @@ from .metrics.models.pydantic.requests import (
|
|
|
92
94
|
TeamSeasonPPARequest,
|
|
93
95
|
WinProbabilityRequest,
|
|
94
96
|
)
|
|
97
|
+
from .observability import (
|
|
98
|
+
EndpointRetrievalStats,
|
|
99
|
+
RetrievalEvent,
|
|
100
|
+
RetrievalObserver,
|
|
101
|
+
RetrievalStats,
|
|
102
|
+
RetrievalStatsSnapshot,
|
|
103
|
+
)
|
|
95
104
|
from .players.models.pydantic.identity import AthleteIdentity
|
|
96
105
|
from .players.models.pydantic.requests import (
|
|
97
106
|
PlayerSearchRequest,
|
|
@@ -200,6 +209,7 @@ __all__ = [
|
|
|
200
209
|
"ConferenceChangesRequest",
|
|
201
210
|
"ConferenceClassification",
|
|
202
211
|
"ConferenceIdentity",
|
|
212
|
+
"ConferenceName",
|
|
203
213
|
"ConferencesRequest",
|
|
204
214
|
"ConferenceSPRatingsRequest",
|
|
205
215
|
"CoreRatingsRequest",
|
|
@@ -207,6 +217,7 @@ __all__ = [
|
|
|
207
217
|
"DraftPicksRequest",
|
|
208
218
|
"DrivesRequest",
|
|
209
219
|
"EloRatingsRequest",
|
|
220
|
+
"EndpointRetrievalStats",
|
|
210
221
|
"ExpandedSRSRatingsRequest",
|
|
211
222
|
"FPIRatingsRequest",
|
|
212
223
|
"FreshnessMode",
|
|
@@ -246,6 +257,10 @@ __all__ = [
|
|
|
246
257
|
"RecruitingPlayersRequest",
|
|
247
258
|
"RecruitingTeamsRequest",
|
|
248
259
|
"RedisCacheConfig",
|
|
260
|
+
"RetrievalEvent",
|
|
261
|
+
"RetrievalObserver",
|
|
262
|
+
"RetrievalStats",
|
|
263
|
+
"RetrievalStatsSnapshot",
|
|
249
264
|
"RetryPolicy",
|
|
250
265
|
"RosterRequest",
|
|
251
266
|
"ReturningProductionRequest",
|
|
@@ -257,6 +272,7 @@ __all__ = [
|
|
|
257
272
|
"SQLiteCacheConfig",
|
|
258
273
|
"TeamGamePPARequest",
|
|
259
274
|
"TeamIdentity",
|
|
275
|
+
"TeamName",
|
|
260
276
|
"TeamGameStatsRequest",
|
|
261
277
|
"TeamSeasonStatsRequest",
|
|
262
278
|
"TeamSeasonPPARequest",
|