datafc 2.7.2__tar.gz → 2.8.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.8.0/PKG-INFO +347 -0
- datafc-2.8.0/README.md +320 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/__init__.py +4 -1
- datafc-2.8.0/datafc/tff/__init__.py +40 -0
- datafc-2.8.0/datafc/tff/_client.py +396 -0
- datafc-2.8.0/datafc/tff/_parsers.py +1134 -0
- datafc-2.8.0/datafc/tff/fetch_fixtures_data.py +100 -0
- datafc-2.8.0/datafc/tff/fetch_match_cards_data.py +30 -0
- datafc-2.8.0/datafc/tff/fetch_match_details_data.py +28 -0
- datafc-2.8.0/datafc/tff/fetch_match_goals_data.py +31 -0
- datafc-2.8.0/datafc/tff/fetch_match_lineups_data.py +31 -0
- datafc-2.8.0/datafc/tff/fetch_match_staff_data.py +28 -0
- datafc-2.8.0/datafc/tff/fetch_player_cards_data.py +48 -0
- datafc-2.8.0/datafc/tff/fetch_player_career_data.py +33 -0
- datafc-2.8.0/datafc/tff/fetch_player_data.py +33 -0
- datafc-2.8.0/datafc/tff/fetch_player_goals_data.py +45 -0
- datafc-2.8.0/datafc/tff/fetch_player_matches_data.py +49 -0
- datafc-2.8.0/datafc/tff/fetch_player_national_matches_data.py +51 -0
- datafc-2.8.0/datafc/tff/fetch_standings_data.py +60 -0
- datafc-2.8.0/datafc/tff/fetch_team_data.py +28 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/utils/_config.py +25 -0
- datafc-2.8.0/datafc.egg-info/PKG-INFO +347 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc.egg-info/SOURCES.txt +17 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc.egg-info/requires.txt +1 -0
- {datafc-2.7.2 → datafc-2.8.0}/pyproject.toml +2 -1
- datafc-2.7.2/PKG-INFO +0 -1186
- datafc-2.7.2/README.md +0 -1160
- datafc-2.7.2/datafc.egg-info/PKG-INFO +0 -1186
- {datafc-2.7.2 → datafc-2.8.0}/LICENSE +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/clubelo/__init__.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/clubelo/_client.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/clubelo/_parsers.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/clubelo/fetch_club_history_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/clubelo/fetch_daily_ranking_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/clubelo/fetch_fixtures_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/eloratings/__init__.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/eloratings/_client.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/eloratings/_parsers.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/eloratings/fetch_country_codes_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/eloratings/fetch_country_matches_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/eloratings/fetch_teams_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/eloratings/fetch_tournament_codes_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/eloratings/fetch_tournament_editions_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/eloratings/fetch_tournament_groups_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/eloratings/fetch_world_ranking_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/exceptions.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/__init__.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/_core.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/_parsers.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/aio.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_average_positions_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_coordinates_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_formations_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_goal_networks_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_incidents_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_league_player_stats_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_lineups_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_match_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_match_details_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_match_h2h_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_match_odds_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_match_stats_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_momentum_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_past_matches_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_player_attribute_overviews_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_player_career_stats_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_player_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_player_match_log_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_player_national_team_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_player_stats_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_player_transfers_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_pregame_form_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_referee_stats_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_search_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_season_rounds_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_seasons_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_shots_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_squad_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_standings_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_substitutions_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_team_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_team_match_history_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_team_stats_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_team_transfers_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/sofascore/fetch_upcoming_matches_data.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/utils/__init__.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/utils/_async_client.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/utils/_cache.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/utils/_client.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/utils/_helpers.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/utils/_save_files.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/utils/_tournament_info.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc/utils/_validate.py +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc.egg-info/dependency_links.txt +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/datafc.egg-info/top_level.txt +0 -0
- {datafc-2.7.2 → datafc-2.8.0}/setup.cfg +0 -0
datafc-2.8.0/PKG-INFO
ADDED
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: datafc
|
|
3
|
+
Version: 2.8.0
|
|
4
|
+
Summary: Fetch, process, and export structured football data.
|
|
5
|
+
Author-email: Uraz Akgül <urazdev@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/urazakgul/datafc
|
|
8
|
+
Project-URL: Repository, https://github.com/urazakgul/datafc
|
|
9
|
+
Project-URL: Issues, https://github.com/urazakgul/datafc/issues
|
|
10
|
+
Keywords: football,soccer,data,analytics,sofascore,clubelo,eloratings,elo
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: pandas>=1.5
|
|
15
|
+
Requires-Dist: curl_cffi>=0.7
|
|
16
|
+
Requires-Dist: openpyxl>=3.0
|
|
17
|
+
Requires-Dist: beautifulsoup4>=4.11
|
|
18
|
+
Provides-Extra: parquet
|
|
19
|
+
Requires-Dist: pyarrow>=12.0; extra == "parquet"
|
|
20
|
+
Provides-Extra: dev
|
|
21
|
+
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
22
|
+
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
23
|
+
Requires-Dist: pandas-stubs>=2.0; extra == "dev"
|
|
24
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
25
|
+
Requires-Dist: pytest-mock>=3.12; extra == "dev"
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# datafc v2.8.0
|
|
29
|
+
|
|
30
|
+
`datafc` is a Python package that turns four public football data sources into clean `pandas` DataFrames: **Sofascore** (tournaments, matches, players, shots, lineups, odds), **ClubElo** (club Elo ratings back to 1939), **eloratings.net** (national team Elo ratings back to 1872), and **tff.org** (Turkish Football Federation fixtures, standings, match sheets, and player pages). 59 functions in total, all with the same call style and an async equivalent under `datafc.aio`.
|
|
31
|
+
|
|
32
|
+
## Sofascore
|
|
33
|
+
|
|
34
|
+
Import from top-level `datafc`.
|
|
35
|
+
|
|
36
|
+
### Discovery and Metadata
|
|
37
|
+
|
|
38
|
+
#### `search_data(query, entity_type=None)`
|
|
39
|
+
Search by name.
|
|
40
|
+
- `query` (str): the search term.
|
|
41
|
+
- `entity_type` (str, optional): `"team"`, `"player"`, `"tournament"`, or `"manager"`. `None` returns all types.
|
|
42
|
+
|
|
43
|
+
#### `seasons_data(tournament_id)`
|
|
44
|
+
Lists every season for a tournament.
|
|
45
|
+
- `tournament_id` (int)
|
|
46
|
+
|
|
47
|
+
#### `season_rounds_data(tournament_id, season_id)`
|
|
48
|
+
Lists every matchweek defined for a season.
|
|
49
|
+
- `tournament_id` (int)
|
|
50
|
+
- `season_id` (int)
|
|
51
|
+
|
|
52
|
+
### League / Season
|
|
53
|
+
|
|
54
|
+
#### `standings_data(tournament_id, season_id)`
|
|
55
|
+
League table for Total, Home, and Away categories.
|
|
56
|
+
- `tournament_id` (int)
|
|
57
|
+
- `season_id` (int)
|
|
58
|
+
|
|
59
|
+
#### `team_data(standings_df)`
|
|
60
|
+
Team profiles: stadium, kit colors, manager, venue capacity.
|
|
61
|
+
- `standings_df` (DataFrame): output of `standings_data`.
|
|
62
|
+
|
|
63
|
+
#### `team_stats_data(standings_df, tournament_id, season_id, season=None)`
|
|
64
|
+
Season-level team statistics (long format).
|
|
65
|
+
- `standings_df` (DataFrame)
|
|
66
|
+
- `tournament_id` (int)
|
|
67
|
+
- `season_id` (int)
|
|
68
|
+
- `season` (str, optional): human-readable label used only in the export filename.
|
|
69
|
+
|
|
70
|
+
#### `team_transfers_data(standings_df)`
|
|
71
|
+
All incoming and outgoing transfer records per team.
|
|
72
|
+
- `standings_df` (DataFrame)
|
|
73
|
+
|
|
74
|
+
#### `player_stats_data(standings_df, tournament_id, season_id)`
|
|
75
|
+
Top player statistics per team (long format).
|
|
76
|
+
- `standings_df` (DataFrame)
|
|
77
|
+
- `tournament_id` (int)
|
|
78
|
+
- `season_id` (int)
|
|
79
|
+
|
|
80
|
+
#### `squad_data(standings_df)`
|
|
81
|
+
Squad roster: age, height, position, preferred foot, contract expiry, market value.
|
|
82
|
+
- `standings_df` (DataFrame)
|
|
83
|
+
|
|
84
|
+
#### `upcoming_matches_data(standings_df)`
|
|
85
|
+
Upcoming fixtures for every team in the standings.
|
|
86
|
+
- `standings_df` (DataFrame)
|
|
87
|
+
|
|
88
|
+
#### `team_match_history_data(team_id)`
|
|
89
|
+
Full match history for a single team across all competitions.
|
|
90
|
+
- `team_id` (int): from `standings_data`, `squad_data`, or `search_data`.
|
|
91
|
+
|
|
92
|
+
#### `league_player_stats_data(tournament_id, season_id, order="-rating", accumulation="total", fields=None, position=None, max_players=100)`
|
|
93
|
+
Wide-format player rankings across an entire league.
|
|
94
|
+
- `tournament_id` (int)
|
|
95
|
+
- `season_id` (int)
|
|
96
|
+
- `order` (str): field to sort by; prefix with `-` for descending.
|
|
97
|
+
- `accumulation` (str): `"total"`, `"per90"`, or `"perMatch"`.
|
|
98
|
+
- `fields` (list, optional): stat columns to include. `None` uses 14 defaults.
|
|
99
|
+
- `position` (str, optional): `"G"`, `"D"`, `"M"`, or `"F"`.
|
|
100
|
+
- `max_players` (int): paginates as needed.
|
|
101
|
+
|
|
102
|
+
Available fields: `goals`, `assists`, `rating`, `expectedGoals`, `expectedAssists`, `goalsAssistsSum`, `penaltyGoals`, `freeKickGoal`, `scoringFrequency`, `totalShots`, `shotsOnTarget`, `bigChancesCreated`, `bigChancesMissed`, `accuratePasses`, `accuratePassesPercentage`, `keyPasses`, `accurateLongBalls`, `accurateLongBallsPercentage`, `successfulDribbles`, `successfulDribblesPercentage`, `tackles`, `interceptions`, `clearances`, `possessionLost`, `yellowCards`, `redCards`, `saves`, `goalsPrevented`, `minutesPlayed`, `appearances`.
|
|
103
|
+
|
|
104
|
+
### Match
|
|
105
|
+
|
|
106
|
+
#### `match_data(tournament_id, season_id, week_number=None, tournament_type=None, tournament_stage=None)`
|
|
107
|
+
Fixtures and scores for a matchweek or tournament stage.
|
|
108
|
+
- `tournament_id` (int)
|
|
109
|
+
- `season_id` (int)
|
|
110
|
+
- `week_number` (int, optional): required for league rounds, UEFA stages, `world_cup` + `group_stage_week`, and every `league_playoff` stage. Not needed for World Cup knockouts.
|
|
111
|
+
- `tournament_type` (str, optional): `"uefa"`, `"world_cup"`, or `"league_playoff"`. `None` assumes a domestic league.
|
|
112
|
+
- `tournament_stage` (str, optional): required when `tournament_type` is set.
|
|
113
|
+
- `"uefa"`: `preliminary_semifinals`, `preliminary_final`, `qualification_round`, `qualification_playoff`, `group_stage_week`, `playoff_round`, `round_of_16`, `quarterfinals`, `semifinals`, `match_for_3rd_place`, `final`.
|
|
114
|
+
- `"world_cup"`: `group_stage_week`, `round_of_32`, `round_of_16`, `quarterfinals`, `semifinals`, `match_for_3rd_place`, `final`.
|
|
115
|
+
- `"league_playoff"`: `qualification_round`, `quarterfinals`, `semifinals`, `final`.
|
|
116
|
+
|
|
117
|
+
The match functions below (except `coordinates_data`) all take `match_df` as their only argument.
|
|
118
|
+
|
|
119
|
+
#### `match_details_data(match_df)`
|
|
120
|
+
Referee info (name, cards, career games) and venue details per match.
|
|
121
|
+
|
|
122
|
+
#### `formations_data(match_df)`
|
|
123
|
+
Home and away formation string (e.g. `4-3-3`).
|
|
124
|
+
|
|
125
|
+
#### `match_stats_data(match_df)`
|
|
126
|
+
Team stats per match (possession, shots, fouls, per period).
|
|
127
|
+
|
|
128
|
+
#### `match_odds_data(match_df)`
|
|
129
|
+
Pre-match and live 1/X/2 betting odds.
|
|
130
|
+
|
|
131
|
+
#### `match_h2h_data(match_df)`
|
|
132
|
+
All-time head-to-head record between the two teams.
|
|
133
|
+
|
|
134
|
+
#### `momentum_data(match_df)`
|
|
135
|
+
Minute-by-minute momentum score (positive: home; negative: away).
|
|
136
|
+
|
|
137
|
+
#### `pregame_form_data(match_df)`
|
|
138
|
+
Last 5 results, average rating, league position, and squad value before the match for each side.
|
|
139
|
+
|
|
140
|
+
#### `shots_data(match_df)`
|
|
141
|
+
Every shot event with coordinates, xG, xGOT, body part, situation, and goal mouth location.
|
|
142
|
+
|
|
143
|
+
#### `lineups_data(match_df)`
|
|
144
|
+
Starting XI and substitutes plus per-match player stats (long format).
|
|
145
|
+
|
|
146
|
+
#### `substitutions_data(match_df)`
|
|
147
|
+
Substitution events with minute, player in, player out.
|
|
148
|
+
|
|
149
|
+
#### `incidents_data(match_df)`
|
|
150
|
+
Goals, cards, and VAR decisions per match.
|
|
151
|
+
|
|
152
|
+
#### `average_positions_data(match_df)`
|
|
153
|
+
Each player's average pitch position (X/Y on a 0 to 100 scale).
|
|
154
|
+
|
|
155
|
+
#### `goal_networks_data(match_df)`
|
|
156
|
+
Coordinates for every action in a goal-scoring sequence (passes, shots, goalkeeper position).
|
|
157
|
+
|
|
158
|
+
#### `past_matches_data(tournament_id, season_id, week_number=None, tournament_type=None, tournament_stage=None)`
|
|
159
|
+
Full head-to-head history for every team pair in the given matchweek. Same signature and stage options as `match_data`.
|
|
160
|
+
|
|
161
|
+
#### `coordinates_data(lineups_df)`
|
|
162
|
+
Heatmap touch coordinates per player.
|
|
163
|
+
- `lineups_df` (DataFrame): output of `lineups_data`.
|
|
164
|
+
|
|
165
|
+
### Player
|
|
166
|
+
|
|
167
|
+
Every function below takes `squad_df` (output of `squad_data`) as its only argument.
|
|
168
|
+
|
|
169
|
+
#### `player_data(squad_df)`
|
|
170
|
+
Player profile: nationality, date of birth, height, weight, preferred foot, jersey number, position, market value.
|
|
171
|
+
|
|
172
|
+
#### `player_attribute_overviews_data(squad_df)`
|
|
173
|
+
Radar attribute snapshots (attacking, technical, tactical, defending, creativity) per player, with the position-average baseline and previous-year snapshots.
|
|
174
|
+
|
|
175
|
+
#### `player_transfers_data(squad_df)`
|
|
176
|
+
Transfer history per player.
|
|
177
|
+
|
|
178
|
+
#### `player_career_stats_data(squad_df)`
|
|
179
|
+
Season-by-season career stats across all competitions (long format, `overall` entries only).
|
|
180
|
+
|
|
181
|
+
#### `player_national_team_data(squad_df)`
|
|
182
|
+
National team career: appearances, goals, debut date.
|
|
183
|
+
|
|
184
|
+
#### `player_match_log_data(squad_df)`
|
|
185
|
+
Match-by-match in-game stats across every recorded match (wide format).
|
|
186
|
+
|
|
187
|
+
### Referee
|
|
188
|
+
|
|
189
|
+
#### `referee_stats_data(referee_id)`
|
|
190
|
+
Career stats for a referee (per tournament).
|
|
191
|
+
- `referee_id` (int): from the `referee_id` column of `match_details_data`.
|
|
192
|
+
|
|
193
|
+
## ClubElo
|
|
194
|
+
|
|
195
|
+
Import from `datafc.clubelo`. Club names must match ClubElo's spelling (e.g. `"Man City"`, `"Real Madrid"`, `"Paris SG"`).
|
|
196
|
+
|
|
197
|
+
#### `clubelo.daily_ranking_data(date)`
|
|
198
|
+
Full ClubElo ranking for a given calendar day.
|
|
199
|
+
- `date` (str or `datetime.date`): `"YYYY-MM-DD"` or a `date` object.
|
|
200
|
+
|
|
201
|
+
#### `clubelo.club_history_data(club)`
|
|
202
|
+
Complete Elo rating history for a single club (values before 1960 are provisional).
|
|
203
|
+
- `club` (str): the ClubElo spelling.
|
|
204
|
+
|
|
205
|
+
#### `clubelo.fixtures_data()`
|
|
206
|
+
Per-goal-difference and exact-result probabilities for upcoming matches. No arguments.
|
|
207
|
+
|
|
208
|
+
## EloRatings (National Teams)
|
|
209
|
+
|
|
210
|
+
Import from `datafc.eloratings`. Country arguments are page slugs, not ISO codes (e.g. `"Czech_Republic"`, `"United_States"`).
|
|
211
|
+
|
|
212
|
+
#### `eloratings.world_ranking_data()`
|
|
213
|
+
Current global Elo ranking for every national team.
|
|
214
|
+
|
|
215
|
+
#### `eloratings.country_matches_data(country)`
|
|
216
|
+
Complete international match history for one national team.
|
|
217
|
+
- `country` (str): the page slug used on eloratings.net.
|
|
218
|
+
|
|
219
|
+
#### `eloratings.country_codes_data()`
|
|
220
|
+
Country code to English country name lookup.
|
|
221
|
+
|
|
222
|
+
#### `eloratings.tournament_codes_data()`
|
|
223
|
+
Tournament code to English tournament name lookup.
|
|
224
|
+
|
|
225
|
+
#### `eloratings.tournament_editions_data()`
|
|
226
|
+
Every tournament edition with start/end dates and page slug.
|
|
227
|
+
|
|
228
|
+
#### `eloratings.tournament_groups_data()`
|
|
229
|
+
Specific tournament code to broader group code (e.g. every WC qualifier variant to `WQT`).
|
|
230
|
+
|
|
231
|
+
#### `eloratings.teams_data()`
|
|
232
|
+
Legacy/historical country code to ISO code mapping.
|
|
233
|
+
|
|
234
|
+
## TFF (Turkish Football Federation)
|
|
235
|
+
|
|
236
|
+
Import from `datafc.tff`. Covers Süper Lig, 1. Lig, 2. Lig, 3. Lig.
|
|
237
|
+
|
|
238
|
+
### Fixtures, Standings, Club
|
|
239
|
+
|
|
240
|
+
#### `tff.fixtures_data(page_id, week=None, group=None, playoff=False, round=None)`
|
|
241
|
+
Weekly fixtures or the promotion play-off bracket.
|
|
242
|
+
- `page_id` (int): the `pageID` query parameter from the tff.org fixture URL.
|
|
243
|
+
- `week` (int, optional): matchweek number.
|
|
244
|
+
- `group` (str, optional): 2. Lig (`"Kırmızı"` / `"Beyaz"`) or 3. Lig (`"01"` to `"04"`); case-insensitive.
|
|
245
|
+
- `playoff` (bool): `True` returns the 1./2./3. Lig play-off bracket with extra-time and penalty-shootout scores.
|
|
246
|
+
- `round` (str, optional): filter play-off rounds (e.g. `"Final"`).
|
|
247
|
+
|
|
248
|
+
#### `tff.standings_data(page_id, week, group=None)`
|
|
249
|
+
League table as of a matchweek.
|
|
250
|
+
- `page_id` (int)
|
|
251
|
+
- `week` (int)
|
|
252
|
+
- `group` (str, optional): required for 2. Lig and 3. Lig.
|
|
253
|
+
|
|
254
|
+
#### `tff.team_data(club_id)`
|
|
255
|
+
Club profile: official (unsponsored) name, address, president, plus stadium info.
|
|
256
|
+
- `club_id` (int)
|
|
257
|
+
|
|
258
|
+
### Match Sheet
|
|
259
|
+
|
|
260
|
+
Every function below takes `match_id` (int) as its only argument.
|
|
261
|
+
|
|
262
|
+
#### `tff.match_details_data(match_id)`
|
|
263
|
+
Match header (teams, score, stadium, tournament) plus every assigned official.
|
|
264
|
+
|
|
265
|
+
#### `tff.match_lineups_data(match_id)`
|
|
266
|
+
Starting XI and bench for both teams (jersey number, player id, player name).
|
|
267
|
+
|
|
268
|
+
#### `tff.match_staff_data(match_id)`
|
|
269
|
+
Head coach for both teams (coach id and name).
|
|
270
|
+
|
|
271
|
+
#### `tff.match_goals_data(match_id)`
|
|
272
|
+
Every goal with scorer, minute, and TFF code (`F` foot, `H` header, `P` penalty, `K` free kick, `KG` own goal).
|
|
273
|
+
|
|
274
|
+
#### `tff.match_cards_data(match_id)`
|
|
275
|
+
Every booking with player, minute, and card colour (yellow / red / second_yellow).
|
|
276
|
+
|
|
277
|
+
### Player
|
|
278
|
+
|
|
279
|
+
Every function below takes `player_id` (int).
|
|
280
|
+
|
|
281
|
+
#### `tff.player_data(player_id)`
|
|
282
|
+
Profile: name, birthplace, birthdate, nationality, current licence and club.
|
|
283
|
+
|
|
284
|
+
#### `tff.player_career_data(player_id)`
|
|
285
|
+
Licence history: every licence issue, club, contract dates, licence type.
|
|
286
|
+
|
|
287
|
+
#### `tff.player_national_matches_data(player_id)`
|
|
288
|
+
Every national-team appearance across all Turkey categories (A, U21, U19, etc.).
|
|
289
|
+
|
|
290
|
+
#### `tff.player_goals_data(player_id)`
|
|
291
|
+
Every TFF-recorded goal (club and national) with match, minute, and goal type.
|
|
292
|
+
|
|
293
|
+
#### `tff.player_matches_data(player_id, season)`
|
|
294
|
+
Every club match the player featured in that season.
|
|
295
|
+
- `season` (str): e.g. `"2025-2026"`.
|
|
296
|
+
|
|
297
|
+
#### `tff.player_cards_data(player_id, season)`
|
|
298
|
+
Every yellow / red the player picked up that season.
|
|
299
|
+
- `season` (str): e.g. `"2025-2026"`.
|
|
300
|
+
|
|
301
|
+
## Async API
|
|
302
|
+
|
|
303
|
+
Every function has an async equivalent in `datafc.aio` with the same signature and parameters, designed for `asyncio.gather()`.
|
|
304
|
+
|
|
305
|
+
```python
|
|
306
|
+
import asyncio
|
|
307
|
+
import pandas as pd
|
|
308
|
+
from datafc import aio
|
|
309
|
+
|
|
310
|
+
async def fetch_full_season(tournament_id, season_id, total_weeks):
|
|
311
|
+
tasks = [
|
|
312
|
+
aio.match_data(tournament_id, season_id, week_number=w)
|
|
313
|
+
for w in range(1, total_weeks + 1)
|
|
314
|
+
]
|
|
315
|
+
frames = await asyncio.gather(*tasks)
|
|
316
|
+
return pd.concat(frames, ignore_index=True)
|
|
317
|
+
|
|
318
|
+
df = asyncio.run(fetch_full_season(52, 63814, total_weeks=38))
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
When mixing independent coroutines, pass `return_exceptions=True` so one failure doesn't cancel the rest:
|
|
322
|
+
|
|
323
|
+
```python
|
|
324
|
+
results = await asyncio.gather(
|
|
325
|
+
aio.match_data(52, 77805, week_number=1),
|
|
326
|
+
aio.standings_data(52, 77805),
|
|
327
|
+
return_exceptions=True,
|
|
328
|
+
)
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
## Caching
|
|
332
|
+
|
|
333
|
+
Cache responses to disk to skip repeated API calls across sessions. The same `DiskCache` instance works across all four data sources.
|
|
334
|
+
|
|
335
|
+
```python
|
|
336
|
+
import asyncio
|
|
337
|
+
from datafc import DiskCache, aio
|
|
338
|
+
|
|
339
|
+
cache = DiskCache(cache_dir=".datafc_cache", ttl_hours=24)
|
|
340
|
+
|
|
341
|
+
async def main():
|
|
342
|
+
df = await aio.match_data(52, 63814, week_number=1, cache=cache)
|
|
343
|
+
|
|
344
|
+
asyncio.run(main())
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
`DiskCache` stores responses as JSON files keyed by URL. `ttl_hours=0` disables expiry. `cache.clear()` invalidates every entry.
|
datafc-2.8.0/README.md
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
# datafc v2.8.0
|
|
2
|
+
|
|
3
|
+
`datafc` is a Python package that turns four public football data sources into clean `pandas` DataFrames: **Sofascore** (tournaments, matches, players, shots, lineups, odds), **ClubElo** (club Elo ratings back to 1939), **eloratings.net** (national team Elo ratings back to 1872), and **tff.org** (Turkish Football Federation fixtures, standings, match sheets, and player pages). 59 functions in total, all with the same call style and an async equivalent under `datafc.aio`.
|
|
4
|
+
|
|
5
|
+
## Sofascore
|
|
6
|
+
|
|
7
|
+
Import from top-level `datafc`.
|
|
8
|
+
|
|
9
|
+
### Discovery and Metadata
|
|
10
|
+
|
|
11
|
+
#### `search_data(query, entity_type=None)`
|
|
12
|
+
Search by name.
|
|
13
|
+
- `query` (str): the search term.
|
|
14
|
+
- `entity_type` (str, optional): `"team"`, `"player"`, `"tournament"`, or `"manager"`. `None` returns all types.
|
|
15
|
+
|
|
16
|
+
#### `seasons_data(tournament_id)`
|
|
17
|
+
Lists every season for a tournament.
|
|
18
|
+
- `tournament_id` (int)
|
|
19
|
+
|
|
20
|
+
#### `season_rounds_data(tournament_id, season_id)`
|
|
21
|
+
Lists every matchweek defined for a season.
|
|
22
|
+
- `tournament_id` (int)
|
|
23
|
+
- `season_id` (int)
|
|
24
|
+
|
|
25
|
+
### League / Season
|
|
26
|
+
|
|
27
|
+
#### `standings_data(tournament_id, season_id)`
|
|
28
|
+
League table for Total, Home, and Away categories.
|
|
29
|
+
- `tournament_id` (int)
|
|
30
|
+
- `season_id` (int)
|
|
31
|
+
|
|
32
|
+
#### `team_data(standings_df)`
|
|
33
|
+
Team profiles: stadium, kit colors, manager, venue capacity.
|
|
34
|
+
- `standings_df` (DataFrame): output of `standings_data`.
|
|
35
|
+
|
|
36
|
+
#### `team_stats_data(standings_df, tournament_id, season_id, season=None)`
|
|
37
|
+
Season-level team statistics (long format).
|
|
38
|
+
- `standings_df` (DataFrame)
|
|
39
|
+
- `tournament_id` (int)
|
|
40
|
+
- `season_id` (int)
|
|
41
|
+
- `season` (str, optional): human-readable label used only in the export filename.
|
|
42
|
+
|
|
43
|
+
#### `team_transfers_data(standings_df)`
|
|
44
|
+
All incoming and outgoing transfer records per team.
|
|
45
|
+
- `standings_df` (DataFrame)
|
|
46
|
+
|
|
47
|
+
#### `player_stats_data(standings_df, tournament_id, season_id)`
|
|
48
|
+
Top player statistics per team (long format).
|
|
49
|
+
- `standings_df` (DataFrame)
|
|
50
|
+
- `tournament_id` (int)
|
|
51
|
+
- `season_id` (int)
|
|
52
|
+
|
|
53
|
+
#### `squad_data(standings_df)`
|
|
54
|
+
Squad roster: age, height, position, preferred foot, contract expiry, market value.
|
|
55
|
+
- `standings_df` (DataFrame)
|
|
56
|
+
|
|
57
|
+
#### `upcoming_matches_data(standings_df)`
|
|
58
|
+
Upcoming fixtures for every team in the standings.
|
|
59
|
+
- `standings_df` (DataFrame)
|
|
60
|
+
|
|
61
|
+
#### `team_match_history_data(team_id)`
|
|
62
|
+
Full match history for a single team across all competitions.
|
|
63
|
+
- `team_id` (int): from `standings_data`, `squad_data`, or `search_data`.
|
|
64
|
+
|
|
65
|
+
#### `league_player_stats_data(tournament_id, season_id, order="-rating", accumulation="total", fields=None, position=None, max_players=100)`
|
|
66
|
+
Wide-format player rankings across an entire league.
|
|
67
|
+
- `tournament_id` (int)
|
|
68
|
+
- `season_id` (int)
|
|
69
|
+
- `order` (str): field to sort by; prefix with `-` for descending.
|
|
70
|
+
- `accumulation` (str): `"total"`, `"per90"`, or `"perMatch"`.
|
|
71
|
+
- `fields` (list, optional): stat columns to include. `None` uses 14 defaults.
|
|
72
|
+
- `position` (str, optional): `"G"`, `"D"`, `"M"`, or `"F"`.
|
|
73
|
+
- `max_players` (int): paginates as needed.
|
|
74
|
+
|
|
75
|
+
Available fields: `goals`, `assists`, `rating`, `expectedGoals`, `expectedAssists`, `goalsAssistsSum`, `penaltyGoals`, `freeKickGoal`, `scoringFrequency`, `totalShots`, `shotsOnTarget`, `bigChancesCreated`, `bigChancesMissed`, `accuratePasses`, `accuratePassesPercentage`, `keyPasses`, `accurateLongBalls`, `accurateLongBallsPercentage`, `successfulDribbles`, `successfulDribblesPercentage`, `tackles`, `interceptions`, `clearances`, `possessionLost`, `yellowCards`, `redCards`, `saves`, `goalsPrevented`, `minutesPlayed`, `appearances`.
|
|
76
|
+
|
|
77
|
+
### Match
|
|
78
|
+
|
|
79
|
+
#### `match_data(tournament_id, season_id, week_number=None, tournament_type=None, tournament_stage=None)`
|
|
80
|
+
Fixtures and scores for a matchweek or tournament stage.
|
|
81
|
+
- `tournament_id` (int)
|
|
82
|
+
- `season_id` (int)
|
|
83
|
+
- `week_number` (int, optional): required for league rounds, UEFA stages, `world_cup` + `group_stage_week`, and every `league_playoff` stage. Not needed for World Cup knockouts.
|
|
84
|
+
- `tournament_type` (str, optional): `"uefa"`, `"world_cup"`, or `"league_playoff"`. `None` assumes a domestic league.
|
|
85
|
+
- `tournament_stage` (str, optional): required when `tournament_type` is set.
|
|
86
|
+
- `"uefa"`: `preliminary_semifinals`, `preliminary_final`, `qualification_round`, `qualification_playoff`, `group_stage_week`, `playoff_round`, `round_of_16`, `quarterfinals`, `semifinals`, `match_for_3rd_place`, `final`.
|
|
87
|
+
- `"world_cup"`: `group_stage_week`, `round_of_32`, `round_of_16`, `quarterfinals`, `semifinals`, `match_for_3rd_place`, `final`.
|
|
88
|
+
- `"league_playoff"`: `qualification_round`, `quarterfinals`, `semifinals`, `final`.
|
|
89
|
+
|
|
90
|
+
The match functions below (except `coordinates_data`) all take `match_df` as their only argument.
|
|
91
|
+
|
|
92
|
+
#### `match_details_data(match_df)`
|
|
93
|
+
Referee info (name, cards, career games) and venue details per match.
|
|
94
|
+
|
|
95
|
+
#### `formations_data(match_df)`
|
|
96
|
+
Home and away formation string (e.g. `4-3-3`).
|
|
97
|
+
|
|
98
|
+
#### `match_stats_data(match_df)`
|
|
99
|
+
Team stats per match (possession, shots, fouls, per period).
|
|
100
|
+
|
|
101
|
+
#### `match_odds_data(match_df)`
|
|
102
|
+
Pre-match and live 1/X/2 betting odds.
|
|
103
|
+
|
|
104
|
+
#### `match_h2h_data(match_df)`
|
|
105
|
+
All-time head-to-head record between the two teams.
|
|
106
|
+
|
|
107
|
+
#### `momentum_data(match_df)`
|
|
108
|
+
Minute-by-minute momentum score (positive: home; negative: away).
|
|
109
|
+
|
|
110
|
+
#### `pregame_form_data(match_df)`
|
|
111
|
+
Last 5 results, average rating, league position, and squad value before the match for each side.
|
|
112
|
+
|
|
113
|
+
#### `shots_data(match_df)`
|
|
114
|
+
Every shot event with coordinates, xG, xGOT, body part, situation, and goal mouth location.
|
|
115
|
+
|
|
116
|
+
#### `lineups_data(match_df)`
|
|
117
|
+
Starting XI and substitutes plus per-match player stats (long format).
|
|
118
|
+
|
|
119
|
+
#### `substitutions_data(match_df)`
|
|
120
|
+
Substitution events with minute, player in, player out.
|
|
121
|
+
|
|
122
|
+
#### `incidents_data(match_df)`
|
|
123
|
+
Goals, cards, and VAR decisions per match.
|
|
124
|
+
|
|
125
|
+
#### `average_positions_data(match_df)`
|
|
126
|
+
Each player's average pitch position (X/Y on a 0 to 100 scale).
|
|
127
|
+
|
|
128
|
+
#### `goal_networks_data(match_df)`
|
|
129
|
+
Coordinates for every action in a goal-scoring sequence (passes, shots, goalkeeper position).
|
|
130
|
+
|
|
131
|
+
#### `past_matches_data(tournament_id, season_id, week_number=None, tournament_type=None, tournament_stage=None)`
|
|
132
|
+
Full head-to-head history for every team pair in the given matchweek. Same signature and stage options as `match_data`.
|
|
133
|
+
|
|
134
|
+
#### `coordinates_data(lineups_df)`
|
|
135
|
+
Heatmap touch coordinates per player.
|
|
136
|
+
- `lineups_df` (DataFrame): output of `lineups_data`.
|
|
137
|
+
|
|
138
|
+
### Player
|
|
139
|
+
|
|
140
|
+
Every function below takes `squad_df` (output of `squad_data`) as its only argument.
|
|
141
|
+
|
|
142
|
+
#### `player_data(squad_df)`
|
|
143
|
+
Player profile: nationality, date of birth, height, weight, preferred foot, jersey number, position, market value.
|
|
144
|
+
|
|
145
|
+
#### `player_attribute_overviews_data(squad_df)`
|
|
146
|
+
Radar attribute snapshots (attacking, technical, tactical, defending, creativity) per player, with the position-average baseline and previous-year snapshots.
|
|
147
|
+
|
|
148
|
+
#### `player_transfers_data(squad_df)`
|
|
149
|
+
Transfer history per player.
|
|
150
|
+
|
|
151
|
+
#### `player_career_stats_data(squad_df)`
|
|
152
|
+
Season-by-season career stats across all competitions (long format, `overall` entries only).
|
|
153
|
+
|
|
154
|
+
#### `player_national_team_data(squad_df)`
|
|
155
|
+
National team career: appearances, goals, debut date.
|
|
156
|
+
|
|
157
|
+
#### `player_match_log_data(squad_df)`
|
|
158
|
+
Match-by-match in-game stats across every recorded match (wide format).
|
|
159
|
+
|
|
160
|
+
### Referee
|
|
161
|
+
|
|
162
|
+
#### `referee_stats_data(referee_id)`
|
|
163
|
+
Career stats for a referee (per tournament).
|
|
164
|
+
- `referee_id` (int): from the `referee_id` column of `match_details_data`.
|
|
165
|
+
|
|
166
|
+
## ClubElo
|
|
167
|
+
|
|
168
|
+
Import from `datafc.clubelo`. Club names must match ClubElo's spelling (e.g. `"Man City"`, `"Real Madrid"`, `"Paris SG"`).
|
|
169
|
+
|
|
170
|
+
#### `clubelo.daily_ranking_data(date)`
|
|
171
|
+
Full ClubElo ranking for a given calendar day.
|
|
172
|
+
- `date` (str or `datetime.date`): `"YYYY-MM-DD"` or a `date` object.
|
|
173
|
+
|
|
174
|
+
#### `clubelo.club_history_data(club)`
|
|
175
|
+
Complete Elo rating history for a single club (values before 1960 are provisional).
|
|
176
|
+
- `club` (str): the ClubElo spelling.
|
|
177
|
+
|
|
178
|
+
#### `clubelo.fixtures_data()`
|
|
179
|
+
Per-goal-difference and exact-result probabilities for upcoming matches. No arguments.
|
|
180
|
+
|
|
181
|
+
## EloRatings (National Teams)
|
|
182
|
+
|
|
183
|
+
Import from `datafc.eloratings`. Country arguments are page slugs, not ISO codes (e.g. `"Czech_Republic"`, `"United_States"`).
|
|
184
|
+
|
|
185
|
+
#### `eloratings.world_ranking_data()`
|
|
186
|
+
Current global Elo ranking for every national team.
|
|
187
|
+
|
|
188
|
+
#### `eloratings.country_matches_data(country)`
|
|
189
|
+
Complete international match history for one national team.
|
|
190
|
+
- `country` (str): the page slug used on eloratings.net.
|
|
191
|
+
|
|
192
|
+
#### `eloratings.country_codes_data()`
|
|
193
|
+
Country code to English country name lookup.
|
|
194
|
+
|
|
195
|
+
#### `eloratings.tournament_codes_data()`
|
|
196
|
+
Tournament code to English tournament name lookup.
|
|
197
|
+
|
|
198
|
+
#### `eloratings.tournament_editions_data()`
|
|
199
|
+
Every tournament edition with start/end dates and page slug.
|
|
200
|
+
|
|
201
|
+
#### `eloratings.tournament_groups_data()`
|
|
202
|
+
Specific tournament code to broader group code (e.g. every WC qualifier variant to `WQT`).
|
|
203
|
+
|
|
204
|
+
#### `eloratings.teams_data()`
|
|
205
|
+
Legacy/historical country code to ISO code mapping.
|
|
206
|
+
|
|
207
|
+
## TFF (Turkish Football Federation)
|
|
208
|
+
|
|
209
|
+
Import from `datafc.tff`. Covers Süper Lig, 1. Lig, 2. Lig, 3. Lig.
|
|
210
|
+
|
|
211
|
+
### Fixtures, Standings, Club
|
|
212
|
+
|
|
213
|
+
#### `tff.fixtures_data(page_id, week=None, group=None, playoff=False, round=None)`
|
|
214
|
+
Weekly fixtures or the promotion play-off bracket.
|
|
215
|
+
- `page_id` (int): the `pageID` query parameter from the tff.org fixture URL.
|
|
216
|
+
- `week` (int, optional): matchweek number.
|
|
217
|
+
- `group` (str, optional): 2. Lig (`"Kırmızı"` / `"Beyaz"`) or 3. Lig (`"01"` to `"04"`); case-insensitive.
|
|
218
|
+
- `playoff` (bool): `True` returns the 1./2./3. Lig play-off bracket with extra-time and penalty-shootout scores.
|
|
219
|
+
- `round` (str, optional): filter play-off rounds (e.g. `"Final"`).
|
|
220
|
+
|
|
221
|
+
#### `tff.standings_data(page_id, week, group=None)`
|
|
222
|
+
League table as of a matchweek.
|
|
223
|
+
- `page_id` (int)
|
|
224
|
+
- `week` (int)
|
|
225
|
+
- `group` (str, optional): required for 2. Lig and 3. Lig.
|
|
226
|
+
|
|
227
|
+
#### `tff.team_data(club_id)`
|
|
228
|
+
Club profile: official (unsponsored) name, address, president, plus stadium info.
|
|
229
|
+
- `club_id` (int)
|
|
230
|
+
|
|
231
|
+
### Match Sheet
|
|
232
|
+
|
|
233
|
+
Every function below takes `match_id` (int) as its only argument.
|
|
234
|
+
|
|
235
|
+
#### `tff.match_details_data(match_id)`
|
|
236
|
+
Match header (teams, score, stadium, tournament) plus every assigned official.
|
|
237
|
+
|
|
238
|
+
#### `tff.match_lineups_data(match_id)`
|
|
239
|
+
Starting XI and bench for both teams (jersey number, player id, player name).
|
|
240
|
+
|
|
241
|
+
#### `tff.match_staff_data(match_id)`
|
|
242
|
+
Head coach for both teams (coach id and name).
|
|
243
|
+
|
|
244
|
+
#### `tff.match_goals_data(match_id)`
|
|
245
|
+
Every goal with scorer, minute, and TFF code (`F` foot, `H` header, `P` penalty, `K` free kick, `KG` own goal).
|
|
246
|
+
|
|
247
|
+
#### `tff.match_cards_data(match_id)`
|
|
248
|
+
Every booking with player, minute, and card colour (yellow / red / second_yellow).
|
|
249
|
+
|
|
250
|
+
### Player
|
|
251
|
+
|
|
252
|
+
Every function below takes `player_id` (int).
|
|
253
|
+
|
|
254
|
+
#### `tff.player_data(player_id)`
|
|
255
|
+
Profile: name, birthplace, birthdate, nationality, current licence and club.
|
|
256
|
+
|
|
257
|
+
#### `tff.player_career_data(player_id)`
|
|
258
|
+
Licence history: every licence issue, club, contract dates, licence type.
|
|
259
|
+
|
|
260
|
+
#### `tff.player_national_matches_data(player_id)`
|
|
261
|
+
Every national-team appearance across all Turkey categories (A, U21, U19, etc.).
|
|
262
|
+
|
|
263
|
+
#### `tff.player_goals_data(player_id)`
|
|
264
|
+
Every TFF-recorded goal (club and national) with match, minute, and goal type.
|
|
265
|
+
|
|
266
|
+
#### `tff.player_matches_data(player_id, season)`
|
|
267
|
+
Every club match the player featured in that season.
|
|
268
|
+
- `season` (str): e.g. `"2025-2026"`.
|
|
269
|
+
|
|
270
|
+
#### `tff.player_cards_data(player_id, season)`
|
|
271
|
+
Every yellow / red the player picked up that season.
|
|
272
|
+
- `season` (str): e.g. `"2025-2026"`.
|
|
273
|
+
|
|
274
|
+
## Async API
|
|
275
|
+
|
|
276
|
+
Every function has an async equivalent in `datafc.aio` with the same signature and parameters, designed for `asyncio.gather()`.
|
|
277
|
+
|
|
278
|
+
```python
|
|
279
|
+
import asyncio
|
|
280
|
+
import pandas as pd
|
|
281
|
+
from datafc import aio
|
|
282
|
+
|
|
283
|
+
async def fetch_full_season(tournament_id, season_id, total_weeks):
|
|
284
|
+
tasks = [
|
|
285
|
+
aio.match_data(tournament_id, season_id, week_number=w)
|
|
286
|
+
for w in range(1, total_weeks + 1)
|
|
287
|
+
]
|
|
288
|
+
frames = await asyncio.gather(*tasks)
|
|
289
|
+
return pd.concat(frames, ignore_index=True)
|
|
290
|
+
|
|
291
|
+
df = asyncio.run(fetch_full_season(52, 63814, total_weeks=38))
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
When mixing independent coroutines, pass `return_exceptions=True` so one failure doesn't cancel the rest:
|
|
295
|
+
|
|
296
|
+
```python
|
|
297
|
+
results = await asyncio.gather(
|
|
298
|
+
aio.match_data(52, 77805, week_number=1),
|
|
299
|
+
aio.standings_data(52, 77805),
|
|
300
|
+
return_exceptions=True,
|
|
301
|
+
)
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## Caching
|
|
305
|
+
|
|
306
|
+
Cache responses to disk to skip repeated API calls across sessions. The same `DiskCache` instance works across all four data sources.
|
|
307
|
+
|
|
308
|
+
```python
|
|
309
|
+
import asyncio
|
|
310
|
+
from datafc import DiskCache, aio
|
|
311
|
+
|
|
312
|
+
cache = DiskCache(cache_dir=".datafc_cache", ttl_hours=24)
|
|
313
|
+
|
|
314
|
+
async def main():
|
|
315
|
+
df = await aio.match_data(52, 63814, week_number=1, cache=cache)
|
|
316
|
+
|
|
317
|
+
asyncio.run(main())
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
`DiskCache` stores responses as JSON files keyed by URL. `ttl_hours=0` disables expiry. `cache.clear()` invalidates every entry.
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
__version__ = "2.
|
|
1
|
+
__version__ = "2.8.0"
|
|
2
2
|
|
|
3
3
|
from .sofascore import *
|
|
4
4
|
from . import clubelo
|
|
5
5
|
from . import eloratings
|
|
6
|
+
from . import tff
|
|
6
7
|
from .exceptions import (
|
|
7
8
|
DataFCError,
|
|
8
9
|
InvalidParameterError,
|
|
@@ -67,6 +68,8 @@ __all__ = [
|
|
|
67
68
|
"clubelo",
|
|
68
69
|
# EloRatings subpackage
|
|
69
70
|
"eloratings",
|
|
71
|
+
# TFF subpackage
|
|
72
|
+
"tff",
|
|
70
73
|
# Exceptions
|
|
71
74
|
"DataFCError",
|
|
72
75
|
"InvalidParameterError",
|