sportsball 0.3.101__tar.gz → 0.3.102__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 (219) hide show
  1. {sportsball-0.3.101/sportsball.egg-info → sportsball-0.3.102}/PKG-INFO +1 -1
  2. {sportsball-0.3.101 → sportsball-0.3.102}/setup.py +1 -1
  3. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/__init__.py +1 -1
  4. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/address_model.py +6 -1
  5. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/google/google_address_model.py +26 -6
  6. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/league_model.py +37 -1
  7. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/sportsreference/sportsreference_team_model.py +1 -0
  8. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/team_model.py +28 -28
  9. {sportsball-0.3.101 → sportsball-0.3.102/sportsball.egg-info}/PKG-INFO +1 -1
  10. {sportsball-0.3.101 → sportsball-0.3.102}/LICENSE +0 -0
  11. {sportsball-0.3.101 → sportsball-0.3.102}/MANIFEST.in +0 -0
  12. {sportsball-0.3.101 → sportsball-0.3.102}/README.md +0 -0
  13. {sportsball-0.3.101 → sportsball-0.3.102}/requirements.txt +0 -0
  14. {sportsball-0.3.101 → sportsball-0.3.102}/setup.cfg +0 -0
  15. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/__main__.py +0 -0
  16. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/args.py +0 -0
  17. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/cache.py +0 -0
  18. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/__init__.py +0 -0
  19. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/__init__.py +0 -0
  20. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/afl/__init__.py +0 -0
  21. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/afl/afl_afl_game_model.py +0 -0
  22. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/afl/afl_afl_league_model.py +0 -0
  23. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/afl/afl_afl_player_model.py +0 -0
  24. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/afl/afl_afl_team_model.py +0 -0
  25. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/afl/afl_afl_venue_model.py +0 -0
  26. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/afltables/__init__.py +0 -0
  27. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/afltables/afl_afltables_game_model.py +0 -0
  28. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/afltables/afl_afltables_league_model.py +0 -0
  29. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/afltables/afl_afltables_player_model.py +0 -0
  30. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/afltables/afl_afltables_team_model.py +0 -0
  31. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/afltables/afl_afltables_venue_model.py +0 -0
  32. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/aussportsbetting/__init__.py +0 -0
  33. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/aussportsbetting/afl_aussportsbetting_league_model.py +0 -0
  34. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/combined/__init__.py +0 -0
  35. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/combined/afl_combined_league_model.py +0 -0
  36. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/espn/__init__.py +0 -0
  37. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/espn/afl_espn_league_model.py +0 -0
  38. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/oddsportal/__init__.py +0 -0
  39. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/afl/oddsportal/afl_oddsportal_league_model.py +0 -0
  40. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/aussportsbetting/__init__.py +0 -0
  41. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/aussportsbetting/aussportsbetting_bookie_model.py +0 -0
  42. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/aussportsbetting/aussportsbetting_game_model.py +0 -0
  43. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/aussportsbetting/aussportsbetting_league_model.py +0 -0
  44. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/aussportsbetting/aussportsbetting_odds_model.py +0 -0
  45. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/aussportsbetting/aussportsbetting_team_model.py +0 -0
  46. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/aussportsbetting/aussportsbetting_venue_model.py +0 -0
  47. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/bookie_model.py +0 -0
  48. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/combined/__init__.py +0 -0
  49. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/combined/combined_address_model.py +0 -0
  50. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/combined/combined_game_model.py +0 -0
  51. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/combined/combined_league_model.py +0 -0
  52. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/combined/combined_player_model.py +0 -0
  53. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/combined/combined_team_model.py +0 -0
  54. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/combined/combined_venue_model.py +0 -0
  55. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/combined/combined_weather_model.py +0 -0
  56. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/espn/__init__.py +0 -0
  57. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/espn/espn_bookie_model.py +0 -0
  58. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/espn/espn_game_model.py +0 -0
  59. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/espn/espn_league_model.py +0 -0
  60. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/espn/espn_odds_model.py +0 -0
  61. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/espn/espn_player_model.py +0 -0
  62. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/espn/espn_team_model.py +0 -0
  63. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/espn/espn_venue_model.py +0 -0
  64. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/field_type.py +0 -0
  65. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/game_model.py +0 -0
  66. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/google/__init__.py +0 -0
  67. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/google/google_news_model.py +0 -0
  68. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/league.py +0 -0
  69. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/model.py +0 -0
  70. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nba/__init__.py +0 -0
  71. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nba/combined/__init__.py +0 -0
  72. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nba/combined/nba_combined_league_model.py +0 -0
  73. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nba/espn/__init__.py +0 -0
  74. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nba/espn/nba_espn_league_model.py +0 -0
  75. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nba/nba/__init__.py +0 -0
  76. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nba/nba/nba_nba_game_model.py +0 -0
  77. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nba/nba/nba_nba_league_model.py +0 -0
  78. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nba/nba/nba_nba_team_model.py +0 -0
  79. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nba/oddsportal/__init__.py +0 -0
  80. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nba/oddsportal/nba_oddsportal_league_model.py +0 -0
  81. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nba/sportsdb/__init__.py +0 -0
  82. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nba/sportsdb/nba_sportsdb_league_model.py +0 -0
  83. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nba/sportsreference/__init__.py +0 -0
  84. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nba/sportsreference/nba_sportsreference_league_model.py +0 -0
  85. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/ncaab/__init__.py +0 -0
  86. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/ncaab/combined/__init__.py +0 -0
  87. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/ncaab/combined/ncaab_combined_league_model.py +0 -0
  88. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/ncaab/espn/__init__.py +0 -0
  89. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/ncaab/espn/ncaab_espn_league_model.py +0 -0
  90. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/ncaab/oddsportal/__init__.py +0 -0
  91. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/ncaab/oddsportal/ncaab_oddsportal_league_model.py +0 -0
  92. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/ncaab/sportsreference/__init__.py +0 -0
  93. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/ncaab/sportsreference/ncaab_sportsreference_league_model.py +0 -0
  94. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/ncaaf/__init__.py +0 -0
  95. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/ncaaf/combined/__init__.py +0 -0
  96. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/ncaaf/combined/ncaaf_combined_league_model.py +0 -0
  97. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/ncaaf/espn/__init__.py +0 -0
  98. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/ncaaf/espn/ncaaf_espn_league_model.py +0 -0
  99. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/ncaaf/oddsportal/__init__.py +0 -0
  100. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/ncaaf/oddsportal/ncaaf_oddsportal_league_model.py +0 -0
  101. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/news_model.py +0 -0
  102. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nfl/__init__.py +0 -0
  103. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nfl/aussportsbetting/__init__.py +0 -0
  104. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nfl/aussportsbetting/nfl_aussportsbetting_league_model.py +0 -0
  105. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nfl/combined/__init__.py +0 -0
  106. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nfl/combined/nfl_combined_league_model.py +0 -0
  107. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nfl/espn/__init__.py +0 -0
  108. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nfl/espn/nfl_espn_league_model.py +0 -0
  109. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nfl/oddsportal/__init__.py +0 -0
  110. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nfl/oddsportal/nfl_oddsportal_league_model.py +0 -0
  111. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nfl/sportsdb/__init__.py +0 -0
  112. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/nfl/sportsdb/nfl_sportsdb_league_model.py +0 -0
  113. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/odds_model.py +0 -0
  114. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/oddsportal/__init__.py +0 -0
  115. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/oddsportal/decrypt.py +0 -0
  116. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/oddsportal/oddsportal_bookie_model.py +0 -0
  117. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/oddsportal/oddsportal_game_model.py +0 -0
  118. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/oddsportal/oddsportal_league_model.py +0 -0
  119. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/oddsportal/oddsportal_odds_model.py +0 -0
  120. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/oddsportal/oddsportal_team_model.py +0 -0
  121. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/oddsportal/oddsportal_venue_model.py +0 -0
  122. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/player_model.py +0 -0
  123. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/season_type.py +0 -0
  124. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/social_model.py +0 -0
  125. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/sportsdb/__init__.py +0 -0
  126. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/sportsdb/sportsdb_game_model.py +0 -0
  127. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/sportsdb/sportsdb_league_model.py +0 -0
  128. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/sportsdb/sportsdb_team_model.py +0 -0
  129. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/sportsdb/sportsdb_venue_model.py +0 -0
  130. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/sportsreference/__init__.py +0 -0
  131. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/sportsreference/sportsreference_game_model.py +0 -0
  132. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/sportsreference/sportsreference_league_model.py +0 -0
  133. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/sportsreference/sportsreference_player_model.py +0 -0
  134. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/sportsreference/sportsreference_venue_model.py +0 -0
  135. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/venue_model.py +0 -0
  136. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/weather/__init__.py +0 -0
  137. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/weather/gribstream/__init__.py +0 -0
  138. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/weather/gribstream/gribstream_weather_model.py +0 -0
  139. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/weather/multi_weather_model.py +0 -0
  140. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/weather/openmeteo/__init__.py +0 -0
  141. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/weather/openmeteo/openmeteo_weather_model.py +0 -0
  142. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/weather_model.py +0 -0
  143. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/wikipedia/__init__.py +0 -0
  144. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/wikipedia/wikipedia_venue_model.py +0 -0
  145. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/x/__init__.py +0 -0
  146. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/data/x/x_social_model.py +0 -0
  147. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/logger.py +0 -0
  148. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/loglevel.py +0 -0
  149. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/playwright.py +0 -0
  150. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/proxy_session.py +0 -0
  151. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/session.py +0 -0
  152. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/sportsball.py +0 -0
  153. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/vendor/__init__.py +0 -0
  154. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball/vendor/pygooglenews/__init__.py +0 -0
  155. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball.egg-info/SOURCES.txt +0 -0
  156. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball.egg-info/dependency_links.txt +0 -0
  157. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball.egg-info/entry_points.txt +0 -0
  158. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball.egg-info/not-zip-safe +0 -0
  159. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball.egg-info/requires.txt +0 -0
  160. {sportsball-0.3.101 → sportsball-0.3.102}/sportsball.egg-info/top_level.txt +0 -0
  161. {sportsball-0.3.101 → sportsball-0.3.102}/tests/__init__.py +0 -0
  162. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/__init__.py +0 -0
  163. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/afl/__init__.py +0 -0
  164. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/afl/afl/__init__.py +0 -0
  165. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/afl/afl/afl_afl_league_model_test.py +0 -0
  166. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/afl/afltables/__init__.py +0 -0
  167. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/afl/afltables/afl_afltables_game_model_test.py +0 -0
  168. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/afl/afltables/afl_afltables_league_model_test.py +0 -0
  169. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/afl/afltables/afl_afltables_player_model_test.py +0 -0
  170. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/aussportsbetting/__init__.py +0 -0
  171. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/aussportsbetting/aussportsbetting_game_model_test.py +0 -0
  172. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/combined/__init__.py +0 -0
  173. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/combined/combined_game_model_test.py +0 -0
  174. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/combined/combined_player_model_test.py +0 -0
  175. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/combined/combined_team_model_test.py +0 -0
  176. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/espn/__init__.py +0 -0
  177. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/espn/espn_game_model_test.py +0 -0
  178. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/espn/espn_player_model_test.py +0 -0
  179. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/game_model_test.py +0 -0
  180. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/google/__init__.py +0 -0
  181. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/google/google_address_model_test.py +0 -0
  182. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/google/google_news_model_test.py +0 -0
  183. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/nba/__init__.py +0 -0
  184. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/nba/nba/__init__.py +0 -0
  185. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/nba/nba/nba_nba_game_model_test.py +0 -0
  186. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/nba/nba/nba_nba_league_model_test.py +0 -0
  187. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/nba/nba/nba_nba_team_model_test.py +0 -0
  188. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/nba/sportsdb/__init__.py +0 -0
  189. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/nba/sportsdb/nba_sportsdb_league_model_test.py +0 -0
  190. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/nba/sportsreference/__init__.py +0 -0
  191. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/nba/sportsreference/nba_sportsreference_league_model_test.py +0 -0
  192. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/ncaab/__init__.py +0 -0
  193. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/ncaab/sportsreference/__init__.py +0 -0
  194. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/ncaab/sportsreference/ncaab_sportsreference_league_model_test.py +0 -0
  195. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/nfl/__init__.py +0 -0
  196. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/nfl/sportsdb/__init__.py +0 -0
  197. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/nfl/sportsdb/nfl_sportsdb_league_model_test.py +0 -0
  198. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/oddsportal/__init__.py +0 -0
  199. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/oddsportal/decrypt_test.py +0 -0
  200. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/oddsportal/oddsportal_game_model_test.py +0 -0
  201. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/oddsportal/oddsportal_league_model_test.py +0 -0
  202. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/player_model_test.py +0 -0
  203. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/social_model_test.py +0 -0
  204. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/sportsdb/__init__.py +0 -0
  205. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/sportsdb/sportsdb_game_model_test.py +0 -0
  206. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/sportsdb/sportsdb_league_model_test.py +0 -0
  207. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/sportsdb/sportsdb_team_model_test.py +0 -0
  208. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/sportsdb/sportsdb_venue_model_test.py +0 -0
  209. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/sportsreference/__init__.py +0 -0
  210. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/sportsreference/sportsreference_game_model_test.py +0 -0
  211. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/sportsreference/sportsreference_league_model_test.py +0 -0
  212. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/sportsreference/sportsreference_player_model_test.py +0 -0
  213. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/sportsreference/sportsreference_team_model_test.py +0 -0
  214. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/sportsreference/sportsreference_venue_model_test.py +0 -0
  215. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/team_model_test.py +0 -0
  216. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/x/__init__.py +0 -0
  217. {sportsball-0.3.101 → sportsball-0.3.102}/tests/data/x/x_social_model_test.py +0 -0
  218. {sportsball-0.3.101 → sportsball-0.3.102}/tests/proxy_session_test.py +0 -0
  219. {sportsball-0.3.101 → sportsball-0.3.102}/tests/sportsball_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: sportsball
3
- Version: 0.3.101
3
+ Version: 0.3.102
4
4
  Summary: A library for pulling in and normalising sports stats.
5
5
  Home-page: https://github.com/8W9aG/sportsball
6
6
  Author: Will Sackfield
@@ -26,7 +26,7 @@ def install_requires() -> typing.List[str]:
26
26
 
27
27
  setup(
28
28
  name='sportsball',
29
- version='0.3.101',
29
+ version='0.3.102',
30
30
  description='A library for pulling in and normalising sports stats.',
31
31
  long_description=long_description,
32
32
  long_description_content_type='text/markdown',
@@ -4,4 +4,4 @@
4
4
  import cchardet # type: ignore
5
5
  import lxml # noqa: ignore
6
6
 
7
- __VERSION__ = "0.3.101"
7
+ __VERSION__ = "0.3.102"
@@ -9,6 +9,7 @@ from .weather_model import WeatherModel
9
9
 
10
10
  ADDRESS_LATITUDE_COLUMN: Literal["latitude"] = "latitude"
11
11
  ADDRESS_LONGITUDE_COLUMN: Literal["longitude"] = "longitude"
12
+ ADDRESS_TIMEZONE_COLUMN: Literal["timezone"] = "timezone"
12
13
 
13
14
 
14
15
  class AddressModel(BaseModel):
@@ -25,5 +26,9 @@ class AddressModel(BaseModel):
25
26
  ..., json_schema_extra={TYPE_KEY: FieldType.CATEGORICAL}
26
27
  )
27
28
  weather: WeatherModel | None
28
- timezone: str = Field(..., json_schema_extra={TYPE_KEY: FieldType.CATEGORICAL})
29
+ timezone: str = Field(
30
+ ...,
31
+ json_schema_extra={TYPE_KEY: FieldType.CATEGORICAL},
32
+ alias=ADDRESS_TIMEZONE_COLUMN,
33
+ )
29
34
  country: str = Field(..., json_schema_extra={TYPE_KEY: FieldType.CATEGORICAL})
@@ -2557,6 +2557,15 @@ COLISEO_JUAN_AUBIN_CRUZ_ABREU = SportsballGeocodeTuple(
2557
2557
  housenumber="670",
2558
2558
  country="USA",
2559
2559
  )
2560
+ COLISEO_RUBEN_RODRIGUEZ = SportsballGeocodeTuple(
2561
+ city="Bayamon",
2562
+ state="PR",
2563
+ postal="",
2564
+ lat=18.394958,
2565
+ lng=-66.150833,
2566
+ housenumber="",
2567
+ country="USA",
2568
+ )
2560
2569
  _CACHED_GEOCODES: dict[str, Any] = {
2561
2570
  "S.C.G. - Australia": SCG,
2562
2571
  "Victoria Park - Australia": SportsballGeocodeTuple(
@@ -13606,13 +13615,24 @@ _CACHED_GEOCODES: dict[str, Any] = {
13606
13615
  ),
13607
13616
  "Coliseum, Cincinnati, Ohio": PAYCOR_STADIUM,
13608
13617
  "Riverfront Coliseum, Cincinnati, Ohio": PAYCOR_STADIUM,
13609
- "Coliseo Rubén Rodríguez, Bayamon": SportsballGeocodeTuple(
13610
- city="Bayamon",
13611
- state="PR",
13618
+ "Coliseo Rubén Rodríguez, Bayamon": COLISEO_RUBEN_RODRIGUEZ,
13619
+ "BankCorp South Arena, Tupelo, Mississippi": SportsballGeocodeTuple(
13620
+ city="Tupelo",
13621
+ state="MS",
13622
+ postal="38804",
13623
+ lat=34.26,
13624
+ lng=-88.7,
13625
+ housenumber="375",
13626
+ country="USA",
13627
+ ),
13628
+ "Coliseo Rubén Rodríguez, Bayamon": COLISEO_RUBEN_RODRIGUEZ,
13629
+ "Tim's Toyota Center, Prescott, Arizona": SportsballGeocodeTuple(
13630
+ city="Prescott",
13631
+ state="AZ",
13612
13632
  postal="",
13613
- lat=18.394958,
13614
- lng=-66.150833,
13615
- housenumber="",
13633
+ lat=34.589242,
13634
+ lng=-112.336361,
13635
+ housenumber="3201",
13616
13636
  country="USA",
13617
13637
  ),
13618
13638
  }
@@ -9,10 +9,12 @@ import tqdm
9
9
  from flatten_json import flatten # type: ignore
10
10
  from pydantic import BaseModel
11
11
 
12
+ from .address_model import ADDRESS_TIMEZONE_COLUMN
12
13
  from .field_type import FieldType
13
- from .game_model import GAME_DT_COLUMN, GameModel
14
+ from .game_model import GAME_DT_COLUMN, VENUE_COLUMN_PREFIX, GameModel
14
15
  from .league import League
15
16
  from .model import Model
17
+ from .venue_model import VENUE_ADDRESS_COLUMN
16
18
 
17
19
  LEAGUE_COLUMN = "league"
18
20
  DELIMITER = "/"
@@ -27,6 +29,37 @@ def _clear_column_list(df: pd.DataFrame) -> pd.DataFrame:
27
29
  return df.drop(columns=cols)
28
30
 
29
31
 
32
+ def _normalize_tz(df: pd.DataFrame) -> pd.DataFrame:
33
+ tz_column = DELIMITER.join(
34
+ [VENUE_COLUMN_PREFIX, VENUE_ADDRESS_COLUMN, ADDRESS_TIMEZONE_COLUMN]
35
+ )
36
+ if tz_column not in df.columns.values.tolist():
37
+ return df
38
+
39
+ tqdm.tqdm.pandas(desc="Timezone Conversions")
40
+
41
+ # Check each row to see if they have the correct timezone
42
+ def apply_tz(row: pd.Series) -> pd.Series:
43
+ if tz_column not in row:
44
+ return row
45
+ tz = row[tz_column]
46
+ if pd.isnull(tz):
47
+ return row
48
+
49
+ datetimes = {
50
+ col: val for col, val in row.items() if isinstance(val, pd.Timestamp)
51
+ }
52
+ for col, dt in datetimes.items():
53
+ if dt.tz is None:
54
+ row[col] = dt.tz_localize(tz, ambiguous=True)
55
+ elif str(dt.tz) != str(tz):
56
+ row[col] = dt.tz_convert(tz)
57
+
58
+ return row
59
+
60
+ return df.apply(apply_tz, axis=1)
61
+
62
+
30
63
  class LeagueModel(Model):
31
64
  """The prototype league model class."""
32
65
 
@@ -143,6 +176,9 @@ class LeagueModel(Model):
143
176
 
144
177
  for categorical_column in df.attrs[str(FieldType.CATEGORICAL)]:
145
178
  df[categorical_column] = df[categorical_column].astype("category")
179
+
180
+ df = _normalize_tz(df)
181
+
146
182
  if GAME_DT_COLUMN in df.columns.values:
147
183
  df[GAME_DT_COLUMN] = pd.to_datetime(df[GAME_DT_COLUMN], utc=True)
148
184
  df = df.sort_values(
@@ -41,6 +41,7 @@ _NON_WAYBACK_URLS: set[str] = {
41
41
  _BAD_TEAM_URLS = {
42
42
  "https://www.sports-reference.com/cbb/schools/mid-atlantic-christian/2016.html",
43
43
  "https://www.sports-reference.com/cbb/schools/claflin/2013.html",
44
+ "https://www.sports-reference.com/cbb/schools/chaminade/2011.html",
44
45
  }
45
46
 
46
47
 
@@ -52,7 +52,7 @@ TEAM_GOAL_ASSISTS_COLUMN: Literal["goal_assists"] = "goal_assists"
52
52
  def _calculate_kicks(data: dict[str, Any]) -> int | None:
53
53
  kicks = 0
54
54
  found_kicks = False
55
- for player in data[PLAYER_COLUMN_PREFIX]:
55
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
56
56
  player_kicks = player.kicks
57
57
  if player_kicks is None:
58
58
  continue
@@ -66,7 +66,7 @@ def _calculate_kicks(data: dict[str, Any]) -> int | None:
66
66
  def _calculate_field_goals(data: dict[str, Any]) -> int | None:
67
67
  field_goals = 0
68
68
  found_field_goals = False
69
- for player in data[PLAYER_COLUMN_PREFIX]:
69
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
70
70
  player_field_goals = player.field_goals
71
71
  if player_field_goals is None:
72
72
  continue
@@ -80,7 +80,7 @@ def _calculate_field_goals(data: dict[str, Any]) -> int | None:
80
80
  def _calculate_field_goals_attempted(data: dict[str, Any]) -> int | None:
81
81
  field_goals_attempted = 0
82
82
  found_field_goals_attempted = False
83
- for player in data[PLAYER_COLUMN_PREFIX]:
83
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
84
84
  player_field_goals_attempted = player.field_goals_attempted
85
85
  if player_field_goals_attempted is None:
86
86
  continue
@@ -94,7 +94,7 @@ def _calculate_field_goals_attempted(data: dict[str, Any]) -> int | None:
94
94
  def _calculate_offensive_rebounds(data: dict[str, Any]) -> int | None:
95
95
  offensive_rebounds = 0
96
96
  found_offensive_rebounds = False
97
- for player in data[PLAYER_COLUMN_PREFIX]:
97
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
98
98
  player_offensive_rebounds = player.offensive_rebounds
99
99
  if player_offensive_rebounds is None:
100
100
  continue
@@ -108,7 +108,7 @@ def _calculate_offensive_rebounds(data: dict[str, Any]) -> int | None:
108
108
  def _calculate_assists(data: dict[str, Any]) -> int | None:
109
109
  assists = 0
110
110
  found_assists = False
111
- for player in data[PLAYER_COLUMN_PREFIX]:
111
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
112
112
  player_assists = player.assists
113
113
  if player_assists is None:
114
114
  continue
@@ -122,7 +122,7 @@ def _calculate_assists(data: dict[str, Any]) -> int | None:
122
122
  def _calculate_turnovers(data: dict[str, Any]) -> int | None:
123
123
  turnovers = 0
124
124
  found_turnovers = False
125
- for player in data[PLAYER_COLUMN_PREFIX]:
125
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
126
126
  player_turnovers = player.turnovers
127
127
  if player_turnovers is None:
128
128
  continue
@@ -136,7 +136,7 @@ def _calculate_turnovers(data: dict[str, Any]) -> int | None:
136
136
  def _calculate_marks(data: dict[str, Any]) -> int | None:
137
137
  marks = 0
138
138
  found_marks = False
139
- for player in data[PLAYER_COLUMN_PREFIX]:
139
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
140
140
  player_marks = player.marks
141
141
  if player_marks is None:
142
142
  continue
@@ -150,7 +150,7 @@ def _calculate_marks(data: dict[str, Any]) -> int | None:
150
150
  def _calculate_handballs(data: dict[str, Any]) -> int | None:
151
151
  handballs = 0
152
152
  found_handballs = False
153
- for player in data[PLAYER_COLUMN_PREFIX]:
153
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
154
154
  player_handballs = player.handballs
155
155
  if player_handballs is None:
156
156
  continue
@@ -164,7 +164,7 @@ def _calculate_handballs(data: dict[str, Any]) -> int | None:
164
164
  def _calculate_disposals(data: dict[str, Any]) -> int | None:
165
165
  disposals = 0
166
166
  found_disposals = False
167
- for player in data[PLAYER_COLUMN_PREFIX]:
167
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
168
168
  player_disposals = player.disposals
169
169
  if player_disposals is None:
170
170
  continue
@@ -178,7 +178,7 @@ def _calculate_disposals(data: dict[str, Any]) -> int | None:
178
178
  def _calculate_goals(data: dict[str, Any]) -> int | None:
179
179
  goals = 0
180
180
  found_goals = False
181
- for player in data[PLAYER_COLUMN_PREFIX]:
181
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
182
182
  player_goals = player.goals
183
183
  if player_goals is None:
184
184
  continue
@@ -192,7 +192,7 @@ def _calculate_goals(data: dict[str, Any]) -> int | None:
192
192
  def _calculate_behinds(data: dict[str, Any]) -> int | None:
193
193
  behinds = 0
194
194
  found_behinds = False
195
- for player in data[PLAYER_COLUMN_PREFIX]:
195
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
196
196
  player_behinds = player.behinds
197
197
  if player_behinds is None:
198
198
  continue
@@ -206,7 +206,7 @@ def _calculate_behinds(data: dict[str, Any]) -> int | None:
206
206
  def _calculate_hit_outs(data: dict[str, Any]) -> int | None:
207
207
  hit_outs = 0
208
208
  found_hit_outs = False
209
- for player in data[PLAYER_COLUMN_PREFIX]:
209
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
210
210
  player_hit_outs = player.hit_outs
211
211
  if player_hit_outs is None:
212
212
  continue
@@ -220,7 +220,7 @@ def _calculate_hit_outs(data: dict[str, Any]) -> int | None:
220
220
  def _calculate_tackles(data: dict[str, Any]) -> int | None:
221
221
  tackles = 0
222
222
  found_tackles = False
223
- for player in data[PLAYER_COLUMN_PREFIX]:
223
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
224
224
  player_tackles = player.tackles
225
225
  if player_tackles is None:
226
226
  continue
@@ -234,7 +234,7 @@ def _calculate_tackles(data: dict[str, Any]) -> int | None:
234
234
  def _calculate_rebounds(data: dict[str, Any]) -> int | None:
235
235
  rebounds = 0
236
236
  found_rebounds = False
237
- for player in data[PLAYER_COLUMN_PREFIX]:
237
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
238
238
  player_rebounds = player.rebounds
239
239
  if player_rebounds is None:
240
240
  continue
@@ -248,7 +248,7 @@ def _calculate_rebounds(data: dict[str, Any]) -> int | None:
248
248
  def _calculate_insides(data: dict[str, Any]) -> int | None:
249
249
  insides = 0
250
250
  found_insides = False
251
- for player in data[PLAYER_COLUMN_PREFIX]:
251
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
252
252
  player_insides = player.insides
253
253
  if player_insides is None:
254
254
  continue
@@ -262,7 +262,7 @@ def _calculate_insides(data: dict[str, Any]) -> int | None:
262
262
  def _calculate_clearances(data: dict[str, Any]) -> int | None:
263
263
  clearances = 0
264
264
  found_clearances = False
265
- for player in data[PLAYER_COLUMN_PREFIX]:
265
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
266
266
  player_clearances = player.clearances
267
267
  if player_clearances is None:
268
268
  continue
@@ -276,7 +276,7 @@ def _calculate_clearances(data: dict[str, Any]) -> int | None:
276
276
  def _calculate_clangers(data: dict[str, Any]) -> int | None:
277
277
  clangers = 0
278
278
  found_clangers = False
279
- for player in data[PLAYER_COLUMN_PREFIX]:
279
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
280
280
  player_clangers = player.clangers
281
281
  if player_clangers is None:
282
282
  continue
@@ -290,7 +290,7 @@ def _calculate_clangers(data: dict[str, Any]) -> int | None:
290
290
  def _calculate_free_kicks_for(data: dict[str, Any]) -> int | None:
291
291
  free_kicks_for = 0
292
292
  found_free_kicks_for = False
293
- for player in data[PLAYER_COLUMN_PREFIX]:
293
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
294
294
  player_free_kicks_for = player.free_kicks_for
295
295
  if player_free_kicks_for is None:
296
296
  continue
@@ -304,7 +304,7 @@ def _calculate_free_kicks_for(data: dict[str, Any]) -> int | None:
304
304
  def _calculate_free_kicks_against(data: dict[str, Any]) -> int | None:
305
305
  free_kicks_against = 0
306
306
  found_free_kicks_against = False
307
- for player in data[PLAYER_COLUMN_PREFIX]:
307
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
308
308
  player_free_kicks_against = player.free_kicks_against
309
309
  if player_free_kicks_against is None:
310
310
  continue
@@ -318,7 +318,7 @@ def _calculate_free_kicks_against(data: dict[str, Any]) -> int | None:
318
318
  def _calculate_brownlow_votes(data: dict[str, Any]) -> int | None:
319
319
  brownlow_votes = 0
320
320
  found_brownlow_votes = False
321
- for player in data[PLAYER_COLUMN_PREFIX]:
321
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
322
322
  player_brownlow_votes = player.brownlow_votes
323
323
  if player_brownlow_votes is None:
324
324
  continue
@@ -332,7 +332,7 @@ def _calculate_brownlow_votes(data: dict[str, Any]) -> int | None:
332
332
  def _calculate_contested_possessions(data: dict[str, Any]) -> int | None:
333
333
  contested_possessions = 0
334
334
  found_contested_possessions = False
335
- for player in data[PLAYER_COLUMN_PREFIX]:
335
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
336
336
  player_contested_possessions = player.contested_possessions
337
337
  if player_contested_possessions is None:
338
338
  continue
@@ -346,7 +346,7 @@ def _calculate_contested_possessions(data: dict[str, Any]) -> int | None:
346
346
  def _calculate_uncontested_possessions(data: dict[str, Any]) -> int | None:
347
347
  uncontested_possessions = 0
348
348
  found_uncontested_possessions = False
349
- for player in data[PLAYER_COLUMN_PREFIX]:
349
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
350
350
  player_uncontested_possessions = player.uncontested_possessions
351
351
  if player_uncontested_possessions is None:
352
352
  continue
@@ -360,7 +360,7 @@ def _calculate_uncontested_possessions(data: dict[str, Any]) -> int | None:
360
360
  def _calculate_contested_marks(data: dict[str, Any]) -> int | None:
361
361
  contested_marks = 0
362
362
  found_contested_marks = False
363
- for player in data[PLAYER_COLUMN_PREFIX]:
363
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
364
364
  player_contested_marks = player.contested_marks
365
365
  if player_contested_marks is None:
366
366
  continue
@@ -374,7 +374,7 @@ def _calculate_contested_marks(data: dict[str, Any]) -> int | None:
374
374
  def _calculate_marks_inside(data: dict[str, Any]) -> int | None:
375
375
  marks_inside = 0
376
376
  found_marks_inside = False
377
- for player in data[PLAYER_COLUMN_PREFIX]:
377
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
378
378
  player_marks_inside = player.marks_inside
379
379
  if player_marks_inside is None:
380
380
  continue
@@ -388,7 +388,7 @@ def _calculate_marks_inside(data: dict[str, Any]) -> int | None:
388
388
  def _calculate_one_percenters(data: dict[str, Any]) -> int | None:
389
389
  one_percenters = 0
390
390
  found_one_percenters = False
391
- for player in data[PLAYER_COLUMN_PREFIX]:
391
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
392
392
  player_one_percenters = player.one_percenters
393
393
  if player_one_percenters is None:
394
394
  continue
@@ -402,7 +402,7 @@ def _calculate_one_percenters(data: dict[str, Any]) -> int | None:
402
402
  def _calculate_bounces(data: dict[str, Any]) -> int | None:
403
403
  bounces = 0
404
404
  found_bounces = False
405
- for player in data[PLAYER_COLUMN_PREFIX]:
405
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
406
406
  player_bounces = player.bounces
407
407
  if player_bounces is None:
408
408
  continue
@@ -416,7 +416,7 @@ def _calculate_bounces(data: dict[str, Any]) -> int | None:
416
416
  def _calculate_goal_assists(data: dict[str, Any]) -> int | None:
417
417
  goal_assists = 0
418
418
  found_goal_assists = False
419
- for player in data[PLAYER_COLUMN_PREFIX]:
419
+ for player in data.get(PLAYER_COLUMN_PREFIX, []):
420
420
  player_goal_assists = player.goal_assists
421
421
  if player_goal_assists is None:
422
422
  continue
@@ -580,7 +580,7 @@ class TeamModel(BaseModel):
580
580
  alias=TEAM_BOUNCES_COLUMN,
581
581
  )
582
582
  goal_assists: int | None = Field(
583
- default_factory=_calculate_bounces,
583
+ default_factory=_calculate_goal_assists,
584
584
  json_schema_extra={TYPE_KEY: FieldType.LOOKAHEAD},
585
585
  alias=TEAM_GOAL_ASSISTS_COLUMN,
586
586
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: sportsball
3
- Version: 0.3.101
3
+ Version: 0.3.102
4
4
  Summary: A library for pulling in and normalising sports stats.
5
5
  Home-page: https://github.com/8W9aG/sportsball
6
6
  Author: Will Sackfield
File without changes
File without changes
File without changes
File without changes