datafc 2.5.0__tar.gz → 2.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {datafc-2.5.0 → datafc-2.6.0}/PKG-INFO +37 -3
- {datafc-2.5.0 → datafc-2.6.0}/README.md +36 -2
- {datafc-2.5.0 → datafc-2.6.0}/datafc/__init__.py +2 -1
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/__init__.py +2 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/_parsers.py +18 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/aio.py +23 -0
- datafc-2.6.0/datafc/sofascore/fetch_formations_data.py +44 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc.egg-info/PKG-INFO +37 -3
- {datafc-2.5.0 → datafc-2.6.0}/datafc.egg-info/SOURCES.txt +1 -0
- {datafc-2.5.0 → datafc-2.6.0}/pyproject.toml +1 -1
- {datafc-2.5.0 → datafc-2.6.0}/LICENSE +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/exceptions.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/_core.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_average_positions_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_coordinates_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_goal_networks_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_incidents_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_league_player_stats_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_lineups_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_match_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_match_details_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_match_h2h_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_match_odds_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_match_stats_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_momentum_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_past_matches_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_player_attribute_overviews_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_player_career_stats_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_player_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_player_match_log_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_player_national_team_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_player_stats_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_player_transfers_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_pregame_form_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_referee_stats_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_search_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_season_rounds_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_seasons_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_shots_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_squad_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_standings_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_substitutions_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_team_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_team_match_history_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_team_stats_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_team_transfers_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/sofascore/fetch_upcoming_matches_data.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/utils/__init__.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/utils/_async_client.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/utils/_cache.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/utils/_client.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/utils/_config.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/utils/_helpers.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/utils/_save_files.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/utils/_tournament_info.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc/utils/_validate.py +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc.egg-info/dependency_links.txt +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc.egg-info/requires.txt +0 -0
- {datafc-2.5.0 → datafc-2.6.0}/datafc.egg-info/top_level.txt +0 -0
- {datafc-2.5.0 → datafc-2.6.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.6.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
|
|
@@ -24,16 +24,27 @@ Requires-Dist: pytest>=8.0; extra == "dev"
|
|
|
24
24
|
Requires-Dist: pytest-mock>=3.12; extra == "dev"
|
|
25
25
|
Dynamic: license-file
|
|
26
26
|
|
|
27
|
-
# datafc v2.
|
|
27
|
+
# datafc v2.6.0
|
|
28
28
|
|
|
29
29
|
## Overview
|
|
30
30
|
|
|
31
|
-
`datafc` fetches, processes, and exports structured football data. It provides **
|
|
31
|
+
`datafc` fetches, processes, and exports structured football data. It provides **35 functions** covering tournament metadata, standings, squad rosters, match fixtures, shots, lineups, player heatmaps, odds, and more — all returning clean `pandas` DataFrames ready for analysis. Sofascore is currently the only supported data source.
|
|
32
32
|
|
|
33
33
|
> **Finding IDs:** `tournament_id` and `season_id` can be discovered two ways:
|
|
34
34
|
> - **From the URL:** navigating to a league page on Sofascore (e.g. `sofascore.com/.../trendyol-super-lig/52#id:63814`) shows `tournament_id=52` and `season_id=63814`.
|
|
35
35
|
> - **Programmatically:** use `search_data("super lig", entity_type="tournament")` to find the tournament ID, then `seasons_data(tournament_id)` to list all available seasons.
|
|
36
36
|
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
<p align="center">
|
|
40
|
+
If you find <strong>datafc</strong> useful, consider supporting the project ☕<br><br>
|
|
41
|
+
<a href="https://buymeacoffee.com/urazdev">
|
|
42
|
+
<img src="https://img.shields.io/badge/Buy%20Me%20A%20Coffee-urazdev-%23FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black" alt="Buy Me A Coffee">
|
|
43
|
+
</a>
|
|
44
|
+
</p>
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
37
48
|
## What Data Can You Access?
|
|
38
49
|
|
|
39
50
|
### Discovery
|
|
@@ -69,6 +80,7 @@ Dynamic: license-file
|
|
|
69
80
|
|---|---|
|
|
70
81
|
| `match_data` | Fixtures for a matchweek: score, status, home/away teams |
|
|
71
82
|
| `match_details_data` | Referee info (name, cards, games) and venue details per match |
|
|
83
|
+
| `formations_data` | Home and away formation for each match |
|
|
72
84
|
| `match_stats_data` | Aggregate team stats per match (possession, shots, fouls, …) |
|
|
73
85
|
| `match_odds_data` | Pre-match 1/X/2 betting odds |
|
|
74
86
|
| `match_h2h_data` | All-time H2H record between the two teams |
|
|
@@ -580,6 +592,22 @@ Dependencies: `match_data`
|
|
|
580
592
|
|
|
581
593
|
---
|
|
582
594
|
|
|
595
|
+
#### `formations_data`
|
|
596
|
+
|
|
597
|
+
Fetch home and away formation for each match.
|
|
598
|
+
|
|
599
|
+
```python
|
|
600
|
+
from datafc import formations_data
|
|
601
|
+
|
|
602
|
+
df = formations_data(match_df=match_df)
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
Columns: `country`, `tournament`, `season`, `week`, `game_id`, `team` (`home` / `away`), `formation`.
|
|
606
|
+
|
|
607
|
+
Dependencies: `match_data`
|
|
608
|
+
|
|
609
|
+
---
|
|
610
|
+
|
|
583
611
|
#### `match_stats_data`
|
|
584
612
|
|
|
585
613
|
Fetch aggregate team statistics (possession, shots, passes, etc.) for each match.
|
|
@@ -935,6 +963,12 @@ Columns: `referee_id`, `referee_name`, `tournament_id`, `tournament_name`, `stat
|
|
|
935
963
|
|
|
936
964
|
## What's new
|
|
937
965
|
|
|
966
|
+
### v2.6.0
|
|
967
|
+
|
|
968
|
+
- **New function: `formations_data`** — fetches home and away formation for each match. Returns two rows per match (`team`: `home` / `away`) with the formation string (e.g. `4-3-3`).
|
|
969
|
+
|
|
970
|
+
---
|
|
971
|
+
|
|
938
972
|
### v2.5.0
|
|
939
973
|
|
|
940
974
|
- **`player_data` now returns `position_detailed`.** New column containing Sofascore's detailed position list (e.g. `["AM", "MC", "RW"]`) alongside the existing single `position` field.
|
|
@@ -1,13 +1,24 @@
|
|
|
1
|
-
# datafc v2.
|
|
1
|
+
# datafc v2.6.0
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
|
-
`datafc` fetches, processes, and exports structured football data. It provides **
|
|
5
|
+
`datafc` fetches, processes, and exports structured football data. It provides **35 functions** covering tournament metadata, standings, squad rosters, match fixtures, shots, lineups, player heatmaps, odds, and more — all returning clean `pandas` DataFrames ready for analysis. Sofascore is currently the only supported data source.
|
|
6
6
|
|
|
7
7
|
> **Finding IDs:** `tournament_id` and `season_id` can be discovered two ways:
|
|
8
8
|
> - **From the URL:** navigating to a league page on Sofascore (e.g. `sofascore.com/.../trendyol-super-lig/52#id:63814`) shows `tournament_id=52` and `season_id=63814`.
|
|
9
9
|
> - **Programmatically:** use `search_data("super lig", entity_type="tournament")` to find the tournament ID, then `seasons_data(tournament_id)` to list all available seasons.
|
|
10
10
|
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
<p align="center">
|
|
14
|
+
If you find <strong>datafc</strong> useful, consider supporting the project ☕<br><br>
|
|
15
|
+
<a href="https://buymeacoffee.com/urazdev">
|
|
16
|
+
<img src="https://img.shields.io/badge/Buy%20Me%20A%20Coffee-urazdev-%23FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black" alt="Buy Me A Coffee">
|
|
17
|
+
</a>
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
11
22
|
## What Data Can You Access?
|
|
12
23
|
|
|
13
24
|
### Discovery
|
|
@@ -43,6 +54,7 @@
|
|
|
43
54
|
|---|---|
|
|
44
55
|
| `match_data` | Fixtures for a matchweek: score, status, home/away teams |
|
|
45
56
|
| `match_details_data` | Referee info (name, cards, games) and venue details per match |
|
|
57
|
+
| `formations_data` | Home and away formation for each match |
|
|
46
58
|
| `match_stats_data` | Aggregate team stats per match (possession, shots, fouls, …) |
|
|
47
59
|
| `match_odds_data` | Pre-match 1/X/2 betting odds |
|
|
48
60
|
| `match_h2h_data` | All-time H2H record between the two teams |
|
|
@@ -554,6 +566,22 @@ Dependencies: `match_data`
|
|
|
554
566
|
|
|
555
567
|
---
|
|
556
568
|
|
|
569
|
+
#### `formations_data`
|
|
570
|
+
|
|
571
|
+
Fetch home and away formation for each match.
|
|
572
|
+
|
|
573
|
+
```python
|
|
574
|
+
from datafc import formations_data
|
|
575
|
+
|
|
576
|
+
df = formations_data(match_df=match_df)
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
Columns: `country`, `tournament`, `season`, `week`, `game_id`, `team` (`home` / `away`), `formation`.
|
|
580
|
+
|
|
581
|
+
Dependencies: `match_data`
|
|
582
|
+
|
|
583
|
+
---
|
|
584
|
+
|
|
557
585
|
#### `match_stats_data`
|
|
558
586
|
|
|
559
587
|
Fetch aggregate team statistics (possession, shots, passes, etc.) for each match.
|
|
@@ -909,6 +937,12 @@ Columns: `referee_id`, `referee_name`, `tournament_id`, `tournament_name`, `stat
|
|
|
909
937
|
|
|
910
938
|
## What's new
|
|
911
939
|
|
|
940
|
+
### v2.6.0
|
|
941
|
+
|
|
942
|
+
- **New function: `formations_data`** — fetches home and away formation for each match. Returns two rows per match (`team`: `home` / `away`) with the formation string (e.g. `4-3-3`).
|
|
943
|
+
|
|
944
|
+
---
|
|
945
|
+
|
|
912
946
|
### v2.5.0
|
|
913
947
|
|
|
914
948
|
- **`player_data` now returns `position_detailed`.** New column containing Sofascore's detailed position list (e.g. `["AM", "MC", "RW"]`) alongside the existing single `position` field.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
__version__ = "2.
|
|
1
|
+
__version__ = "2.6.0"
|
|
2
2
|
|
|
3
3
|
from .sofascore import *
|
|
4
4
|
from .exceptions import (
|
|
@@ -36,6 +36,7 @@ __all__ = [
|
|
|
36
36
|
# Matchweek
|
|
37
37
|
"match_data",
|
|
38
38
|
"match_details_data",
|
|
39
|
+
"formations_data",
|
|
39
40
|
"match_stats_data",
|
|
40
41
|
"match_odds_data",
|
|
41
42
|
"match_h2h_data",
|
|
@@ -3,6 +3,7 @@ from .fetch_match_stats_data import match_stats_data
|
|
|
3
3
|
from .fetch_standings_data import standings_data
|
|
4
4
|
from .fetch_shots_data import shots_data
|
|
5
5
|
from .fetch_goal_networks_data import goal_networks_data
|
|
6
|
+
from .fetch_formations_data import formations_data
|
|
6
7
|
from .fetch_lineups_data import lineups_data
|
|
7
8
|
from .fetch_coordinates_data import coordinates_data
|
|
8
9
|
from .fetch_substitutions_data import substitutions_data
|
|
@@ -47,6 +48,7 @@ __all__ = [
|
|
|
47
48
|
"substitutions_data",
|
|
48
49
|
"incidents_data",
|
|
49
50
|
"match_details_data",
|
|
51
|
+
"formations_data",
|
|
50
52
|
"upcoming_matches_data",
|
|
51
53
|
"team_match_history_data",
|
|
52
54
|
"goal_networks_data",
|
|
@@ -162,6 +162,24 @@ def parse_momentum_records(
|
|
|
162
162
|
]
|
|
163
163
|
|
|
164
164
|
|
|
165
|
+
def parse_formations_records(
|
|
166
|
+
data: dict, country: str, tournament: str, season, week, game_id
|
|
167
|
+
) -> list:
|
|
168
|
+
"""Extract home and away formation records from a single event's lineups response."""
|
|
169
|
+
records = []
|
|
170
|
+
for team_key in ("home", "away"):
|
|
171
|
+
team_data = data.get(team_key, {})
|
|
172
|
+
formation = team_data.get("formation")
|
|
173
|
+
if formation is not None:
|
|
174
|
+
records.append({
|
|
175
|
+
"country": country, "tournament": tournament,
|
|
176
|
+
"season": season, "week": week, "game_id": game_id,
|
|
177
|
+
"team": team_key,
|
|
178
|
+
"formation": formation,
|
|
179
|
+
})
|
|
180
|
+
return records
|
|
181
|
+
|
|
182
|
+
|
|
165
183
|
def parse_lineups_records(
|
|
166
184
|
data: dict, country: str, tournament: str, season, week, game_id
|
|
167
185
|
) -> list:
|
|
@@ -57,6 +57,7 @@ from datafc.sofascore._core import (
|
|
|
57
57
|
)
|
|
58
58
|
from datafc.sofascore._parsers import (
|
|
59
59
|
parse_average_positions_records,
|
|
60
|
+
parse_formations_records,
|
|
60
61
|
parse_incidents_records,
|
|
61
62
|
parse_league_player_stats_records,
|
|
62
63
|
parse_lineups_records,
|
|
@@ -236,6 +237,28 @@ async def momentum_data(
|
|
|
236
237
|
)
|
|
237
238
|
|
|
238
239
|
|
|
240
|
+
async def formations_data(
|
|
241
|
+
match_df: pd.DataFrame,
|
|
242
|
+
data_source: str = "sofascore",
|
|
243
|
+
rate_limit: float = 2.0,
|
|
244
|
+
cache: Optional[DiskCache] = None,
|
|
245
|
+
enable_json_export: bool = False,
|
|
246
|
+
enable_excel_export: bool = False,
|
|
247
|
+
output_dir: str = ".",
|
|
248
|
+
) -> pd.DataFrame:
|
|
249
|
+
"""Async version of formations_data()."""
|
|
250
|
+
return await _per_match_simple(
|
|
251
|
+
match_df, data_source, rate_limit, cache,
|
|
252
|
+
endpoint="{base}/api/v1/event/{game_id}/lineups",
|
|
253
|
+
parser=parse_formations_records,
|
|
254
|
+
log_label="formations",
|
|
255
|
+
fn_name="formations_data",
|
|
256
|
+
error_msg="No formation data found.",
|
|
257
|
+
enable_json_export=enable_json_export, enable_excel_export=enable_excel_export,
|
|
258
|
+
output_dir=output_dir,
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
|
|
239
262
|
async def lineups_data(
|
|
240
263
|
match_df: pd.DataFrame,
|
|
241
264
|
data_source: str = "sofascore",
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, Optional
|
|
2
|
+
import pandas as pd
|
|
3
|
+
from datafc.utils._client import SofascoreClient
|
|
4
|
+
from datafc.utils._validate import validate_source, validate_df
|
|
5
|
+
from datafc.sofascore._parsers import parse_formations_records
|
|
6
|
+
from datafc.sofascore._core import iter_per_match_sync, export_df
|
|
7
|
+
from datafc.exceptions import DataNotAvailableError
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from datafc.utils._cache import DiskCache
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def formations_data(
|
|
14
|
+
match_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 home and away formation for each match. Two rows per match."""
|
|
23
|
+
validate_source(data_source)
|
|
24
|
+
validate_df(match_df, "match_df")
|
|
25
|
+
|
|
26
|
+
with SofascoreClient(rate_limit=rate_limit, cache=cache) as client:
|
|
27
|
+
records = iter_per_match_sync(
|
|
28
|
+
match_df, client,
|
|
29
|
+
data_source=data_source,
|
|
30
|
+
endpoint="{base}/api/v1/event/{game_id}/lineups",
|
|
31
|
+
parser=parse_formations_records,
|
|
32
|
+
log_label="formations",
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
result_df = pd.DataFrame(records)
|
|
36
|
+
if result_df.empty:
|
|
37
|
+
raise DataNotAvailableError("No formation data found for the specified parameters.")
|
|
38
|
+
|
|
39
|
+
export_df(
|
|
40
|
+
result_df, fn_name="formations_data", data_source=data_source,
|
|
41
|
+
output_dir=output_dir,
|
|
42
|
+
enable_json_export=enable_json_export, enable_excel_export=enable_excel_export,
|
|
43
|
+
)
|
|
44
|
+
return result_df
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datafc
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.6.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
|
|
@@ -24,16 +24,27 @@ Requires-Dist: pytest>=8.0; extra == "dev"
|
|
|
24
24
|
Requires-Dist: pytest-mock>=3.12; extra == "dev"
|
|
25
25
|
Dynamic: license-file
|
|
26
26
|
|
|
27
|
-
# datafc v2.
|
|
27
|
+
# datafc v2.6.0
|
|
28
28
|
|
|
29
29
|
## Overview
|
|
30
30
|
|
|
31
|
-
`datafc` fetches, processes, and exports structured football data. It provides **
|
|
31
|
+
`datafc` fetches, processes, and exports structured football data. It provides **35 functions** covering tournament metadata, standings, squad rosters, match fixtures, shots, lineups, player heatmaps, odds, and more — all returning clean `pandas` DataFrames ready for analysis. Sofascore is currently the only supported data source.
|
|
32
32
|
|
|
33
33
|
> **Finding IDs:** `tournament_id` and `season_id` can be discovered two ways:
|
|
34
34
|
> - **From the URL:** navigating to a league page on Sofascore (e.g. `sofascore.com/.../trendyol-super-lig/52#id:63814`) shows `tournament_id=52` and `season_id=63814`.
|
|
35
35
|
> - **Programmatically:** use `search_data("super lig", entity_type="tournament")` to find the tournament ID, then `seasons_data(tournament_id)` to list all available seasons.
|
|
36
36
|
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
<p align="center">
|
|
40
|
+
If you find <strong>datafc</strong> useful, consider supporting the project ☕<br><br>
|
|
41
|
+
<a href="https://buymeacoffee.com/urazdev">
|
|
42
|
+
<img src="https://img.shields.io/badge/Buy%20Me%20A%20Coffee-urazdev-%23FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black" alt="Buy Me A Coffee">
|
|
43
|
+
</a>
|
|
44
|
+
</p>
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
37
48
|
## What Data Can You Access?
|
|
38
49
|
|
|
39
50
|
### Discovery
|
|
@@ -69,6 +80,7 @@ Dynamic: license-file
|
|
|
69
80
|
|---|---|
|
|
70
81
|
| `match_data` | Fixtures for a matchweek: score, status, home/away teams |
|
|
71
82
|
| `match_details_data` | Referee info (name, cards, games) and venue details per match |
|
|
83
|
+
| `formations_data` | Home and away formation for each match |
|
|
72
84
|
| `match_stats_data` | Aggregate team stats per match (possession, shots, fouls, …) |
|
|
73
85
|
| `match_odds_data` | Pre-match 1/X/2 betting odds |
|
|
74
86
|
| `match_h2h_data` | All-time H2H record between the two teams |
|
|
@@ -580,6 +592,22 @@ Dependencies: `match_data`
|
|
|
580
592
|
|
|
581
593
|
---
|
|
582
594
|
|
|
595
|
+
#### `formations_data`
|
|
596
|
+
|
|
597
|
+
Fetch home and away formation for each match.
|
|
598
|
+
|
|
599
|
+
```python
|
|
600
|
+
from datafc import formations_data
|
|
601
|
+
|
|
602
|
+
df = formations_data(match_df=match_df)
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
Columns: `country`, `tournament`, `season`, `week`, `game_id`, `team` (`home` / `away`), `formation`.
|
|
606
|
+
|
|
607
|
+
Dependencies: `match_data`
|
|
608
|
+
|
|
609
|
+
---
|
|
610
|
+
|
|
583
611
|
#### `match_stats_data`
|
|
584
612
|
|
|
585
613
|
Fetch aggregate team statistics (possession, shots, passes, etc.) for each match.
|
|
@@ -935,6 +963,12 @@ Columns: `referee_id`, `referee_name`, `tournament_id`, `tournament_name`, `stat
|
|
|
935
963
|
|
|
936
964
|
## What's new
|
|
937
965
|
|
|
966
|
+
### v2.6.0
|
|
967
|
+
|
|
968
|
+
- **New function: `formations_data`** — fetches home and away formation for each match. Returns two rows per match (`team`: `home` / `away`) with the formation string (e.g. `4-3-3`).
|
|
969
|
+
|
|
970
|
+
---
|
|
971
|
+
|
|
938
972
|
### v2.5.0
|
|
939
973
|
|
|
940
974
|
- **`player_data` now returns `position_detailed`.** New column containing Sofascore's detailed position list (e.g. `["AM", "MC", "RW"]`) alongside the existing single `position` field.
|
|
@@ -14,6 +14,7 @@ datafc/sofascore/_parsers.py
|
|
|
14
14
|
datafc/sofascore/aio.py
|
|
15
15
|
datafc/sofascore/fetch_average_positions_data.py
|
|
16
16
|
datafc/sofascore/fetch_coordinates_data.py
|
|
17
|
+
datafc/sofascore/fetch_formations_data.py
|
|
17
18
|
datafc/sofascore/fetch_goal_networks_data.py
|
|
18
19
|
datafc/sofascore/fetch_incidents_data.py
|
|
19
20
|
datafc/sofascore/fetch_league_player_stats_data.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|