rustat-python-api 0.1.1__tar.gz → 0.2.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.
- {rustat-python-api-0.1.1/rustat_python_api.egg-info → rustat-python-api-0.2.0}/PKG-INFO +3 -1
- {rustat-python-api-0.1.1 → rustat-python-api-0.2.0}/README.md +2 -0
- {rustat-python-api-0.1.1 → rustat-python-api-0.2.0}/rustat_python_api/parser.py +54 -8
- {rustat-python-api-0.1.1 → rustat-python-api-0.2.0}/rustat_python_api/urls.py +2 -1
- {rustat-python-api-0.1.1 → rustat-python-api-0.2.0/rustat_python_api.egg-info}/PKG-INFO +3 -1
- {rustat-python-api-0.1.1 → rustat-python-api-0.2.0}/setup.py +1 -1
- {rustat-python-api-0.1.1 → rustat-python-api-0.2.0}/LICENSE +0 -0
- {rustat-python-api-0.1.1 → rustat-python-api-0.2.0}/pyproject.toml +0 -0
- {rustat-python-api-0.1.1 → rustat-python-api-0.2.0}/rustat_python_api/__init__.py +0 -0
- {rustat-python-api-0.1.1 → rustat-python-api-0.2.0}/rustat_python_api.egg-info/SOURCES.txt +0 -0
- {rustat-python-api-0.1.1 → rustat-python-api-0.2.0}/rustat_python_api.egg-info/dependency_links.txt +0 -0
- {rustat-python-api-0.1.1 → rustat-python-api-0.2.0}/rustat_python_api.egg-info/requires.txt +0 -0
- {rustat-python-api-0.1.1 → rustat-python-api-0.2.0}/rustat_python_api.egg-info/top_level.txt +0 -0
- {rustat-python-api-0.1.1 → rustat-python-api-0.2.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: rustat-python-api
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: A Python wrapper for RuStat API
|
|
5
5
|
Home-page: https://github.com/dailydaniel/rustat-python-api
|
|
6
6
|
Author: Daniel Zholkovsky
|
|
@@ -41,4 +41,6 @@ match_id = keys[-1]
|
|
|
41
41
|
events = parser.get_events(match_id)
|
|
42
42
|
|
|
43
43
|
stats = parser.get_match_stats(match_id)
|
|
44
|
+
|
|
45
|
+
tracking = parser.get_tracking(match_id)
|
|
44
46
|
```
|
|
@@ -2,12 +2,19 @@ import requests
|
|
|
2
2
|
import pandas as pd
|
|
3
3
|
from collections import defaultdict
|
|
4
4
|
from tqdm import tqdm
|
|
5
|
+
import time
|
|
5
6
|
|
|
6
7
|
from .urls import URLs
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class RuStatParser:
|
|
10
|
-
def __init__(
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
user: str,
|
|
14
|
+
password: str,
|
|
15
|
+
urls: dict = URLs,
|
|
16
|
+
sleep: int = -1
|
|
17
|
+
):
|
|
11
18
|
self.numeric_columns = [
|
|
12
19
|
'id', 'number', 'player_id', 'team_id', 'half', 'second',
|
|
13
20
|
'pos_x', 'pos_y', 'pos_dest_x', 'pos_dest_y', 'len', 'possession_id', 'possession_team_id',
|
|
@@ -17,18 +24,23 @@ class RuStatParser:
|
|
|
17
24
|
|
|
18
25
|
self.user = user
|
|
19
26
|
self.password = password
|
|
27
|
+
self.urls = urls
|
|
28
|
+
self.sleep = sleep
|
|
20
29
|
|
|
21
30
|
self.cached_info = {}
|
|
22
31
|
|
|
23
|
-
|
|
24
|
-
|
|
32
|
+
def resp2data(self, query: str) -> dict:
|
|
33
|
+
|
|
34
|
+
if self.sleep > 0:
|
|
35
|
+
time.sleep(self.sleep)
|
|
36
|
+
|
|
25
37
|
response = requests.get(query)
|
|
26
38
|
return response.json()
|
|
27
39
|
|
|
28
40
|
def get_rpl_info(self):
|
|
29
41
|
for season_id in tqdm(range(1, 36)):
|
|
30
42
|
data = self.resp2data(
|
|
31
|
-
|
|
43
|
+
self.urls["tournament_teams"].format(
|
|
32
44
|
user=self.user,
|
|
33
45
|
password=self.password,
|
|
34
46
|
season_id=season_id
|
|
@@ -38,7 +50,7 @@ class RuStatParser:
|
|
|
38
50
|
if data:
|
|
39
51
|
first_team_id = data["data"]["row"][0]["id"]
|
|
40
52
|
first_team_schedule = self.resp2data(
|
|
41
|
-
|
|
53
|
+
self.urls["schedule"].format(
|
|
42
54
|
user=self.user,
|
|
43
55
|
password=self.password,
|
|
44
56
|
team_id=first_team_id,
|
|
@@ -61,7 +73,7 @@ class RuStatParser:
|
|
|
61
73
|
|
|
62
74
|
def get_schedule(self, team_id: str, season_id: str) -> dict:
|
|
63
75
|
data = self.resp2data(
|
|
64
|
-
|
|
76
|
+
self.urls["schedule"].format(
|
|
65
77
|
user=self.user,
|
|
66
78
|
password=self.password,
|
|
67
79
|
team_id=team_id,
|
|
@@ -85,7 +97,7 @@ class RuStatParser:
|
|
|
85
97
|
|
|
86
98
|
def get_events(self, match_id: int) -> pd.DataFrame | None:
|
|
87
99
|
data = self.resp2data(
|
|
88
|
-
|
|
100
|
+
self.urls["events"].format(
|
|
89
101
|
user=self.user,
|
|
90
102
|
password=self.password,
|
|
91
103
|
match_id=match_id
|
|
@@ -102,9 +114,43 @@ class RuStatParser:
|
|
|
102
114
|
|
|
103
115
|
return df
|
|
104
116
|
|
|
117
|
+
def get_tracking(self, match_id: int) -> pd.DataFrame | None:
|
|
118
|
+
data = self.resp2data(
|
|
119
|
+
self.urls["tracking"].format(
|
|
120
|
+
user=self.user,
|
|
121
|
+
password=self.password,
|
|
122
|
+
match_id=match_id
|
|
123
|
+
)
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
if not data:
|
|
127
|
+
return None
|
|
128
|
+
|
|
129
|
+
data = data["data"]["team"]
|
|
130
|
+
df = pd.DataFrame(columns=["half", "second", "pos_x", "pos_y", "team_id", "player_id", "player_name", "side_1h"])
|
|
131
|
+
|
|
132
|
+
for team_data in tqdm(data):
|
|
133
|
+
team_id = team_data["id"]
|
|
134
|
+
side_1h = team_data["gate_position_half_1"]
|
|
135
|
+
|
|
136
|
+
for player_data in team_data["player"]:
|
|
137
|
+
player_id = player_data["id"]
|
|
138
|
+
player_name = player_data["name"]
|
|
139
|
+
|
|
140
|
+
cur_df = pd.json_normalize(player_data["row"])
|
|
141
|
+
cur_df = cur_df.apply(pd.to_numeric, errors='coerce')
|
|
142
|
+
cur_df["team_id"] = team_id
|
|
143
|
+
cur_df["player_id"] = player_id
|
|
144
|
+
cur_df["player_name"] = player_name
|
|
145
|
+
cur_df["side_1h"] = side_1h
|
|
146
|
+
|
|
147
|
+
df = pd.concat([df, cur_df], ignore_index=True)
|
|
148
|
+
|
|
149
|
+
return df.sort_values(by=["second", "team_id", "player_id"])
|
|
150
|
+
|
|
105
151
|
def get_match_stats(self, match_id: int) -> dict:
|
|
106
152
|
data = self.resp2data(
|
|
107
|
-
|
|
153
|
+
self.urls["match_stats"].format(
|
|
108
154
|
user=self.user,
|
|
109
155
|
password=self.password,
|
|
110
156
|
match_id=match_id
|
|
@@ -2,5 +2,6 @@ URLs = {
|
|
|
2
2
|
"schedule": "http://feeds.rustatsport.ru/?tpl=35&user={user}&key={password}&team_id={team_id}&season_id={season_id}&date_start=&date_end=&format=json",
|
|
3
3
|
"events": "http://feeds.rustatsport.ru/?tpl=36&user={user}&key={password}&match_id={match_id}&start_ms=0&dl=0&lang_id=1&format=json",
|
|
4
4
|
"match_stats": "http://feeds.rustatsport.ru/?tpl=207&user={user}&key={password}&match_id={match_id}&lang_id=1&format=json",
|
|
5
|
-
"tournament_teams": "http://feeds.rustatsport.ru/?tpl=32&user={user}&key={password}&tournament_id=2&season_id={season_id}&date_start=&date_end=&lang_id=1&format=json"
|
|
5
|
+
"tournament_teams": "http://feeds.rustatsport.ru/?tpl=32&user={user}&key={password}&tournament_id=2&season_id={season_id}&date_start=&date_end=&lang_id=1&format=json",
|
|
6
|
+
"tracking": "https://feeds.rustatsport.ru/?tpl=274&user={user}&key={password}&match_id={match_id}&lang_id=0&format=json"
|
|
6
7
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: rustat-python-api
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: A Python wrapper for RuStat API
|
|
5
5
|
Home-page: https://github.com/dailydaniel/rustat-python-api
|
|
6
6
|
Author: Daniel Zholkovsky
|
|
@@ -41,4 +41,6 @@ match_id = keys[-1]
|
|
|
41
41
|
events = parser.get_events(match_id)
|
|
42
42
|
|
|
43
43
|
stats = parser.get_match_stats(match_id)
|
|
44
|
+
|
|
45
|
+
tracking = parser.get_tracking(match_id)
|
|
44
46
|
```
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rustat-python-api-0.1.1 → rustat-python-api-0.2.0}/rustat_python_api.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
{rustat-python-api-0.1.1 → rustat-python-api-0.2.0}/rustat_python_api.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|