cfb-data 0.7.1__tar.gz → 0.9.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.7.1 → cfb_data-0.9.0}/PKG-INFO +60 -11
- {cfb_data-0.7.1 → cfb_data-0.9.0}/README.md +44 -8
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/_executor.py +4 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/_observability.py +27 -2
- cfb_data-0.9.0/cfb_data/cfb_data/_operation.py +167 -0
- {cfb_data-0.7.1/cfb_data/cfb_data/cache → cfb_data-0.9.0/cfb_data/cfb_data}/_sqlite_sql.py +3 -14
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/_tabular.py +192 -1
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/_transport.py +41 -1
- cfb_data-0.9.0/cfb_data/cfb_data/adjusted_metrics/_operations.py +58 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/adjusted_metrics/resource.py +19 -63
- cfb_data-0.9.0/cfb_data/cfb_data/adjusted_metrics/sources.py +114 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/__init__.py +182 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_artifact_contract.py +171 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_artifacts.py +767 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_checkpoints.py +123 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_compiler.py +444 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_compute.py +89 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_contracts.py +73 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_dask.py +505 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_dask_transport.py +324 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_declarations.py +44 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_execution.py +140 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_graph.py +133 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_graph_context.py +34 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_native_execution.py +223 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_native_tables.py +443 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_observability.py +38 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_parameters.py +148 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_persistence.py +1595 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_recipes.py +867 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_registration.py +115 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_runtime.py +756 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_sources.py +712 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_sqlite_sql.py +18 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/_transforms.py +1173 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/config.py +38 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/discovery.py +241 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/errors.py +168 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/maintenance.py +630 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/observability.py +143 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/operations.py +339 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/planning.py +507 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/results.py +490 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/artifacts/insert_gc_transition.sql +2 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/artifacts/insert_object.sql +4 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/artifacts/insert_pin_transition.sql +3 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/artifacts/require_registered.sql +1 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/artifacts/select_active_pins.sql +11 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/artifacts/select_eligible_for_prune.sql +37 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/artifacts/select_gc_state.sql +4 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/artifacts/select_manifest.sql +3 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/artifacts/select_pin_state.sql +4 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/artifacts/select_referenced_runs.sql +4 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/artifacts/select_registered_digests.sql +3 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/attempts/count_by_run.sql +3 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/attempts/insert_reservation.sql +3 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/checkpoints/select_global.sql +11 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/checkpoints/select_parent.sql +21 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/config/set_busy_timeout.sql +1 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/config/set_journal_delete.sql +1 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/config/set_query_only.sql +1 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/config/set_synchronous_full.sql +1 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/leases/acquire_node_lease.sql +10 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/leases/release_node_lease.sql +3 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/leases/renew_node_lease.sql +5 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/leases/select_node_lease.sql +3 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/migrations/001_initial.sql +96 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/migrations/002_credential_scope.sql +4 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/migrations/003_retention.sql +53 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/migrations/004_attempt_reservations.sql +26 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/migrations/005_checkpoint_eligibility.sql +8 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/migrations/006_node_leases.sql +16 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/migrations/get_user_version.sql +1 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/nodes/insert_binding.sql +4 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/nodes/insert_transition.sql +3 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/nodes/select_bindings.sql +3 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/nodes/select_current_state.sql +4 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/runs/insert_retention_transition.sql +2 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/runs/insert_run.sql +5 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/runs/insert_transition.sql +3 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/runs/require_run.sql +1 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/runs/select_attempt_limit.sql +1 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/runs/select_current_state.sql +4 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/runs/select_newest_compatible_run.sql +15 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/runs/select_retention_state.sql +4 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/runs/select_run.sql +9 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/runs/select_runs.sql +10 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/runs/select_unavailable_retained_content.sql +14 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/transaction/commit.sql +1 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/transaction/rollback.sql +1 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/tables.py +691 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/tabular.py +261 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/types.py +85 -0
- cfb_data-0.9.0/cfb_data/cfb_data/analytics/yaml.py +704 -0
- cfb_data-0.9.0/cfb_data/cfb_data/betting/_operations.py +19 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/betting/resource.py +4 -18
- cfb_data-0.9.0/cfb_data/cfb_data/betting/sources.py +66 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/_backend.py +5 -1
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/_coordinator.py +23 -1
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/_models.py +18 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/_null.py +5 -1
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/_redis.py +27 -1
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/_sqlite.py +37 -1
- cfb_data-0.9.0/cfb_data/cfb_data/cache/_sqlite_sql.py +15 -0
- cfb_data-0.9.0/cfb_data/cfb_data/cache/sql/begin_immediate.sql +1 -0
- cfb_data-0.9.0/cfb_data/cfb_data/cache/sql/enable_foreign_keys.sql +1 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/client.py +53 -5
- cfb_data-0.9.0/cfb_data/cfb_data/coaches/_operations.py +32 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/coaches/resource.py +7 -14
- cfb_data-0.9.0/cfb_data/cfb_data/coaches/sources.py +65 -0
- cfb_data-0.9.0/cfb_data/cfb_data/drives/_operations.py +19 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/drives/resource.py +4 -19
- cfb_data-0.9.0/cfb_data/cfb_data/drives/sources.py +70 -0
- cfb_data-0.9.0/cfb_data/cfb_data/games/_operations.py +95 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/games/resource.py +31 -66
- cfb_data-0.9.0/cfb_data/cfb_data/games/sources.py +285 -0
- cfb_data-0.9.0/cfb_data/cfb_data/metrics/_operations.py +71 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/metrics/resource.py +22 -35
- cfb_data-0.9.0/cfb_data/cfb_data/metrics/sources.py +181 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/observability.py +4 -0
- cfb_data-0.9.0/cfb_data/cfb_data/players/_operations.py +32 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/players/resource.py +7 -14
- cfb_data-0.9.0/cfb_data/cfb_data/players/sources.py +61 -0
- cfb_data-0.9.0/cfb_data/cfb_data/plays/_operations.py +44 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/plays/models/pydantic/requests.py +6 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/plays/resource.py +8 -46
- cfb_data-0.9.0/cfb_data/cfb_data/plays/sources.py +73 -0
- cfb_data-0.9.0/cfb_data/cfb_data/rankings/_operations.py +19 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/rankings/resource.py +4 -18
- cfb_data-0.9.0/cfb_data/cfb_data/rankings/sources.py +58 -0
- cfb_data-0.9.0/cfb_data/cfb_data/ratings/_operations.py +95 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/ratings/resource.py +31 -85
- cfb_data-0.9.0/cfb_data/cfb_data/ratings/sources.py +202 -0
- cfb_data-0.9.0/cfb_data/cfb_data/recruiting/_operations.py +35 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/recruiting/resource.py +7 -14
- cfb_data-0.9.0/cfb_data/cfb_data/recruiting/sources.py +66 -0
- cfb_data-0.9.0/cfb_data/cfb_data/stats/_operations.py +95 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/stats/resource.py +32 -86
- cfb_data-0.9.0/cfb_data/cfb_data/stats/sources.py +289 -0
- cfb_data-0.9.0/cfb_data/cfb_data/teams/_operations.py +59 -0
- cfb_data-0.9.0/cfb_data/cfb_data/teams/identity.py +143 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/teams/resource.py +13 -46
- cfb_data-0.9.0/cfb_data/cfb_data/teams/sources.py +94 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data.egg-info/PKG-INFO +60 -11
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data.egg-info/SOURCES.txt +134 -1
- cfb_data-0.9.0/cfb_data/cfb_data.egg-info/entry_points.txt +2 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data.egg-info/requires.txt +15 -0
- cfb_data-0.9.0/cfb_data/cfb_data.egg-info/top_level.txt +2 -0
- cfb_data-0.9.0/cfb_data/cfb_data_recipes/__init__.py +6 -0
- cfb_data-0.9.0/cfb_data/cfb_data_recipes/betting_lines.py +172 -0
- cfb_data-0.9.0/cfb_data/cfb_data_recipes/coach_seasons.py +244 -0
- cfb_data-0.9.0/cfb_data/cfb_data_recipes/drives.py +214 -0
- cfb_data-0.9.0/cfb_data/cfb_data_recipes/game_summaries.py +579 -0
- cfb_data-0.9.0/cfb_data/cfb_data_recipes/play_player_stats.py +316 -0
- cfb_data-0.9.0/cfb_data/cfb_data_recipes/player_game_stats.py +226 -0
- cfb_data-0.9.0/cfb_data/cfb_data_recipes/player_seasons.py +456 -0
- cfb_data-0.9.0/cfb_data/cfb_data_recipes/plays.py +277 -0
- cfb_data-0.9.0/cfb_data/cfb_data_recipes/poll_rankings.py +133 -0
- cfb_data-0.9.0/cfb_data/cfb_data_recipes/program_history.py +256 -0
- cfb_data-0.9.0/cfb_data/cfb_data_recipes/py.typed +0 -0
- cfb_data-0.9.0/cfb_data/cfb_data_recipes/recruiting_classes.py +206 -0
- cfb_data-0.9.0/cfb_data/cfb_data_recipes/rosters.py +152 -0
- cfb_data-0.9.0/cfb_data/cfb_data_recipes/single_game_analysis.py +92 -0
- cfb_data-0.9.0/cfb_data/cfb_data_recipes/team_games.py +653 -0
- cfb_data-0.9.0/cfb_data/cfb_data_recipes/team_season_analysis.py +178 -0
- cfb_data-0.9.0/cfb_data/cfb_data_recipes/team_seasons.py +477 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/pyproject.toml +27 -6
- cfb_data-0.7.1/cfb_data/cfb_data.egg-info/top_level.txt +0 -1
- {cfb_data-0.7.1 → cfb_data-0.9.0}/LICENSE +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/_catalog/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/_catalog/merge.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/_catalog/models.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/_catalog/projection.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/_catalog/sources.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/_dataframes.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/_parquet.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/_reference_enums.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/_request_rules.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/_requests.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/adjusted_metrics/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/adjusted_metrics/models/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/adjusted_metrics/models/pydantic/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/adjusted_metrics/models/pydantic/requests.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/adjusted_metrics/models/pydantic/responses.py +0 -0
- {cfb_data-0.7.1/cfb_data/cfb_data/cache/sql → cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/config}/enable_foreign_keys.sql +0 -0
- {cfb_data-0.7.1/cfb_data/cfb_data/cache/sql → cfb_data-0.9.0/cfb_data/cfb_data/analytics/sql/transaction}/begin_immediate.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/base/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/base/types.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/betting/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/betting/models/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/betting/models/pydantic/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/betting/models/pydantic/requests.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/betting/models/pydantic/responses.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/_catalog.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/_catalog_codecs.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/_identity_codecs.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/_key.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/config.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/policy.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/acquire_refresh_lease.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/catalog_counts.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/cleanup_responses.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/delete_coverage_failure.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/delete_response.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/delete_team_aliases.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/enable_wal.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/find_athletes.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/find_conference_by_id.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/find_conference_by_name.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/find_fresh_coverage.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/find_game_by_id.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/find_games.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/find_team_by_id.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/find_team_by_name.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/find_venue_by_id.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/find_venue_by_name.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/get_response.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/get_response_size.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/get_schema_version.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/initialize_schema_version.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/release_refresh_lease.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/renew_refresh_lease.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/schema.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/select_catalog_observations.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/select_projection_contract.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/set_busy_timeout.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/set_synchronous_normal.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/upsert_athlete.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/upsert_athlete_team_season.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/upsert_catalog_observation.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/upsert_coach.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/upsert_coach_team_season.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/upsert_conference.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/upsert_conference_affiliation.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/upsert_coverage.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/upsert_coverage_failure.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/upsert_drive.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/upsert_game.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/upsert_play.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/upsert_playoff_matchup.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/upsert_recruit.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/upsert_response.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/upsert_team.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/upsert_team_alias.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/upsert_team_season.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/upsert_venue.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/cache/sql/upsert_vocabulary.sql +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/coaches/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/coaches/models/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/coaches/models/pydantic/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/coaches/models/pydantic/requests.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/coaches/models/pydantic/responses.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/conferences/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/conferences/models/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/conferences/models/pydantic/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/conferences/models/pydantic/identity.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/conferences/models/pydantic/requests.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/conferences/models/pydantic/responses.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/conferences/resource.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/draft/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/draft/models/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/draft/models/pydantic/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/draft/models/pydantic/requests.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/draft/models/pydantic/responses.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/draft/resource.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/drives/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/drives/models/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/drives/models/pydantic/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/drives/models/pydantic/requests.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/drives/models/pydantic/responses.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/enums.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/errors.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/games/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/games/models/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/games/models/pydantic/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/games/models/pydantic/identity.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/games/models/pydantic/requests.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/games/models/pydantic/responses.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/identities/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/identities/_normalization.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/identities/contracts.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/identities/resource.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/info/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/info/models/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/info/models/pydantic/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/info/models/pydantic/requests.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/info/models/pydantic/responses.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/info/resource.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/metrics/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/metrics/models/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/metrics/models/pydantic/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/metrics/models/pydantic/requests.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/metrics/models/pydantic/responses.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/players/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/players/models/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/players/models/pydantic/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/players/models/pydantic/identity.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/players/models/pydantic/requests.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/players/models/pydantic/responses.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/playoffs/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/playoffs/models/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/playoffs/models/pydantic/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/playoffs/models/pydantic/requests.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/playoffs/models/pydantic/responses.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/playoffs/resource.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/plays/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/plays/models/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/plays/models/pydantic/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/plays/models/pydantic/responses.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/py.typed +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/rankings/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/rankings/models/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/rankings/models/pydantic/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/rankings/models/pydantic/requests.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/rankings/models/pydantic/responses.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/ratings/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/ratings/models/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/ratings/models/pydantic/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/ratings/models/pydantic/requests.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/ratings/models/pydantic/responses.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/recruiting/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/recruiting/models/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/recruiting/models/pydantic/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/recruiting/models/pydantic/requests.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/recruiting/models/pydantic/responses.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/retry.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/stats/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/stats/models/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/stats/models/pydantic/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/stats/models/pydantic/requests.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/stats/models/pydantic/responses.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/teams/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/teams/models/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/teams/models/pydantic/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/teams/models/pydantic/identity.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/teams/models/pydantic/requests.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/teams/models/pydantic/responses.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/venues/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/venues/models/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/venues/models/pydantic/__init__.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/venues/models/pydantic/identity.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/venues/models/pydantic/responses.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data/venues/resource.py +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/cfb_data/cfb_data.egg-info/dependency_links.txt +0 -0
- {cfb_data-0.7.1 → cfb_data-0.9.0}/setup.cfg +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cfb-data
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: Async validated CollegeFootballData access for pandas and Polars
|
|
3
|
+
Version: 0.9.0
|
|
4
|
+
Summary: Async validated CollegeFootballData access for pandas and Polars, with native Dask analytics
|
|
5
5
|
Author: Ryan Anderson
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: Documentation, https://ryanpaulanderson.github.io/cfb-data/
|
|
8
8
|
Project-URL: Repository, https://github.com/ryanpaulanderson/cfb-data
|
|
9
9
|
Project-URL: Issues, https://github.com/ryanpaulanderson/cfb-data/issues
|
|
10
|
-
Classifier: Development Status ::
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
11
|
Classifier: Intended Audience :: Developers
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -17,14 +17,22 @@ Description-Content-Type: text/markdown
|
|
|
17
17
|
License-File: LICENSE
|
|
18
18
|
Requires-Dist: aiohttp<4,>=3.13
|
|
19
19
|
Requires-Dist: aiosqlite<1,>=0.22
|
|
20
|
+
Requires-Dist: dask[dataframe]<2027,>=2026.7.1
|
|
20
21
|
Requires-Dist: jinja2<4,>=3.1
|
|
22
|
+
Requires-Dist: narwhals<3,>=2.24
|
|
23
|
+
Requires-Dist: numpy<3,>=2
|
|
21
24
|
Requires-Dist: pandas<4,>=3.0
|
|
25
|
+
Requires-Dist: platformdirs<5,>=4.11
|
|
22
26
|
Requires-Dist: pydantic<3,>=2.12
|
|
23
27
|
Requires-Dist: pyarrow<26,>=25
|
|
24
28
|
Provides-Extra: polars
|
|
25
29
|
Requires-Dist: polars<2,>=1.43.2; extra == "polars"
|
|
26
30
|
Provides-Extra: redis
|
|
27
31
|
Requires-Dist: redis<9,>=7.1; extra == "redis"
|
|
32
|
+
Provides-Extra: dask
|
|
33
|
+
Requires-Dist: distributed<2027,>=2026.7.1; extra == "dask"
|
|
34
|
+
Provides-Extra: yaml
|
|
35
|
+
Requires-Dist: PyYAML<7,>=6.0.3; extra == "yaml"
|
|
28
36
|
Provides-Extra: dev
|
|
29
37
|
Requires-Dist: build<2,>=1.5; extra == "dev"
|
|
30
38
|
Requires-Dist: furo>=2025.12.19; extra == "dev"
|
|
@@ -34,14 +42,19 @@ Requires-Dist: pre-commit<5,>=4.5; extra == "dev"
|
|
|
34
42
|
Requires-Dist: pyarrow-stubs<21,>=20.0.0.20260625; extra == "dev"
|
|
35
43
|
Requires-Dist: pytest<10,>=9; extra == "dev"
|
|
36
44
|
Requires-Dist: pytest-asyncio<2,>=1.3; extra == "dev"
|
|
45
|
+
Requires-Dist: pytest-split<1,>=0.11; extra == "dev"
|
|
46
|
+
Requires-Dist: pytest-xdist<4,>=3.8; extra == "dev"
|
|
37
47
|
Requires-Dist: ruff<0.17,>=0.15.22; extra == "dev"
|
|
48
|
+
Requires-Dist: setuptools<85,>=80; extra == "dev"
|
|
38
49
|
Requires-Dist: sphinx<10,>=9.1; extra == "dev"
|
|
39
50
|
Requires-Dist: twine<8,>=7; extra == "dev"
|
|
51
|
+
Requires-Dist: types-PyYAML<6.1,>=6.0.12.20260815; extra == "dev"
|
|
52
|
+
Requires-Dist: wheel<1,>=0.46; extra == "dev"
|
|
40
53
|
Dynamic: license-file
|
|
41
54
|
|
|
42
55
|
# College Football Data Python Toolkit
|
|
43
56
|
|
|
44
|
-
`cfb-data` 0.
|
|
57
|
+
`cfb-data` 0.9.0 is a beta Python toolkit for exploring the public
|
|
45
58
|
[CollegeFootballData API](https://collegefootballdata.com/). Most calls return
|
|
46
59
|
eager pandas DataFrames that are ready for analysis. Polars is available as an
|
|
47
60
|
option, and a few naturally nested results return Pydantic models.
|
|
@@ -55,7 +68,7 @@ HTTP client or cleaning up inconsistent response shapes.
|
|
|
55
68
|
- Pull games, plays, drives, ratings, rosters, recruiting, betting, draft, and
|
|
56
69
|
other CFBD data into Python.
|
|
57
70
|
- Explore one team or season in a notebook.
|
|
58
|
-
-
|
|
71
|
+
- Run or author durable pandas or Polars recipes across several endpoints.
|
|
59
72
|
- Cache responses locally so rerunning an analysis does not repeat every API
|
|
60
73
|
call.
|
|
61
74
|
- Resolve team, venue, game, and athlete names and IDs when joining data.
|
|
@@ -66,7 +79,7 @@ Arrow, HTTP retry logic, or the cache implementation.
|
|
|
66
79
|
|
|
67
80
|
## Install
|
|
68
81
|
|
|
69
|
-
Python 3.12 and 3.13 are supported. pandas and
|
|
82
|
+
Python 3.12 and 3.13 are supported. pandas, PyArrow, and native Dask DataFrame processing are included:
|
|
70
83
|
|
|
71
84
|
```shell
|
|
72
85
|
python -m pip install cfb-data
|
|
@@ -86,6 +99,12 @@ python -m pip install "cfb-data[redis]"
|
|
|
86
99
|
|
|
87
100
|
SQLite caching is included in the normal installation.
|
|
88
101
|
|
|
102
|
+
For parallel Dask workers or safe declarative YAML recipes:
|
|
103
|
+
|
|
104
|
+
```shell
|
|
105
|
+
python -m pip install "cfb-data[dask,yaml]"
|
|
106
|
+
```
|
|
107
|
+
|
|
89
108
|
## Make a first request
|
|
90
109
|
|
|
91
110
|
Get an API key from [CollegeFootballData](https://collegefootballdata.com/) and
|
|
@@ -124,6 +143,32 @@ The `async with` block lets related calls share one HTTP session and closes it
|
|
|
124
143
|
when the block ends. Async is limited to gathering and validating data; the
|
|
125
144
|
pandas calculation starts synchronously after the completed frame is returned.
|
|
126
145
|
|
|
146
|
+
## Run a modular analytics recipe
|
|
147
|
+
|
|
148
|
+
First-party datasets and workflows are ordinary independently importable
|
|
149
|
+
recipe modules. They use the same authoring and execution surface available to
|
|
150
|
+
your own package:
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
from cfb_data_recipes.team_seasons import team_seasons
|
|
154
|
+
|
|
155
|
+
async with CFBDClient() as client:
|
|
156
|
+
season = await team_seasons(
|
|
157
|
+
client,
|
|
158
|
+
season=2024,
|
|
159
|
+
team="Penn State",
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
print(season[["team", "season", "expected_wins", "total"]])
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Use ``.plan()`` for a pure no-I/O execution plan and ``.run()`` for durable
|
|
166
|
+
artifacts, lineage, source coverage, quality results, and recovery evidence.
|
|
167
|
+
Workflows return explicit named outputs rather than choosing a hidden primary
|
|
168
|
+
table. See [Build durable analyses with modular
|
|
169
|
+
recipes](docs/guides/modular-analytics.md) for the thirteen included datasets,
|
|
170
|
+
three workflows, Dask execution, safe YAML, recovery, and user authoring.
|
|
171
|
+
|
|
127
172
|
## Find the data you need
|
|
128
173
|
|
|
129
174
|
Methods are grouped by subject:
|
|
@@ -244,8 +289,8 @@ async with CFBDClient(cache=SQLiteCacheConfig(), observer=stats) as client:
|
|
|
244
289
|
await client.games.list(year=2025)
|
|
245
290
|
|
|
246
291
|
snapshot = stats.snapshot()
|
|
247
|
-
print(snapshot.http_attempts)
|
|
248
|
-
print(snapshot.fresh_cache_hits)
|
|
292
|
+
print(snapshot.http_attempts) # actual client-side HTTP attempts
|
|
293
|
+
print(snapshot.fresh_cache_hits) # fresh initial cache hits
|
|
249
294
|
print(snapshot.fresh_hit_rate)
|
|
250
295
|
```
|
|
251
296
|
|
|
@@ -271,8 +316,9 @@ The [complete documentation](https://ryanpaulanderson.github.io/cfb-data/)
|
|
|
271
316
|
is organized in layers:
|
|
272
317
|
|
|
273
318
|
- **Start and use:** installation, examples, requests, results, caching, and
|
|
274
|
-
troubleshooting, including [
|
|
275
|
-
recipes](docs/guides/
|
|
319
|
+
troubleshooting, including [modular analytics
|
|
320
|
+
recipes](docs/guides/modular-analytics.md) and [common notebook
|
|
321
|
+
patterns](docs/guides/common-recipes.md).
|
|
276
322
|
- **Advanced details:** exact enum values, dtypes, TTLs, retries, and storage
|
|
277
323
|
behavior.
|
|
278
324
|
- **Project internals:** architecture decisions and contributor-facing design.
|
|
@@ -280,7 +326,10 @@ is organized in layers:
|
|
|
280
326
|
The [product constitution](docs/product-constitution.md) is the concise north
|
|
281
327
|
star used to evaluate product and engineering decisions.
|
|
282
328
|
|
|
283
|
-
The project is
|
|
329
|
+
The project is in beta: its core retrieval, validation, DataFrame, caching, and
|
|
330
|
+
identity workflows are usable and carefully tested. Public APIs and local cache
|
|
331
|
+
formats may still change before 1.0, and the documentation describes the
|
|
332
|
+
current version.
|
|
284
333
|
|
|
285
334
|
## Development
|
|
286
335
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# College Football Data Python Toolkit
|
|
2
2
|
|
|
3
|
-
`cfb-data` 0.
|
|
3
|
+
`cfb-data` 0.9.0 is a beta Python toolkit for exploring the public
|
|
4
4
|
[CollegeFootballData API](https://collegefootballdata.com/). Most calls return
|
|
5
5
|
eager pandas DataFrames that are ready for analysis. Polars is available as an
|
|
6
6
|
option, and a few naturally nested results return Pydantic models.
|
|
@@ -14,7 +14,7 @@ HTTP client or cleaning up inconsistent response shapes.
|
|
|
14
14
|
- Pull games, plays, drives, ratings, rosters, recruiting, betting, draft, and
|
|
15
15
|
other CFBD data into Python.
|
|
16
16
|
- Explore one team or season in a notebook.
|
|
17
|
-
-
|
|
17
|
+
- Run or author durable pandas or Polars recipes across several endpoints.
|
|
18
18
|
- Cache responses locally so rerunning an analysis does not repeat every API
|
|
19
19
|
call.
|
|
20
20
|
- Resolve team, venue, game, and athlete names and IDs when joining data.
|
|
@@ -25,7 +25,7 @@ Arrow, HTTP retry logic, or the cache implementation.
|
|
|
25
25
|
|
|
26
26
|
## Install
|
|
27
27
|
|
|
28
|
-
Python 3.12 and 3.13 are supported. pandas and
|
|
28
|
+
Python 3.12 and 3.13 are supported. pandas, PyArrow, and native Dask DataFrame processing are included:
|
|
29
29
|
|
|
30
30
|
```shell
|
|
31
31
|
python -m pip install cfb-data
|
|
@@ -45,6 +45,12 @@ python -m pip install "cfb-data[redis]"
|
|
|
45
45
|
|
|
46
46
|
SQLite caching is included in the normal installation.
|
|
47
47
|
|
|
48
|
+
For parallel Dask workers or safe declarative YAML recipes:
|
|
49
|
+
|
|
50
|
+
```shell
|
|
51
|
+
python -m pip install "cfb-data[dask,yaml]"
|
|
52
|
+
```
|
|
53
|
+
|
|
48
54
|
## Make a first request
|
|
49
55
|
|
|
50
56
|
Get an API key from [CollegeFootballData](https://collegefootballdata.com/) and
|
|
@@ -83,6 +89,32 @@ The `async with` block lets related calls share one HTTP session and closes it
|
|
|
83
89
|
when the block ends. Async is limited to gathering and validating data; the
|
|
84
90
|
pandas calculation starts synchronously after the completed frame is returned.
|
|
85
91
|
|
|
92
|
+
## Run a modular analytics recipe
|
|
93
|
+
|
|
94
|
+
First-party datasets and workflows are ordinary independently importable
|
|
95
|
+
recipe modules. They use the same authoring and execution surface available to
|
|
96
|
+
your own package:
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
from cfb_data_recipes.team_seasons import team_seasons
|
|
100
|
+
|
|
101
|
+
async with CFBDClient() as client:
|
|
102
|
+
season = await team_seasons(
|
|
103
|
+
client,
|
|
104
|
+
season=2024,
|
|
105
|
+
team="Penn State",
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
print(season[["team", "season", "expected_wins", "total"]])
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Use ``.plan()`` for a pure no-I/O execution plan and ``.run()`` for durable
|
|
112
|
+
artifacts, lineage, source coverage, quality results, and recovery evidence.
|
|
113
|
+
Workflows return explicit named outputs rather than choosing a hidden primary
|
|
114
|
+
table. See [Build durable analyses with modular
|
|
115
|
+
recipes](docs/guides/modular-analytics.md) for the thirteen included datasets,
|
|
116
|
+
three workflows, Dask execution, safe YAML, recovery, and user authoring.
|
|
117
|
+
|
|
86
118
|
## Find the data you need
|
|
87
119
|
|
|
88
120
|
Methods are grouped by subject:
|
|
@@ -203,8 +235,8 @@ async with CFBDClient(cache=SQLiteCacheConfig(), observer=stats) as client:
|
|
|
203
235
|
await client.games.list(year=2025)
|
|
204
236
|
|
|
205
237
|
snapshot = stats.snapshot()
|
|
206
|
-
print(snapshot.http_attempts)
|
|
207
|
-
print(snapshot.fresh_cache_hits)
|
|
238
|
+
print(snapshot.http_attempts) # actual client-side HTTP attempts
|
|
239
|
+
print(snapshot.fresh_cache_hits) # fresh initial cache hits
|
|
208
240
|
print(snapshot.fresh_hit_rate)
|
|
209
241
|
```
|
|
210
242
|
|
|
@@ -230,8 +262,9 @@ The [complete documentation](https://ryanpaulanderson.github.io/cfb-data/)
|
|
|
230
262
|
is organized in layers:
|
|
231
263
|
|
|
232
264
|
- **Start and use:** installation, examples, requests, results, caching, and
|
|
233
|
-
troubleshooting, including [
|
|
234
|
-
recipes](docs/guides/
|
|
265
|
+
troubleshooting, including [modular analytics
|
|
266
|
+
recipes](docs/guides/modular-analytics.md) and [common notebook
|
|
267
|
+
patterns](docs/guides/common-recipes.md).
|
|
235
268
|
- **Advanced details:** exact enum values, dtypes, TTLs, retries, and storage
|
|
236
269
|
behavior.
|
|
237
270
|
- **Project internals:** architecture decisions and contributor-facing design.
|
|
@@ -239,7 +272,10 @@ is organized in layers:
|
|
|
239
272
|
The [product constitution](docs/product-constitution.md) is the concise north
|
|
240
273
|
star used to evaluate product and engineering decisions.
|
|
241
274
|
|
|
242
|
-
The project is
|
|
275
|
+
The project is in beta: its core retrieval, validation, DataFrame, caching, and
|
|
276
|
+
identity workflows are usable and carefully tested. Public APIs and local cache
|
|
277
|
+
formats may still change before 1.0, and the documentation describes the
|
|
278
|
+
current version.
|
|
243
279
|
|
|
244
280
|
## Development
|
|
245
281
|
|
|
@@ -149,6 +149,8 @@ class _EndpointExecutor:
|
|
|
149
149
|
endpoint=endpoint,
|
|
150
150
|
parameter_names=tuple(sorted(parameters)),
|
|
151
151
|
cache_mode=self._cache_coordinator.current_mode,
|
|
152
|
+
analytics_run_id=context.analytics_run_id,
|
|
153
|
+
analytics_node_id=context.analytics_node_id,
|
|
152
154
|
)
|
|
153
155
|
)
|
|
154
156
|
try:
|
|
@@ -190,6 +192,8 @@ class _EndpointExecutor:
|
|
|
190
192
|
failure_category=(
|
|
191
193
|
_failure_category(error) if error is not None else None
|
|
192
194
|
),
|
|
195
|
+
analytics_run_id=context.analytics_run_id,
|
|
196
|
+
analytics_node_id=context.analytics_node_id,
|
|
193
197
|
)
|
|
194
198
|
)
|
|
195
199
|
|
|
@@ -6,7 +6,9 @@ import asyncio
|
|
|
6
6
|
import logging
|
|
7
7
|
import time
|
|
8
8
|
import uuid
|
|
9
|
-
from collections.abc import Callable
|
|
9
|
+
from collections.abc import Callable, Iterator
|
|
10
|
+
from contextlib import contextmanager
|
|
11
|
+
from contextvars import ContextVar
|
|
10
12
|
from dataclasses import dataclass
|
|
11
13
|
|
|
12
14
|
from cfb_data.observability import (
|
|
@@ -16,6 +18,9 @@ from cfb_data.observability import (
|
|
|
16
18
|
)
|
|
17
19
|
|
|
18
20
|
_LOGGER = logging.getLogger(__name__)
|
|
21
|
+
_ANALYTICS_CORRELATION: ContextVar[tuple[str, str] | None] = ContextVar(
|
|
22
|
+
"cfb_data_analytics_retrieval_correlation", default=None
|
|
23
|
+
)
|
|
19
24
|
|
|
20
25
|
|
|
21
26
|
@dataclass(slots=True)
|
|
@@ -28,6 +33,8 @@ class _OperationContext:
|
|
|
28
33
|
started_at: float
|
|
29
34
|
source: RetrievalSource = RetrievalSource.unknown
|
|
30
35
|
refresh_id: str | None = None
|
|
36
|
+
analytics_run_id: str | None = None
|
|
37
|
+
analytics_node_id: str | None = None
|
|
31
38
|
|
|
32
39
|
|
|
33
40
|
class _EventDispatcher:
|
|
@@ -62,11 +69,14 @@ class _EventDispatcher:
|
|
|
62
69
|
"""Return a new safe operation context when observation is enabled."""
|
|
63
70
|
if self._observer is None:
|
|
64
71
|
return None
|
|
72
|
+
correlation = _ANALYTICS_CORRELATION.get()
|
|
65
73
|
return _OperationContext(
|
|
66
74
|
client_id=self._client_id,
|
|
67
75
|
operation_id=uuid.uuid4().hex,
|
|
68
76
|
endpoint=endpoint,
|
|
69
77
|
started_at=self._monotonic(),
|
|
78
|
+
analytics_run_id=(correlation[0] if correlation is not None else None),
|
|
79
|
+
analytics_node_id=(correlation[1] if correlation is not None else None),
|
|
70
80
|
)
|
|
71
81
|
|
|
72
82
|
def new_refresh_id(self) -> str:
|
|
@@ -108,4 +118,19 @@ def _failure_category(error: BaseException) -> str:
|
|
|
108
118
|
return type(error).__name__[:64]
|
|
109
119
|
|
|
110
120
|
|
|
111
|
-
|
|
121
|
+
@contextmanager
|
|
122
|
+
def _analytics_retrieval_context(run_id: str, node_id: str) -> Iterator[None]:
|
|
123
|
+
"""Correlate task-local endpoint retrieval events with one analytics node."""
|
|
124
|
+
token = _ANALYTICS_CORRELATION.set((run_id, node_id))
|
|
125
|
+
try:
|
|
126
|
+
yield
|
|
127
|
+
finally:
|
|
128
|
+
_ANALYTICS_CORRELATION.reset(token)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
__all__ = [
|
|
132
|
+
"_EventDispatcher",
|
|
133
|
+
"_OperationContext",
|
|
134
|
+
"_analytics_retrieval_context",
|
|
135
|
+
"_failure_category",
|
|
136
|
+
]
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"""Define generic endpoint-operation ownership shared by resources and recipes."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from types import GenericAlias
|
|
8
|
+
from typing import Literal
|
|
9
|
+
|
|
10
|
+
from pydantic import BaseModel, TypeAdapter
|
|
11
|
+
|
|
12
|
+
from cfb_data._dataframes import _DataFrameAdapter
|
|
13
|
+
from cfb_data._executor import _EndpointExecutor, _response_contract, _serialize_request
|
|
14
|
+
from cfb_data._requests import _resolve_request
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class _EndpointOperation[RequestT: BaseModel, RowT: BaseModel](ABC):
|
|
18
|
+
"""Own the common contract for one validated endpoint operation."""
|
|
19
|
+
|
|
20
|
+
id: str
|
|
21
|
+
revision: int
|
|
22
|
+
endpoint: str
|
|
23
|
+
request_type: type[RequestT]
|
|
24
|
+
row_model: type[RowT]
|
|
25
|
+
access_tier: Literal["free", "tier_1", "tier_2"]
|
|
26
|
+
documented_limit: int | None
|
|
27
|
+
cost: int
|
|
28
|
+
|
|
29
|
+
def resolve(
|
|
30
|
+
self,
|
|
31
|
+
request: RequestT | None,
|
|
32
|
+
filters: dict[str, object],
|
|
33
|
+
) -> RequestT:
|
|
34
|
+
"""Return the one authoritative validated request model."""
|
|
35
|
+
return _resolve_request(
|
|
36
|
+
endpoint=self.endpoint,
|
|
37
|
+
request_type=self.request_type,
|
|
38
|
+
request=request,
|
|
39
|
+
filters=filters,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
@abstractmethod
|
|
43
|
+
async def fetch(
|
|
44
|
+
self,
|
|
45
|
+
executor: _EndpointExecutor,
|
|
46
|
+
request: RequestT,
|
|
47
|
+
) -> list[RowT]:
|
|
48
|
+
"""Return one normalized row list through the shared executor."""
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
@abstractmethod
|
|
52
|
+
def rows_adapter(self) -> TypeAdapter[list[RowT]]:
|
|
53
|
+
"""Return the adapter for the normalized analytical row list."""
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
@abstractmethod
|
|
57
|
+
def response_contract(self) -> str:
|
|
58
|
+
"""Return the actual HTTP response schema fingerprint."""
|
|
59
|
+
|
|
60
|
+
def serialized_parameters(
|
|
61
|
+
self, request: RequestT
|
|
62
|
+
) -> dict[str, str | int | float | bool]:
|
|
63
|
+
"""Return the exact typed upstream request parameters."""
|
|
64
|
+
return _serialize_request(self.endpoint, request)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@dataclass(frozen=True, slots=True)
|
|
68
|
+
class _ManyEndpointOperation[RequestT: BaseModel, RowT: BaseModel](
|
|
69
|
+
_EndpointOperation[RequestT, RowT]
|
|
70
|
+
):
|
|
71
|
+
"""Own one endpoint whose HTTP response is a model list."""
|
|
72
|
+
|
|
73
|
+
id: str
|
|
74
|
+
revision: int
|
|
75
|
+
endpoint: str
|
|
76
|
+
request_type: type[RequestT]
|
|
77
|
+
response_adapter: TypeAdapter[list[RowT]]
|
|
78
|
+
row_model: type[RowT]
|
|
79
|
+
access_tier: Literal["free", "tier_1", "tier_2"]
|
|
80
|
+
documented_limit: int | None = None
|
|
81
|
+
cost: int = 1
|
|
82
|
+
|
|
83
|
+
async def fetch(
|
|
84
|
+
self,
|
|
85
|
+
executor: _EndpointExecutor,
|
|
86
|
+
request: RequestT,
|
|
87
|
+
) -> list[RowT]:
|
|
88
|
+
"""Return validated rows through the shared endpoint executor."""
|
|
89
|
+
return await executor.fetch_many(
|
|
90
|
+
endpoint=self.endpoint,
|
|
91
|
+
request=request,
|
|
92
|
+
response_adapter=self.response_adapter,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
def rows_adapter(self) -> TypeAdapter[list[RowT]]:
|
|
97
|
+
"""Return the HTTP list adapter as the analytical row adapter."""
|
|
98
|
+
return self.response_adapter
|
|
99
|
+
|
|
100
|
+
async def fetch_frame[FrameT](
|
|
101
|
+
self,
|
|
102
|
+
executor: _EndpointExecutor,
|
|
103
|
+
dataframe_adapter: _DataFrameAdapter[FrameT],
|
|
104
|
+
request: RequestT | None,
|
|
105
|
+
filters: dict[str, object],
|
|
106
|
+
) -> FrameT:
|
|
107
|
+
"""Validate, retrieve, and present rows for a public resource method."""
|
|
108
|
+
validated = self.resolve(request, filters)
|
|
109
|
+
rows = await self.fetch(executor, validated)
|
|
110
|
+
return dataframe_adapter.from_models(
|
|
111
|
+
endpoint=self.endpoint,
|
|
112
|
+
row_model=self.row_model,
|
|
113
|
+
models=rows,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
@property
|
|
117
|
+
def response_contract(self) -> str:
|
|
118
|
+
"""Return the stable response schema fingerprint used by the cache."""
|
|
119
|
+
return _response_contract(self.response_adapter)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@dataclass(frozen=True, slots=True)
|
|
123
|
+
class _OneEndpointOperation[RequestT: BaseModel, RowT: BaseModel](
|
|
124
|
+
_EndpointOperation[RequestT, RowT]
|
|
125
|
+
):
|
|
126
|
+
"""Own one endpoint whose HTTP response is one validated model."""
|
|
127
|
+
|
|
128
|
+
id: str
|
|
129
|
+
revision: int
|
|
130
|
+
endpoint: str
|
|
131
|
+
request_type: type[RequestT]
|
|
132
|
+
response_adapter: TypeAdapter[RowT]
|
|
133
|
+
row_model: type[RowT]
|
|
134
|
+
access_tier: Literal["free", "tier_1", "tier_2"]
|
|
135
|
+
documented_limit: int | None = None
|
|
136
|
+
cost: int = 1
|
|
137
|
+
|
|
138
|
+
async def fetch(
|
|
139
|
+
self,
|
|
140
|
+
executor: _EndpointExecutor,
|
|
141
|
+
request: RequestT,
|
|
142
|
+
) -> list[RowT]:
|
|
143
|
+
"""Wrap the validated HTTP object in the analytical row list."""
|
|
144
|
+
return [await self.fetch_one(executor, request)]
|
|
145
|
+
|
|
146
|
+
async def fetch_one(
|
|
147
|
+
self,
|
|
148
|
+
executor: _EndpointExecutor,
|
|
149
|
+
request: RequestT,
|
|
150
|
+
) -> RowT:
|
|
151
|
+
"""Return the validated object through the shared endpoint executor."""
|
|
152
|
+
return await executor.fetch_one(
|
|
153
|
+
endpoint=self.endpoint,
|
|
154
|
+
request=request,
|
|
155
|
+
response_adapter=self.response_adapter,
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
@property
|
|
159
|
+
def rows_adapter(self) -> TypeAdapter[list[RowT]]:
|
|
160
|
+
"""Return the normalized analytical row-list adapter."""
|
|
161
|
+
annotation = GenericAlias(list, self.row_model)
|
|
162
|
+
return TypeAdapter(annotation)
|
|
163
|
+
|
|
164
|
+
@property
|
|
165
|
+
def response_contract(self) -> str:
|
|
166
|
+
"""Return the stable single-object response schema fingerprint."""
|
|
167
|
+
return _response_contract(self.response_adapter)
|
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
"""Render packaged SQLite templates through one strict
|
|
1
|
+
"""Render packaged SQLite templates through one strict shared handler."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from pathlib import PurePosixPath
|
|
6
6
|
|
|
7
|
-
from jinja2 import
|
|
8
|
-
BaseLoader,
|
|
9
|
-
Environment,
|
|
10
|
-
PackageLoader,
|
|
11
|
-
StrictUndefined,
|
|
12
|
-
TemplateError,
|
|
13
|
-
)
|
|
7
|
+
from jinja2 import BaseLoader, Environment, StrictUndefined, TemplateError
|
|
14
8
|
|
|
15
9
|
|
|
16
10
|
class SQLTemplateHandler:
|
|
@@ -60,9 +54,4 @@ class SQLTemplateHandler:
|
|
|
60
54
|
return rendered
|
|
61
55
|
|
|
62
56
|
|
|
63
|
-
|
|
64
|
-
"""Load installed SQLite templates from the cache package."""
|
|
65
|
-
|
|
66
|
-
def __init__(self) -> None:
|
|
67
|
-
"""Bind the strict handler to packaged cache SQL resources."""
|
|
68
|
-
super().__init__(PackageLoader("cfb_data.cache", "sql"))
|
|
57
|
+
__all__ = ["SQLTemplateHandler"]
|