datafc 2.9.0__tar.gz → 2.10.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 (94) hide show
  1. {datafc-2.9.0 → datafc-2.10.0}/PKG-INFO +4 -4
  2. {datafc-2.9.0 → datafc-2.10.0}/README.md +166 -166
  3. {datafc-2.9.0 → datafc-2.10.0}/datafc/__init__.py +1 -1
  4. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_rating_breakdown_data.py +66 -66
  5. {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/_parsers.py +191 -11
  6. {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_fixtures_data.py +46 -4
  7. {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_standings_data.py +37 -2
  8. {datafc-2.9.0 → datafc-2.10.0}/datafc.egg-info/PKG-INFO +4 -4
  9. {datafc-2.9.0 → datafc-2.10.0}/pyproject.toml +1 -1
  10. {datafc-2.9.0 → datafc-2.10.0}/LICENSE +0 -0
  11. {datafc-2.9.0 → datafc-2.10.0}/datafc/clubelo/__init__.py +0 -0
  12. {datafc-2.9.0 → datafc-2.10.0}/datafc/clubelo/_client.py +0 -0
  13. {datafc-2.9.0 → datafc-2.10.0}/datafc/clubelo/_parsers.py +0 -0
  14. {datafc-2.9.0 → datafc-2.10.0}/datafc/clubelo/fetch_club_history_data.py +0 -0
  15. {datafc-2.9.0 → datafc-2.10.0}/datafc/clubelo/fetch_daily_ranking_data.py +0 -0
  16. {datafc-2.9.0 → datafc-2.10.0}/datafc/clubelo/fetch_fixtures_data.py +0 -0
  17. {datafc-2.9.0 → datafc-2.10.0}/datafc/eloratings/__init__.py +0 -0
  18. {datafc-2.9.0 → datafc-2.10.0}/datafc/eloratings/_client.py +0 -0
  19. {datafc-2.9.0 → datafc-2.10.0}/datafc/eloratings/_parsers.py +0 -0
  20. {datafc-2.9.0 → datafc-2.10.0}/datafc/eloratings/fetch_country_codes_data.py +0 -0
  21. {datafc-2.9.0 → datafc-2.10.0}/datafc/eloratings/fetch_country_matches_data.py +0 -0
  22. {datafc-2.9.0 → datafc-2.10.0}/datafc/eloratings/fetch_teams_data.py +0 -0
  23. {datafc-2.9.0 → datafc-2.10.0}/datafc/eloratings/fetch_tournament_codes_data.py +0 -0
  24. {datafc-2.9.0 → datafc-2.10.0}/datafc/eloratings/fetch_tournament_editions_data.py +0 -0
  25. {datafc-2.9.0 → datafc-2.10.0}/datafc/eloratings/fetch_tournament_groups_data.py +0 -0
  26. {datafc-2.9.0 → datafc-2.10.0}/datafc/eloratings/fetch_world_ranking_data.py +0 -0
  27. {datafc-2.9.0 → datafc-2.10.0}/datafc/exceptions.py +0 -0
  28. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/__init__.py +0 -0
  29. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/_core.py +0 -0
  30. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/_parsers.py +0 -0
  31. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/aio.py +0 -0
  32. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_average_positions_data.py +0 -0
  33. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_coordinates_data.py +0 -0
  34. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_formations_data.py +0 -0
  35. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_goal_networks_data.py +0 -0
  36. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_incidents_data.py +0 -0
  37. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_league_player_stats_data.py +0 -0
  38. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_lineups_data.py +0 -0
  39. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_match_data.py +0 -0
  40. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_match_details_data.py +0 -0
  41. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_match_h2h_data.py +0 -0
  42. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_match_odds_data.py +0 -0
  43. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_match_stats_data.py +0 -0
  44. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_momentum_data.py +0 -0
  45. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_past_matches_data.py +0 -0
  46. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_player_attribute_overviews_data.py +0 -0
  47. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_player_career_stats_data.py +0 -0
  48. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_player_data.py +0 -0
  49. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_player_match_log_data.py +0 -0
  50. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_player_national_team_data.py +0 -0
  51. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_player_stats_data.py +0 -0
  52. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_player_transfers_data.py +0 -0
  53. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_pregame_form_data.py +0 -0
  54. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_referee_stats_data.py +0 -0
  55. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_search_data.py +0 -0
  56. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_season_rounds_data.py +0 -0
  57. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_seasons_data.py +0 -0
  58. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_shots_data.py +0 -0
  59. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_squad_data.py +0 -0
  60. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_standings_data.py +0 -0
  61. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_substitutions_data.py +0 -0
  62. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_team_data.py +0 -0
  63. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_team_match_history_data.py +0 -0
  64. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_team_stats_data.py +0 -0
  65. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_team_transfers_data.py +0 -0
  66. {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_upcoming_matches_data.py +0 -0
  67. {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/__init__.py +0 -0
  68. {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/_client.py +0 -0
  69. {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_match_cards_data.py +0 -0
  70. {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_match_details_data.py +0 -0
  71. {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_match_goals_data.py +0 -0
  72. {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_match_lineups_data.py +0 -0
  73. {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_match_staff_data.py +0 -0
  74. {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_player_cards_data.py +0 -0
  75. {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_player_career_data.py +0 -0
  76. {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_player_data.py +0 -0
  77. {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_player_goals_data.py +0 -0
  78. {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_player_matches_data.py +0 -0
  79. {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_player_national_matches_data.py +0 -0
  80. {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_team_data.py +0 -0
  81. {datafc-2.9.0 → datafc-2.10.0}/datafc/utils/__init__.py +0 -0
  82. {datafc-2.9.0 → datafc-2.10.0}/datafc/utils/_async_client.py +0 -0
  83. {datafc-2.9.0 → datafc-2.10.0}/datafc/utils/_cache.py +0 -0
  84. {datafc-2.9.0 → datafc-2.10.0}/datafc/utils/_client.py +0 -0
  85. {datafc-2.9.0 → datafc-2.10.0}/datafc/utils/_config.py +0 -0
  86. {datafc-2.9.0 → datafc-2.10.0}/datafc/utils/_helpers.py +0 -0
  87. {datafc-2.9.0 → datafc-2.10.0}/datafc/utils/_save_files.py +0 -0
  88. {datafc-2.9.0 → datafc-2.10.0}/datafc/utils/_tournament_info.py +0 -0
  89. {datafc-2.9.0 → datafc-2.10.0}/datafc/utils/_validate.py +0 -0
  90. {datafc-2.9.0 → datafc-2.10.0}/datafc.egg-info/SOURCES.txt +0 -0
  91. {datafc-2.9.0 → datafc-2.10.0}/datafc.egg-info/dependency_links.txt +0 -0
  92. {datafc-2.9.0 → datafc-2.10.0}/datafc.egg-info/requires.txt +0 -0
  93. {datafc-2.9.0 → datafc-2.10.0}/datafc.egg-info/top_level.txt +0 -0
  94. {datafc-2.9.0 → datafc-2.10.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datafc
3
- Version: 2.9.0
3
+ Version: 2.10.0
4
4
  Summary: Fetch, process, and export structured football data.
5
5
  Author-email: Uraz Akgül <urazdev@gmail.com>
6
6
  License: MIT
@@ -25,7 +25,7 @@ Requires-Dist: pytest>=8.0; extra == "dev"
25
25
  Requires-Dist: pytest-mock>=3.12; extra == "dev"
26
26
  Dynamic: license-file
27
27
 
28
- # datafc v2.9.0
28
+ # datafc v2.10.0
29
29
 
30
30
  Football data from **Sofascore**, **ClubElo**, **eloratings.net** (Elo since 1872) and **tff.org** (Turkish federation) as pandas DataFrames. 60 functions total, each with an async mirror under `datafc.aio`, optional `DiskCache`.
31
31
 
@@ -138,8 +138,8 @@ Süper Lig, 1. Lig, 2. Lig, 3. Lig.
138
138
  ### Discovery / league
139
139
  | Function | Purpose |
140
140
  | --- | --- |
141
- | `fixtures_data(page_id, week=None, group=None, playoff=False, round=None)` | weekly fixtures or play-off bracket |
142
- | `standings_data(page_id, week, group=None)` | league table (`group` required for 2. Lig / 3. Lig) |
141
+ | `fixtures_data(page_id, week=None, group=None, playoff=False, round=None, stage=None)` | weekly fixtures or play-off bracket (`stage` picks a stage group, e.g. Süper Lig 2011/12 Süper Final) |
142
+ | `standings_data(page_id, week, group=None, stage=None)` | league table (`group` required for 2. Lig / 3. Lig; `stage` picks a play-off table, e.g. Süper Lig 2011/12) |
143
143
  | `team_data(club_id)` | club profile |
144
144
 
145
145
  ### From `match_id`
@@ -1,166 +1,166 @@
1
- # datafc v2.9.0
2
-
3
- Football data from **Sofascore**, **ClubElo**, **eloratings.net** (Elo since 1872) and **tff.org** (Turkish federation) as pandas DataFrames. 60 functions total, each with an async mirror under `datafc.aio`, optional `DiskCache`.
4
-
5
- ```bash
6
- pip install datafc
7
- ```
8
-
9
- ---
10
-
11
- ## Sofascore — `from datafc import ...`
12
-
13
- Grouped by the argument each function needs. Chain them: id → root frame → derived frame.
14
-
15
- ### Discovery
16
- | Function | Purpose |
17
- | --- | --- |
18
- | `search_data(query, entity_type=None)` | search teams, players, tournaments, managers |
19
- | `seasons_data(tournament_id)` | every season of a tournament |
20
- | `season_rounds_data(tournament_id, season_id)` | defined matchweeks |
21
-
22
- ### Root (id-driven)
23
- | Function | Purpose |
24
- | --- | --- |
25
- | `standings_data(tournament_id, season_id)` | Total / Home / Away table |
26
- | `match_data(tournament_id, season_id, week_number=None, tournament_type=None, tournament_stage=None)` | fixtures + scores |
27
- | `past_matches_data(...)` | same signature; H2H history per pair |
28
- | `team_match_history_data(team_id)` | full match history for one team |
29
- | `league_player_stats_data(tournament_id, season_id, order='-rating', accumulation='total', fields=None, position=None, max_players=100)` | wide-format player leaderboard |
30
- | `referee_stats_data(referee_id)` | per-tournament career stats |
31
-
32
- `tournament_type` ∈ `{"uefa", "world_cup", "league_playoff"}` with matching `tournament_stage` (`group_stage_week`, `round_of_16`, `quarterfinals`, `semifinals`, `final`, …).
33
-
34
- ### From `standings_df`
35
- | Function | Purpose |
36
- | --- | --- |
37
- | `team_data(standings_df)` | profile, kits, manager, venue |
38
- | `team_stats_data(standings_df, tournament_id, season_id, season=None)` | season team stats (long) |
39
- | `team_transfers_data(standings_df)` | team transfer log |
40
- | `player_stats_data(standings_df, tournament_id, season_id)` | top players per team |
41
- | `squad_data(standings_df)` | full roster |
42
- | `upcoming_matches_data(standings_df)` | upcoming fixtures |
43
-
44
- ### From `match_df`
45
- | Function | Purpose |
46
- | --- | --- |
47
- | `match_details_data` | referee + venue |
48
- | `formations_data` | formation strings |
49
- | `match_stats_data` | team stats per match |
50
- | `match_odds_data` | 1/X/2 odds |
51
- | `match_h2h_data` | head-to-head record |
52
- | `momentum_data` | minute-by-minute momentum |
53
- | `pregame_form_data` | last-5 form, rating, position, market value |
54
- | `shots_data` | every shot (xG, xGOT, body part, situation) |
55
- | `lineups_data` | XI + subs + per-match player stats |
56
- | `substitutions_data` | substitutions |
57
- | `incidents_data` | goals, cards, VAR |
58
- | `average_positions_data` | average pitch position (X/Y) |
59
- | `goal_networks_data` | coordinates for every action in a goal sequence |
60
-
61
- ### From `lineups_df`
62
- | Function | Purpose |
63
- | --- | --- |
64
- | `coordinates_data(lineups_df)` | touch heatmap per player |
65
- | `rating_breakdown_data(lineups_df)` | every pass / dribble / defensive action / ball-carry with start-end coordinates and outcome flags |
66
-
67
- ### From `squad_df`
68
- | Function | Purpose |
69
- | --- | --- |
70
- | `player_data` | profile |
71
- | `player_attribute_overviews_data` | radar attributes + baselines |
72
- | `player_transfers_data` | transfer history |
73
- | `player_career_stats_data` | season-by-season career stats |
74
- | `player_national_team_data` | international career |
75
- | `player_match_log_data` | match-by-match in-game stats (wide) |
76
-
77
- ---
78
-
79
- ## ClubElo — `from datafc import clubelo`
80
-
81
- Club names use ClubElo spelling (`Man City`, `Real Madrid`, `Paris SG`).
82
-
83
- | Function | Purpose |
84
- | --- | --- |
85
- | `daily_ranking_data(date)` | full ranking on a calendar day (`"YYYY-MM-DD"` or `date`) |
86
- | `club_history_data(club)` | Elo history for one club (pre-1960 values are provisional) |
87
- | `fixtures_data()` | probability grid for upcoming matches |
88
-
89
- ---
90
-
91
- ## EloRatings — `from datafc import eloratings`
92
-
93
- Country arguments are page slugs (`Czech_Republic`, `United_States`).
94
-
95
- | Function | Purpose |
96
- | --- | --- |
97
- | `world_ranking_data()` | current national-team ranking |
98
- | `country_matches_data(country)` | full international match history |
99
- | `country_codes_data()` | code → country |
100
- | `tournament_codes_data()` | code → tournament |
101
- | `tournament_editions_data()` | edition list with dates + slugs |
102
- | `tournament_groups_data()` | subcode → group code (e.g. WC qualifiers → `WQT`) |
103
- | `teams_data()` | legacy country code → ISO |
104
-
105
- ---
106
-
107
- ## TFF — `from datafc import tff`
108
-
109
- Süper Lig, 1. Lig, 2. Lig, 3. Lig.
110
-
111
- ### Discovery / league
112
- | Function | Purpose |
113
- | --- | --- |
114
- | `fixtures_data(page_id, week=None, group=None, playoff=False, round=None)` | weekly fixtures or play-off bracket |
115
- | `standings_data(page_id, week, group=None)` | league table (`group` required for 2. Lig / 3. Lig) |
116
- | `team_data(club_id)` | club profile |
117
-
118
- ### From `match_id`
119
- | Function | Purpose |
120
- | --- | --- |
121
- | `match_details_data` | teams, score, officials |
122
- | `match_lineups_data` | XI + bench |
123
- | `match_staff_data` | head coaches |
124
- | `match_goals_data` | goals with type (`F`/`H`/`P`/`K`/`KG`) |
125
- | `match_cards_data` | bookings (yellow / red / second_yellow) |
126
-
127
- ### From `player_id`
128
- | Function | Purpose |
129
- | --- | --- |
130
- | `player_data` | profile (licence, current club) |
131
- | `player_career_data` | licence history |
132
- | `player_national_matches_data` | national-team appearances |
133
- | `player_goals_data` | every recorded goal |
134
- | `player_matches_data(player_id, season)` | club matches in a season (`"2025-2026"`) |
135
- | `player_cards_data(player_id, season)` | bookings in a season |
136
-
137
- ---
138
-
139
- ## Async
140
-
141
- Every function has a mirror in `datafc.aio` with the same signature:
142
-
143
- ```python
144
- import asyncio
145
- from datafc import aio
146
-
147
- async def main():
148
- tasks = [aio.match_data(52, 63814, week_number=w) for w in range(1, 39)]
149
- return await asyncio.gather(*tasks, return_exceptions=True)
150
-
151
- asyncio.run(main())
152
- ```
153
-
154
- ## Cache
155
-
156
- ```python
157
- from datafc import DiskCache
158
-
159
- cache = DiskCache(cache_dir=".datafc_cache", ttl_hours=24)
160
- ```
161
-
162
- Pass `cache=cache` to any function. `ttl_hours=0` disables expiry; `cache.clear()` empties it.
163
-
164
- ## Exceptions
165
-
166
- `DataFCError` (base), `InvalidParameterError`, `APIError`, `RateLimitError`, `ServerError`, `DataNotAvailableError`.
1
+ # datafc v2.10.0
2
+
3
+ Football data from **Sofascore**, **ClubElo**, **eloratings.net** (Elo since 1872) and **tff.org** (Turkish federation) as pandas DataFrames. 60 functions total, each with an async mirror under `datafc.aio`, optional `DiskCache`.
4
+
5
+ ```bash
6
+ pip install datafc
7
+ ```
8
+
9
+ ---
10
+
11
+ ## Sofascore — `from datafc import ...`
12
+
13
+ Grouped by the argument each function needs. Chain them: id → root frame → derived frame.
14
+
15
+ ### Discovery
16
+ | Function | Purpose |
17
+ | --- | --- |
18
+ | `search_data(query, entity_type=None)` | search teams, players, tournaments, managers |
19
+ | `seasons_data(tournament_id)` | every season of a tournament |
20
+ | `season_rounds_data(tournament_id, season_id)` | defined matchweeks |
21
+
22
+ ### Root (id-driven)
23
+ | Function | Purpose |
24
+ | --- | --- |
25
+ | `standings_data(tournament_id, season_id)` | Total / Home / Away table |
26
+ | `match_data(tournament_id, season_id, week_number=None, tournament_type=None, tournament_stage=None)` | fixtures + scores |
27
+ | `past_matches_data(...)` | same signature; H2H history per pair |
28
+ | `team_match_history_data(team_id)` | full match history for one team |
29
+ | `league_player_stats_data(tournament_id, season_id, order='-rating', accumulation='total', fields=None, position=None, max_players=100)` | wide-format player leaderboard |
30
+ | `referee_stats_data(referee_id)` | per-tournament career stats |
31
+
32
+ `tournament_type` ∈ `{"uefa", "world_cup", "league_playoff"}` with matching `tournament_stage` (`group_stage_week`, `round_of_16`, `quarterfinals`, `semifinals`, `final`, …).
33
+
34
+ ### From `standings_df`
35
+ | Function | Purpose |
36
+ | --- | --- |
37
+ | `team_data(standings_df)` | profile, kits, manager, venue |
38
+ | `team_stats_data(standings_df, tournament_id, season_id, season=None)` | season team stats (long) |
39
+ | `team_transfers_data(standings_df)` | team transfer log |
40
+ | `player_stats_data(standings_df, tournament_id, season_id)` | top players per team |
41
+ | `squad_data(standings_df)` | full roster |
42
+ | `upcoming_matches_data(standings_df)` | upcoming fixtures |
43
+
44
+ ### From `match_df`
45
+ | Function | Purpose |
46
+ | --- | --- |
47
+ | `match_details_data` | referee + venue |
48
+ | `formations_data` | formation strings |
49
+ | `match_stats_data` | team stats per match |
50
+ | `match_odds_data` | 1/X/2 odds |
51
+ | `match_h2h_data` | head-to-head record |
52
+ | `momentum_data` | minute-by-minute momentum |
53
+ | `pregame_form_data` | last-5 form, rating, position, market value |
54
+ | `shots_data` | every shot (xG, xGOT, body part, situation) |
55
+ | `lineups_data` | XI + subs + per-match player stats |
56
+ | `substitutions_data` | substitutions |
57
+ | `incidents_data` | goals, cards, VAR |
58
+ | `average_positions_data` | average pitch position (X/Y) |
59
+ | `goal_networks_data` | coordinates for every action in a goal sequence |
60
+
61
+ ### From `lineups_df`
62
+ | Function | Purpose |
63
+ | --- | --- |
64
+ | `coordinates_data(lineups_df)` | touch heatmap per player |
65
+ | `rating_breakdown_data(lineups_df)` | every pass / dribble / defensive action / ball-carry with start-end coordinates and outcome flags |
66
+
67
+ ### From `squad_df`
68
+ | Function | Purpose |
69
+ | --- | --- |
70
+ | `player_data` | profile |
71
+ | `player_attribute_overviews_data` | radar attributes + baselines |
72
+ | `player_transfers_data` | transfer history |
73
+ | `player_career_stats_data` | season-by-season career stats |
74
+ | `player_national_team_data` | international career |
75
+ | `player_match_log_data` | match-by-match in-game stats (wide) |
76
+
77
+ ---
78
+
79
+ ## ClubElo — `from datafc import clubelo`
80
+
81
+ Club names use ClubElo spelling (`Man City`, `Real Madrid`, `Paris SG`).
82
+
83
+ | Function | Purpose |
84
+ | --- | --- |
85
+ | `daily_ranking_data(date)` | full ranking on a calendar day (`"YYYY-MM-DD"` or `date`) |
86
+ | `club_history_data(club)` | Elo history for one club (pre-1960 values are provisional) |
87
+ | `fixtures_data()` | probability grid for upcoming matches |
88
+
89
+ ---
90
+
91
+ ## EloRatings — `from datafc import eloratings`
92
+
93
+ Country arguments are page slugs (`Czech_Republic`, `United_States`).
94
+
95
+ | Function | Purpose |
96
+ | --- | --- |
97
+ | `world_ranking_data()` | current national-team ranking |
98
+ | `country_matches_data(country)` | full international match history |
99
+ | `country_codes_data()` | code → country |
100
+ | `tournament_codes_data()` | code → tournament |
101
+ | `tournament_editions_data()` | edition list with dates + slugs |
102
+ | `tournament_groups_data()` | subcode → group code (e.g. WC qualifiers → `WQT`) |
103
+ | `teams_data()` | legacy country code → ISO |
104
+
105
+ ---
106
+
107
+ ## TFF — `from datafc import tff`
108
+
109
+ Süper Lig, 1. Lig, 2. Lig, 3. Lig.
110
+
111
+ ### Discovery / league
112
+ | Function | Purpose |
113
+ | --- | --- |
114
+ | `fixtures_data(page_id, week=None, group=None, playoff=False, round=None, stage=None)` | weekly fixtures or play-off bracket (`stage` picks a stage group, e.g. Süper Lig 2011/12 Süper Final) |
115
+ | `standings_data(page_id, week, group=None, stage=None)` | league table (`group` required for 2. Lig / 3. Lig; `stage` picks a play-off table, e.g. Süper Lig 2011/12) |
116
+ | `team_data(club_id)` | club profile |
117
+
118
+ ### From `match_id`
119
+ | Function | Purpose |
120
+ | --- | --- |
121
+ | `match_details_data` | teams, score, officials |
122
+ | `match_lineups_data` | XI + bench |
123
+ | `match_staff_data` | head coaches |
124
+ | `match_goals_data` | goals with type (`F`/`H`/`P`/`K`/`KG`) |
125
+ | `match_cards_data` | bookings (yellow / red / second_yellow) |
126
+
127
+ ### From `player_id`
128
+ | Function | Purpose |
129
+ | --- | --- |
130
+ | `player_data` | profile (licence, current club) |
131
+ | `player_career_data` | licence history |
132
+ | `player_national_matches_data` | national-team appearances |
133
+ | `player_goals_data` | every recorded goal |
134
+ | `player_matches_data(player_id, season)` | club matches in a season (`"2025-2026"`) |
135
+ | `player_cards_data(player_id, season)` | bookings in a season |
136
+
137
+ ---
138
+
139
+ ## Async
140
+
141
+ Every function has a mirror in `datafc.aio` with the same signature:
142
+
143
+ ```python
144
+ import asyncio
145
+ from datafc import aio
146
+
147
+ async def main():
148
+ tasks = [aio.match_data(52, 63814, week_number=w) for w in range(1, 39)]
149
+ return await asyncio.gather(*tasks, return_exceptions=True)
150
+
151
+ asyncio.run(main())
152
+ ```
153
+
154
+ ## Cache
155
+
156
+ ```python
157
+ from datafc import DiskCache
158
+
159
+ cache = DiskCache(cache_dir=".datafc_cache", ttl_hours=24)
160
+ ```
161
+
162
+ Pass `cache=cache` to any function. `ttl_hours=0` disables expiry; `cache.clear()` empties it.
163
+
164
+ ## Exceptions
165
+
166
+ `DataFCError` (base), `InvalidParameterError`, `APIError`, `RateLimitError`, `ServerError`, `DataNotAvailableError`.
@@ -1,4 +1,4 @@
1
- __version__ = "2.9.0"
1
+ __version__ = "2.10.0"
2
2
 
3
3
  from .sofascore import *
4
4
  from . import clubelo
@@ -1,66 +1,66 @@
1
- from typing import TYPE_CHECKING, Optional
2
- import pandas as pd
3
- from datafc.utils._client import SofascoreClient
4
- from datafc.utils._config import API_URLS
5
- from datafc.utils._validate import validate_source, validate_df
6
- from datafc.sofascore._core import rating_breakdown_records, export_df
7
- from datafc.exceptions import APIError, DataNotAvailableError, InvalidParameterError
8
-
9
- if TYPE_CHECKING:
10
- from datafc.utils._cache import DiskCache
11
-
12
-
13
- def rating_breakdown_data(
14
- lineups_df: pd.DataFrame,
15
- data_source: str = "sofascore",
16
- rate_limit: float = 2.0,
17
- cache: Optional["DiskCache"] = None,
18
- enable_json_export: bool = False,
19
- enable_excel_export: bool = False,
20
- output_dir: str = ".",
21
- ) -> pd.DataFrame:
22
- """Fetches rating-breakdown action data for each player in the provided lineup dataset.
23
-
24
- The endpoint returns four buckets — passes, dribbles, defensive actions and
25
- ball carries — each with start (and optionally end) coordinates plus outcome
26
- flags (``outcome``, ``keypass``, ``isAssist``, ``isLongBall``). Rows are
27
- flattened so each action becomes a single record tagged with ``category``.
28
-
29
- Players with no rating breakdown data (404/403) are silently skipped.
30
- """
31
- validate_source(data_source)
32
- validate_df(lineups_df, "lineups_df")
33
-
34
- unique_players = lineups_df[[
35
- "country", "tournament", "season", "week", "game_id", "team", "player_id", "player_name"
36
- ]].drop_duplicates()
37
-
38
- if unique_players.empty:
39
- raise InvalidParameterError("No unique players found in lineups_df.")
40
-
41
- records = []
42
- with SofascoreClient(rate_limit=rate_limit, cache=cache) as client:
43
- for _, row in unique_players.iterrows():
44
- url = (
45
- f"{API_URLS[data_source]}/api/v1/event/{row['game_id']}"
46
- f"/player/{row['player_id']}/rating-breakdown"
47
- )
48
- try:
49
- data = client.get(url)
50
- except APIError as exc:
51
- if exc.status_code in (404, 403):
52
- continue
53
- raise
54
- records.extend(rating_breakdown_records(data, row))
55
-
56
- result_df = pd.DataFrame(records)
57
- if result_df.empty:
58
- raise DataNotAvailableError("No rating breakdown data found for the specified players.")
59
-
60
- export_df(
61
- result_df, fn_name="rating_breakdown_data", data_source=data_source,
62
- output_dir=output_dir,
63
- first_row=lineups_df.iloc[0],
64
- enable_json_export=enable_json_export, enable_excel_export=enable_excel_export,
65
- )
66
- return result_df
1
+ from typing import TYPE_CHECKING, Optional
2
+ import pandas as pd
3
+ from datafc.utils._client import SofascoreClient
4
+ from datafc.utils._config import API_URLS
5
+ from datafc.utils._validate import validate_source, validate_df
6
+ from datafc.sofascore._core import rating_breakdown_records, export_df
7
+ from datafc.exceptions import APIError, DataNotAvailableError, InvalidParameterError
8
+
9
+ if TYPE_CHECKING:
10
+ from datafc.utils._cache import DiskCache
11
+
12
+
13
+ def rating_breakdown_data(
14
+ lineups_df: pd.DataFrame,
15
+ data_source: str = "sofascore",
16
+ rate_limit: float = 2.0,
17
+ cache: Optional["DiskCache"] = None,
18
+ enable_json_export: bool = False,
19
+ enable_excel_export: bool = False,
20
+ output_dir: str = ".",
21
+ ) -> pd.DataFrame:
22
+ """Fetches rating-breakdown action data for each player in the provided lineup dataset.
23
+
24
+ The endpoint returns four buckets — passes, dribbles, defensive actions and
25
+ ball carries — each with start (and optionally end) coordinates plus outcome
26
+ flags (``outcome``, ``keypass``, ``isAssist``, ``isLongBall``). Rows are
27
+ flattened so each action becomes a single record tagged with ``category``.
28
+
29
+ Players with no rating breakdown data (404/403) are silently skipped.
30
+ """
31
+ validate_source(data_source)
32
+ validate_df(lineups_df, "lineups_df")
33
+
34
+ unique_players = lineups_df[[
35
+ "country", "tournament", "season", "week", "game_id", "team", "player_id", "player_name"
36
+ ]].drop_duplicates()
37
+
38
+ if unique_players.empty:
39
+ raise InvalidParameterError("No unique players found in lineups_df.")
40
+
41
+ records = []
42
+ with SofascoreClient(rate_limit=rate_limit, cache=cache) as client:
43
+ for _, row in unique_players.iterrows():
44
+ url = (
45
+ f"{API_URLS[data_source]}/api/v1/event/{row['game_id']}"
46
+ f"/player/{row['player_id']}/rating-breakdown"
47
+ )
48
+ try:
49
+ data = client.get(url)
50
+ except APIError as exc:
51
+ if exc.status_code in (404, 403):
52
+ continue
53
+ raise
54
+ records.extend(rating_breakdown_records(data, row))
55
+
56
+ result_df = pd.DataFrame(records)
57
+ if result_df.empty:
58
+ raise DataNotAvailableError("No rating breakdown data found for the specified players.")
59
+
60
+ export_df(
61
+ result_df, fn_name="rating_breakdown_data", data_source=data_source,
62
+ output_dir=output_dir,
63
+ first_row=lineups_df.iloc[0],
64
+ enable_json_export=enable_json_export, enable_excel_export=enable_excel_export,
65
+ )
66
+ return result_df