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.
Files changed (215) hide show
  1. cfb_data-0.6.0/PKG-INFO +305 -0
  2. cfb_data-0.6.0/README.md +264 -0
  3. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/__init__.py +16 -0
  4. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_executor.py +101 -7
  5. cfb_data-0.6.0/cfb_data/cfb_data/_observability.py +111 -0
  6. cfb_data-0.6.0/cfb_data/cfb_data/_reference_enums.py +790 -0
  7. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_transport.py +166 -13
  8. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_coordinator.py +494 -33
  9. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/client.py +13 -1
  10. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/enums.py +13 -0
  11. cfb_data-0.6.0/cfb_data/cfb_data/observability.py +632 -0
  12. cfb_data-0.6.0/cfb_data/cfb_data.egg-info/PKG-INFO +305 -0
  13. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data.egg-info/SOURCES.txt +3 -0
  14. {cfb_data-0.5.0 → cfb_data-0.6.0}/pyproject.toml +1 -1
  15. cfb_data-0.5.0/PKG-INFO +0 -482
  16. cfb_data-0.5.0/README.md +0 -441
  17. cfb_data-0.5.0/cfb_data/cfb_data.egg-info/PKG-INFO +0 -482
  18. {cfb_data-0.5.0 → cfb_data-0.6.0}/LICENSE +0 -0
  19. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_catalog/__init__.py +0 -0
  20. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_catalog/merge.py +0 -0
  21. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_catalog/models.py +0 -0
  22. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_catalog/projection.py +0 -0
  23. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_catalog/sources.py +0 -0
  24. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_dataframes.py +0 -0
  25. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_parquet.py +0 -0
  26. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_request_rules.py +0 -0
  27. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_requests.py +0 -0
  28. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/_tabular.py +0 -0
  29. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/adjusted_metrics/__init__.py +0 -0
  30. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/adjusted_metrics/models/__init__.py +0 -0
  31. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/adjusted_metrics/models/pydantic/__init__.py +0 -0
  32. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/adjusted_metrics/models/pydantic/requests.py +0 -0
  33. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/adjusted_metrics/models/pydantic/responses.py +0 -0
  34. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/adjusted_metrics/resource.py +0 -0
  35. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/base/__init__.py +0 -0
  36. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/base/types.py +0 -0
  37. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/betting/__init__.py +0 -0
  38. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/betting/models/__init__.py +0 -0
  39. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/betting/models/pydantic/__init__.py +0 -0
  40. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/betting/models/pydantic/requests.py +0 -0
  41. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/betting/models/pydantic/responses.py +0 -0
  42. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/betting/resource.py +0 -0
  43. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/__init__.py +0 -0
  44. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_backend.py +0 -0
  45. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_catalog.py +0 -0
  46. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_catalog_codecs.py +0 -0
  47. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_identity_codecs.py +0 -0
  48. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_key.py +0 -0
  49. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_models.py +0 -0
  50. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_null.py +0 -0
  51. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_redis.py +0 -0
  52. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_sqlite.py +0 -0
  53. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/_sqlite_sql.py +0 -0
  54. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/config.py +0 -0
  55. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/policy.py +0 -0
  56. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/acquire_refresh_lease.sql +0 -0
  57. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/begin_immediate.sql +0 -0
  58. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/catalog_counts.sql +0 -0
  59. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/cleanup_responses.sql +0 -0
  60. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/delete_coverage_failure.sql +0 -0
  61. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/delete_response.sql +0 -0
  62. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/delete_team_aliases.sql +0 -0
  63. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/enable_foreign_keys.sql +0 -0
  64. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/enable_wal.sql +0 -0
  65. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/find_athletes.sql +0 -0
  66. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/find_conference_by_id.sql +0 -0
  67. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/find_conference_by_name.sql +0 -0
  68. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/find_fresh_coverage.sql +0 -0
  69. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/find_game_by_id.sql +0 -0
  70. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/find_games.sql +0 -0
  71. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/find_team_by_id.sql +0 -0
  72. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/find_team_by_name.sql +0 -0
  73. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/find_venue_by_id.sql +0 -0
  74. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/find_venue_by_name.sql +0 -0
  75. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/get_response.sql +0 -0
  76. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/get_response_size.sql +0 -0
  77. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/get_schema_version.sql +0 -0
  78. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/initialize_schema_version.sql +0 -0
  79. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/release_refresh_lease.sql +0 -0
  80. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/renew_refresh_lease.sql +0 -0
  81. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/schema.sql +0 -0
  82. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/select_catalog_observations.sql +0 -0
  83. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/set_busy_timeout.sql +0 -0
  84. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/set_synchronous_normal.sql +0 -0
  85. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_athlete.sql +0 -0
  86. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_athlete_team_season.sql +0 -0
  87. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_catalog_observation.sql +0 -0
  88. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_coach.sql +0 -0
  89. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_coach_team_season.sql +0 -0
  90. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_conference.sql +0 -0
  91. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_conference_affiliation.sql +0 -0
  92. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_coverage.sql +0 -0
  93. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_coverage_failure.sql +0 -0
  94. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_drive.sql +0 -0
  95. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_game.sql +0 -0
  96. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_play.sql +0 -0
  97. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_playoff_matchup.sql +0 -0
  98. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_recruit.sql +0 -0
  99. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_response.sql +0 -0
  100. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_team.sql +0 -0
  101. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_team_alias.sql +0 -0
  102. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_team_season.sql +0 -0
  103. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_venue.sql +0 -0
  104. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/cache/sql/upsert_vocabulary.sql +0 -0
  105. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/coaches/__init__.py +0 -0
  106. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/coaches/models/__init__.py +0 -0
  107. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/coaches/models/pydantic/__init__.py +0 -0
  108. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/coaches/models/pydantic/requests.py +0 -0
  109. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/coaches/models/pydantic/responses.py +0 -0
  110. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/coaches/resource.py +0 -0
  111. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/conferences/__init__.py +0 -0
  112. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/conferences/models/__init__.py +0 -0
  113. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/conferences/models/pydantic/__init__.py +0 -0
  114. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/conferences/models/pydantic/identity.py +0 -0
  115. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/conferences/models/pydantic/requests.py +0 -0
  116. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/conferences/models/pydantic/responses.py +0 -0
  117. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/conferences/resource.py +0 -0
  118. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/draft/__init__.py +0 -0
  119. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/draft/models/__init__.py +0 -0
  120. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/draft/models/pydantic/__init__.py +0 -0
  121. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/draft/models/pydantic/requests.py +0 -0
  122. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/draft/models/pydantic/responses.py +0 -0
  123. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/draft/resource.py +0 -0
  124. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/drives/__init__.py +0 -0
  125. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/drives/models/__init__.py +0 -0
  126. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/drives/models/pydantic/__init__.py +0 -0
  127. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/drives/models/pydantic/requests.py +0 -0
  128. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/drives/models/pydantic/responses.py +0 -0
  129. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/drives/resource.py +0 -0
  130. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/errors.py +0 -0
  131. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/games/__init__.py +0 -0
  132. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/games/models/__init__.py +0 -0
  133. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/games/models/pydantic/__init__.py +0 -0
  134. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/games/models/pydantic/identity.py +0 -0
  135. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/games/models/pydantic/requests.py +0 -0
  136. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/games/models/pydantic/responses.py +0 -0
  137. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/games/resource.py +0 -0
  138. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/identities/__init__.py +0 -0
  139. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/identities/_normalization.py +0 -0
  140. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/identities/contracts.py +0 -0
  141. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/identities/resource.py +0 -0
  142. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/info/__init__.py +0 -0
  143. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/info/models/__init__.py +0 -0
  144. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/info/models/pydantic/__init__.py +0 -0
  145. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/info/models/pydantic/requests.py +0 -0
  146. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/info/models/pydantic/responses.py +0 -0
  147. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/info/resource.py +0 -0
  148. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/metrics/__init__.py +0 -0
  149. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/metrics/models/__init__.py +0 -0
  150. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/metrics/models/pydantic/__init__.py +0 -0
  151. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/metrics/models/pydantic/requests.py +0 -0
  152. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/metrics/models/pydantic/responses.py +0 -0
  153. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/metrics/resource.py +0 -0
  154. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/players/__init__.py +0 -0
  155. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/players/models/__init__.py +0 -0
  156. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/players/models/pydantic/__init__.py +0 -0
  157. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/players/models/pydantic/identity.py +0 -0
  158. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/players/models/pydantic/requests.py +0 -0
  159. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/players/models/pydantic/responses.py +0 -0
  160. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/players/resource.py +0 -0
  161. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/playoffs/__init__.py +0 -0
  162. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/playoffs/models/__init__.py +0 -0
  163. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/playoffs/models/pydantic/__init__.py +0 -0
  164. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/playoffs/models/pydantic/requests.py +0 -0
  165. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/playoffs/models/pydantic/responses.py +0 -0
  166. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/playoffs/resource.py +0 -0
  167. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/plays/__init__.py +0 -0
  168. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/plays/models/__init__.py +0 -0
  169. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/plays/models/pydantic/__init__.py +0 -0
  170. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/plays/models/pydantic/requests.py +0 -0
  171. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/plays/models/pydantic/responses.py +0 -0
  172. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/plays/resource.py +0 -0
  173. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/py.typed +0 -0
  174. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/rankings/__init__.py +0 -0
  175. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/rankings/models/__init__.py +0 -0
  176. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/rankings/models/pydantic/__init__.py +0 -0
  177. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/rankings/models/pydantic/requests.py +0 -0
  178. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/rankings/models/pydantic/responses.py +0 -0
  179. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/rankings/resource.py +0 -0
  180. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/ratings/__init__.py +0 -0
  181. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/ratings/models/__init__.py +0 -0
  182. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/ratings/models/pydantic/__init__.py +0 -0
  183. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/ratings/models/pydantic/requests.py +0 -0
  184. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/ratings/models/pydantic/responses.py +0 -0
  185. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/ratings/resource.py +0 -0
  186. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/recruiting/__init__.py +0 -0
  187. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/recruiting/models/__init__.py +0 -0
  188. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/recruiting/models/pydantic/__init__.py +0 -0
  189. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/recruiting/models/pydantic/requests.py +0 -0
  190. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/recruiting/models/pydantic/responses.py +0 -0
  191. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/recruiting/resource.py +0 -0
  192. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/retry.py +0 -0
  193. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/stats/__init__.py +0 -0
  194. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/stats/models/__init__.py +0 -0
  195. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/stats/models/pydantic/__init__.py +0 -0
  196. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/stats/models/pydantic/requests.py +0 -0
  197. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/stats/models/pydantic/responses.py +0 -0
  198. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/stats/resource.py +0 -0
  199. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/teams/__init__.py +0 -0
  200. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/teams/models/__init__.py +0 -0
  201. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/teams/models/pydantic/__init__.py +0 -0
  202. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/teams/models/pydantic/identity.py +0 -0
  203. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/teams/models/pydantic/requests.py +0 -0
  204. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/teams/models/pydantic/responses.py +0 -0
  205. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/teams/resource.py +0 -0
  206. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/venues/__init__.py +0 -0
  207. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/venues/models/__init__.py +0 -0
  208. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/venues/models/pydantic/__init__.py +0 -0
  209. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/venues/models/pydantic/identity.py +0 -0
  210. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/venues/models/pydantic/responses.py +0 -0
  211. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data/venues/resource.py +0 -0
  212. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data.egg-info/dependency_links.txt +0 -0
  213. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data.egg-info/requires.txt +0 -0
  214. {cfb_data-0.5.0 → cfb_data-0.6.0}/cfb_data/cfb_data.egg-info/top_level.txt +0 -0
  215. {cfb_data-0.5.0 → cfb_data-0.6.0}/setup.cfg +0 -0
@@ -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.
@@ -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",