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.
- {datafc-2.9.0 → datafc-2.10.0}/PKG-INFO +4 -4
- {datafc-2.9.0 → datafc-2.10.0}/README.md +166 -166
- {datafc-2.9.0 → datafc-2.10.0}/datafc/__init__.py +1 -1
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_rating_breakdown_data.py +66 -66
- {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/_parsers.py +191 -11
- {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_fixtures_data.py +46 -4
- {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_standings_data.py +37 -2
- {datafc-2.9.0 → datafc-2.10.0}/datafc.egg-info/PKG-INFO +4 -4
- {datafc-2.9.0 → datafc-2.10.0}/pyproject.toml +1 -1
- {datafc-2.9.0 → datafc-2.10.0}/LICENSE +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/clubelo/__init__.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/clubelo/_client.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/clubelo/_parsers.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/clubelo/fetch_club_history_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/clubelo/fetch_daily_ranking_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/clubelo/fetch_fixtures_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/eloratings/__init__.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/eloratings/_client.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/eloratings/_parsers.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/eloratings/fetch_country_codes_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/eloratings/fetch_country_matches_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/eloratings/fetch_teams_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/eloratings/fetch_tournament_codes_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/eloratings/fetch_tournament_editions_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/eloratings/fetch_tournament_groups_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/eloratings/fetch_world_ranking_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/exceptions.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/__init__.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/_core.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/_parsers.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/aio.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_average_positions_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_coordinates_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_formations_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_goal_networks_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_incidents_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_league_player_stats_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_lineups_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_match_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_match_details_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_match_h2h_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_match_odds_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_match_stats_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_momentum_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_past_matches_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_player_attribute_overviews_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_player_career_stats_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_player_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_player_match_log_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_player_national_team_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_player_stats_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_player_transfers_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_pregame_form_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_referee_stats_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_search_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_season_rounds_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_seasons_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_shots_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_squad_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_standings_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_substitutions_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_team_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_team_match_history_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_team_stats_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_team_transfers_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/sofascore/fetch_upcoming_matches_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/__init__.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/_client.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_match_cards_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_match_details_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_match_goals_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_match_lineups_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_match_staff_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_player_cards_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_player_career_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_player_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_player_goals_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_player_matches_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_player_national_matches_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/tff/fetch_team_data.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/utils/__init__.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/utils/_async_client.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/utils/_cache.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/utils/_client.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/utils/_config.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/utils/_helpers.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/utils/_save_files.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/utils/_tournament_info.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc/utils/_validate.py +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc.egg-info/SOURCES.txt +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc.egg-info/dependency_links.txt +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc.egg-info/requires.txt +0 -0
- {datafc-2.9.0 → datafc-2.10.0}/datafc.egg-info/top_level.txt +0 -0
- {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.
|
|
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.
|
|
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.
|
|
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,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
|