ATG-lib 1.5.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.
- atg_lib-1.5.0/ATG/__init__.py +8 -0
- atg_lib-1.5.0/ATG/api/__init__.py +46 -0
- atg_lib-1.5.0/ATG/api/account_v1.py +29 -0
- atg_lib-1.5.0/ATG/api/ddragon.py +6 -0
- atg_lib-1.5.0/ATG/api/league_v4.py +91 -0
- atg_lib-1.5.0/ATG/api/match_v5.py +59 -0
- atg_lib-1.5.0/ATG/api/spectator_v5.py +28 -0
- atg_lib-1.5.0/ATG/api/summoner_v4.py +43 -0
- atg_lib-1.5.0/ATG/api/utils.py +73 -0
- atg_lib-1.5.0/ATG/database/__init__.py +3 -0
- atg_lib-1.5.0/ATG/database/database.py +10 -0
- atg_lib-1.5.0/ATG/match_lib/__init__.py +23 -0
- atg_lib-1.5.0/ATG/match_lib/esports_ingest.py +112 -0
- atg_lib-1.5.0/ATG/match_lib/ingest_match.py +175 -0
- atg_lib-1.5.0/ATG/models/__init__.py +33 -0
- atg_lib-1.5.0/ATG/models/account.py +43 -0
- atg_lib-1.5.0/ATG/models/base.py +5 -0
- atg_lib-1.5.0/ATG/models/champion.py +14 -0
- atg_lib-1.5.0/ATG/models/draft_event.py +26 -0
- atg_lib-1.5.0/ATG/models/game.py +131 -0
- atg_lib-1.5.0/ATG/models/game_event.py +33 -0
- atg_lib-1.5.0/ATG/models/participant.py +62 -0
- atg_lib-1.5.0/ATG/models/participant_stat.py +177 -0
- atg_lib-1.5.0/ATG/models/player.py +28 -0
- atg_lib-1.5.0/ATG/models/player_team_association.py +18 -0
- atg_lib-1.5.0/ATG/models/series.py +23 -0
- atg_lib-1.5.0/ATG/models/team.py +31 -0
- atg_lib-1.5.0/ATG/models/team_dto.py +29 -0
- atg_lib-1.5.0/ATG/models/team_stat.py +34 -0
- atg_lib-1.5.0/ATG/models/tournament.py +33 -0
- atg_lib-1.5.0/ATG/rate_limiter/README.md +44 -0
- atg_lib-1.5.0/ATG/rate_limiter/__init__.py +7 -0
- atg_lib-1.5.0/ATG/rate_limiter/rate_limiter.py +193 -0
- atg_lib-1.5.0/ATG/utils/__init__.py +25 -0
- atg_lib-1.5.0/ATG/utils/constants.py +65 -0
- atg_lib-1.5.0/ATG/utils/db_utils.py +38 -0
- atg_lib-1.5.0/ATG/utils/helpers.py +12 -0
- atg_lib-1.5.0/LICENSE +674 -0
- atg_lib-1.5.0/PKG-INFO +121 -0
- atg_lib-1.5.0/README.md +100 -0
- atg_lib-1.5.0/pyproject.toml +26 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from .account_v1 import get_account_by_puuid, get_account_by_riot_id
|
|
2
|
+
from .ddragon import get_ddragon_versions
|
|
3
|
+
from .league_v4 import (
|
|
4
|
+
get_masters,
|
|
5
|
+
get_grandmasters,
|
|
6
|
+
get_challengers,
|
|
7
|
+
get_league_entries_by_puuid,
|
|
8
|
+
get_league_entries_by_summoner_id,
|
|
9
|
+
get_all_league_entries,
|
|
10
|
+
get_league_entries_by_league_id,
|
|
11
|
+
)
|
|
12
|
+
from .match_v5 import get_available_matches, get_match_by_id, get_match_history
|
|
13
|
+
from .spectator_v5 import get_active_games, get_featured_games
|
|
14
|
+
from .summoner_v4 import (
|
|
15
|
+
get_summoner_by_account_id,
|
|
16
|
+
get_summoner_by_puuid,
|
|
17
|
+
get_summoner_by_summoner_id,
|
|
18
|
+
)
|
|
19
|
+
from .utils import parse_match_id, REGIONS, QUEUES, DIVISIONS, TIERS
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"get_account_by_puuid",
|
|
24
|
+
"get_account_by_riot_id",
|
|
25
|
+
"get_ddragon_versions",
|
|
26
|
+
"get_masters",
|
|
27
|
+
"get_grandmasters",
|
|
28
|
+
"get_challengers",
|
|
29
|
+
"get_league_entries_by_puuid",
|
|
30
|
+
"get_league_entries_by_summoner_id",
|
|
31
|
+
"get_all_league_entries",
|
|
32
|
+
"get_league_entries_by_league_id",
|
|
33
|
+
"get_available_matches",
|
|
34
|
+
"get_match_by_id",
|
|
35
|
+
"get_match_history",
|
|
36
|
+
"get_active_games",
|
|
37
|
+
"get_featured_games",
|
|
38
|
+
"get_summoner_by_account_id",
|
|
39
|
+
"get_summoner_by_puuid",
|
|
40
|
+
"get_summoner_by_summoner_id",
|
|
41
|
+
"parse_match_id",
|
|
42
|
+
"REGIONS",
|
|
43
|
+
"QUEUES",
|
|
44
|
+
"DIVISIONS",
|
|
45
|
+
"TIERS",
|
|
46
|
+
]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import requests as r
|
|
2
|
+
from requests import Response
|
|
3
|
+
from .utils import headers, RoutingLiteral
|
|
4
|
+
from ..rate_limiter import riot_api_limiter
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@riot_api_limiter(endpoint_key="account_v1_by_riot_id")
|
|
8
|
+
def get_account_by_riot_id(
|
|
9
|
+
game_name: str, tag_line: str, api_key: str, routing: RoutingLiteral = "americas"
|
|
10
|
+
) -> Response:
|
|
11
|
+
_headers = {"X-Riot-Token": api_key, **headers}
|
|
12
|
+
# There are three routing values for account-v1; americas, asia, and europe. You can query for any account in any region. We recommend using the nearest cluster.
|
|
13
|
+
response = r.get(
|
|
14
|
+
f"https://{routing}.api.riotgames.com/riot/account/v1/accounts/by-riot-id/{game_name}/{tag_line}",
|
|
15
|
+
headers=_headers,
|
|
16
|
+
)
|
|
17
|
+
return response
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@riot_api_limiter(endpoint_key="account_v1_by_puuid")
|
|
21
|
+
def get_account_by_puuid(
|
|
22
|
+
puuid: str, api_key: str, routing: RoutingLiteral = "americas"
|
|
23
|
+
) -> Response:
|
|
24
|
+
_headers = {"X-Riot-Token": api_key, **headers}
|
|
25
|
+
response = r.get(
|
|
26
|
+
f"https://{routing}.api.riotgames.com/riot/account/v1/accounts/by-puuid/{puuid}",
|
|
27
|
+
headers=_headers,
|
|
28
|
+
)
|
|
29
|
+
return response
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import requests as r
|
|
2
|
+
from requests import Response
|
|
3
|
+
from .utils import headers, RegionLiteral, QueueLiteral, DivisionLiteral, TierLiteral
|
|
4
|
+
from ..rate_limiter import riot_api_limiter
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@riot_api_limiter(endpoint_key="league_v4_get_challengers")
|
|
8
|
+
def get_challengers(
|
|
9
|
+
region: RegionLiteral, queue: QueueLiteral, api_key: str
|
|
10
|
+
) -> Response:
|
|
11
|
+
_headers = {"X-Riot-Token": api_key, **headers}
|
|
12
|
+
response = r.get(
|
|
13
|
+
f"https://{region.lower()}.api.riotgames.com/lol/league/v4/challengerleagues/by-queue/{queue}",
|
|
14
|
+
headers=_headers,
|
|
15
|
+
)
|
|
16
|
+
return response
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@riot_api_limiter(endpoint_key="league_v4_get_grandmasters")
|
|
20
|
+
def get_grandmasters(
|
|
21
|
+
region: RegionLiteral, queue: QueueLiteral, api_key: str
|
|
22
|
+
) -> Response:
|
|
23
|
+
_headers = {"X-Riot-Token": api_key, **headers}
|
|
24
|
+
response = r.get(
|
|
25
|
+
f"https://{region.lower()}.api.riotgames.com/lol/league/v4/grandmasterleagues/by-queue/{queue}",
|
|
26
|
+
headers=_headers,
|
|
27
|
+
)
|
|
28
|
+
return response
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@riot_api_limiter(endpoint_key="league_v4_get_masters")
|
|
32
|
+
def get_masters(region: RegionLiteral, queue: QueueLiteral, api_key: str) -> Response:
|
|
33
|
+
_headers = {"X-Riot-Token": api_key, **headers}
|
|
34
|
+
response = r.get(
|
|
35
|
+
f"https://{region.lower()}.api.riotgames.com/lol/league/v4/masterleagues/by-queue/{queue}",
|
|
36
|
+
headers=_headers,
|
|
37
|
+
)
|
|
38
|
+
return response
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@riot_api_limiter(endpoint_key="league_v4_entries_puuid")
|
|
42
|
+
def get_league_entries_by_puuid(
|
|
43
|
+
region: RegionLiteral, puuid: str, api_key: str
|
|
44
|
+
) -> Response:
|
|
45
|
+
_headers = {"X-Riot-Token": api_key, **headers}
|
|
46
|
+
response = r.get(
|
|
47
|
+
f"https://{region.lower()}.api.riotgames.com/lol/league/v4/entries/by-puuid/{puuid}",
|
|
48
|
+
headers=_headers,
|
|
49
|
+
)
|
|
50
|
+
return response
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@riot_api_limiter(endpoint_key="league_v4_entries_summoner_id")
|
|
54
|
+
def get_league_entries_by_summoner_id(
|
|
55
|
+
region: RegionLiteral, summoner_id: str, api_key: str
|
|
56
|
+
) -> Response:
|
|
57
|
+
_headers = {"X-Riot-Token": api_key, **headers}
|
|
58
|
+
response = r.get(
|
|
59
|
+
f"https://{region.lower()}.api.riotgames.com/lol/league/v4/entries/by-summoner/{summoner_id}",
|
|
60
|
+
headers=_headers,
|
|
61
|
+
)
|
|
62
|
+
return response
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@riot_api_limiter(endpoint_key="league_v4_all_entries")
|
|
66
|
+
def get_all_league_entries(
|
|
67
|
+
region: RegionLiteral,
|
|
68
|
+
queue: QueueLiteral,
|
|
69
|
+
tier: TierLiteral,
|
|
70
|
+
division: DivisionLiteral,
|
|
71
|
+
api_key: str,
|
|
72
|
+
page: int = 1,
|
|
73
|
+
) -> Response:
|
|
74
|
+
_headers = {"X-Riot-Token": api_key, "page": str(page), **headers}
|
|
75
|
+
response = r.get(
|
|
76
|
+
f"https://{region.lower()}.api.riotgames.com/lol/league/v4/entries/{queue}/{tier}/{division}",
|
|
77
|
+
headers=_headers,
|
|
78
|
+
)
|
|
79
|
+
return response
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@riot_api_limiter(endpoint_key="league_v4_entries_league_id")
|
|
83
|
+
def get_league_entries_by_league_id(
|
|
84
|
+
region: RegionLiteral, league_id: str, api_key: str
|
|
85
|
+
) -> Response:
|
|
86
|
+
_headers = {"X-Riot-Token": api_key, **headers}
|
|
87
|
+
response = r.get(
|
|
88
|
+
f"https://{region.lower()}.api.riotgames.com/lol/league/v4/leagues/{league_id}",
|
|
89
|
+
headers=_headers,
|
|
90
|
+
)
|
|
91
|
+
return response
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import requests as r
|
|
2
|
+
from requests import Response
|
|
3
|
+
from .utils import headers, PLATFORM_ROUTING, parse_match_id, RegionLiteral
|
|
4
|
+
from ..rate_limiter import riot_api_limiter
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@riot_api_limiter(endpoint_key="match_v5_by_id")
|
|
8
|
+
def get_match_by_id(match_id: str, api_key: str, timeline: bool = False) -> Response:
|
|
9
|
+
region, _ = parse_match_id(match_id)
|
|
10
|
+
is_timeline = "/timeline" if timeline else ""
|
|
11
|
+
_headers = {"X-Riot-Token": api_key, **headers}
|
|
12
|
+
response = r.get(
|
|
13
|
+
f"https://{PLATFORM_ROUTING[region]}.api.riotgames.com/lol/match/v5/matches/{match_id}{is_timeline}",
|
|
14
|
+
headers=_headers,
|
|
15
|
+
)
|
|
16
|
+
return response
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@riot_api_limiter(endpoint_key="match_v5_available_matches")
|
|
20
|
+
def get_available_matches(
|
|
21
|
+
puuid: str, region: RegionLiteral, api_key: str, **kwargs
|
|
22
|
+
) -> Response:
|
|
23
|
+
_headers = {"X-Riot-Token": api_key, **headers}
|
|
24
|
+
response = r.get(
|
|
25
|
+
f"https://{PLATFORM_ROUTING[region]}.api.riotgames.com/lol/match/v5/matches/by-puuid/{puuid}/ids",
|
|
26
|
+
headers=_headers,
|
|
27
|
+
params=kwargs,
|
|
28
|
+
)
|
|
29
|
+
return response
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def get_match_history(
|
|
33
|
+
puuid: str, region: RegionLiteral, api_key: str, **kwargs
|
|
34
|
+
) -> list[str]:
|
|
35
|
+
start = 0
|
|
36
|
+
count = 100
|
|
37
|
+
match_history = []
|
|
38
|
+
while True:
|
|
39
|
+
match_list = get_available_matches(
|
|
40
|
+
puuid=puuid,
|
|
41
|
+
region=region,
|
|
42
|
+
api_key=api_key,
|
|
43
|
+
start=start,
|
|
44
|
+
count=count,
|
|
45
|
+
**kwargs,
|
|
46
|
+
)
|
|
47
|
+
if match_list:
|
|
48
|
+
try:
|
|
49
|
+
match_list.raise_for_status()
|
|
50
|
+
match_list = match_list.json()
|
|
51
|
+
if len(match_list) == 0:
|
|
52
|
+
break
|
|
53
|
+
match_history.extend(match_list)
|
|
54
|
+
start += count
|
|
55
|
+
except:
|
|
56
|
+
# If an error occurs, we will fail.
|
|
57
|
+
print(f"{match_list.status_code} - Failed to retrieve match history")
|
|
58
|
+
return match_history
|
|
59
|
+
return match_history
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import requests as r
|
|
2
|
+
from requests import Response
|
|
3
|
+
from .utils import headers, RegionLiteral
|
|
4
|
+
from ..rate_limiter import riot_api_limiter
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@riot_api_limiter(endpoint_key="spectator_v5_active_games")
|
|
8
|
+
def get_active_games(
|
|
9
|
+
puuid: str, region: RegionLiteral, api_key: str, **kwargs
|
|
10
|
+
) -> Response:
|
|
11
|
+
_headers = {"X-Riot-Token": api_key, **headers}
|
|
12
|
+
response = r.get(
|
|
13
|
+
f"https://{region.lower()}.api.riotgames.com/lol/spectator/v5/active-games/by-summoner/{puuid}",
|
|
14
|
+
headers=_headers,
|
|
15
|
+
params=kwargs,
|
|
16
|
+
)
|
|
17
|
+
return response
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@riot_api_limiter(endpoint_key="spectator_v5_featured_games")
|
|
21
|
+
def get_featured_games(region: RegionLiteral, api_key: str, **kwargs) -> Response:
|
|
22
|
+
_headers = {"X-Riot-Token": api_key, **headers}
|
|
23
|
+
response = r.get(
|
|
24
|
+
f"https://{region.lower()}.api.riotgames.com/lol/spectator/v5/featured-games",
|
|
25
|
+
headers=_headers,
|
|
26
|
+
params=kwargs,
|
|
27
|
+
)
|
|
28
|
+
return response
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import requests as r
|
|
2
|
+
from requests import Response
|
|
3
|
+
from .utils import headers, RegionLiteral
|
|
4
|
+
from ..rate_limiter import riot_api_limiter
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@riot_api_limiter(endpoint_key="summoner_v4_by_account_id")
|
|
8
|
+
def get_summoner_by_account_id(
|
|
9
|
+
account_id: str, region: RegionLiteral, api_key: str, **kwargs
|
|
10
|
+
) -> Response:
|
|
11
|
+
_headers = {"X-Riot-Token": api_key, **headers}
|
|
12
|
+
response = r.get(
|
|
13
|
+
f"https://{region.lower()}.api.riotgames.com/lol/summoner/v4/summoners/by-account/{account_id}",
|
|
14
|
+
headers=_headers,
|
|
15
|
+
params=kwargs,
|
|
16
|
+
)
|
|
17
|
+
return response
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@riot_api_limiter(endpoint_key="summoner_v4_by_puuid")
|
|
21
|
+
def get_summoner_by_puuid(
|
|
22
|
+
puuid: str, region: RegionLiteral, api_key: str, **kwargs
|
|
23
|
+
) -> Response:
|
|
24
|
+
_headers = {"X-Riot-Token": api_key, **headers}
|
|
25
|
+
response = r.get(
|
|
26
|
+
f"https://{region.lower()}.api.riotgames.com/lol/summoner/v4/summoners/by-puuid/{puuid}",
|
|
27
|
+
headers=_headers,
|
|
28
|
+
params=kwargs,
|
|
29
|
+
)
|
|
30
|
+
return response
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@riot_api_limiter(endpoint_key="summoner_v4_by_summoner_id")
|
|
34
|
+
def get_summoner_by_summoner_id(
|
|
35
|
+
summoner_id: str, region: RegionLiteral, api_key: str, **kwargs
|
|
36
|
+
) -> Response:
|
|
37
|
+
_headers = {"X-Riot-Token": api_key, **headers}
|
|
38
|
+
response = r.get(
|
|
39
|
+
f"https://{region.lower()}.api.riotgames.com/lol/summoner/v4/summoners/{summoner_id}",
|
|
40
|
+
headers=_headers,
|
|
41
|
+
params=kwargs,
|
|
42
|
+
)
|
|
43
|
+
return response
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from typing import Dict, Literal
|
|
2
|
+
from enum import StrEnum
|
|
3
|
+
|
|
4
|
+
headers = {
|
|
5
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36",
|
|
6
|
+
"Accept-Language": "en-US,en-CA;q=0.9,en;q=0.8,ru-RU;q=0.7,ru;q=0.6,ko-KR;q=0.5,ko;q=0.4",
|
|
7
|
+
"Accept-Charset": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
# The AMERICAS routing value serves NA, BR, LAN and LAS. The ASIA routing value serves KR and JP. The EUROPE routing value serves EUNE, EUW, ME1, TR and RU. The SEA routing value serves OCE, SG2, TW2 and VN2.
|
|
11
|
+
PLATFORM_ROUTING: Dict[str, str] = {
|
|
12
|
+
"NA1": "americas",
|
|
13
|
+
"BR1": "americas",
|
|
14
|
+
"LA1": "americas",
|
|
15
|
+
"LA2": "americas",
|
|
16
|
+
"KR": "asia",
|
|
17
|
+
"JP": "asia",
|
|
18
|
+
"ME1": "europe",
|
|
19
|
+
"EUN1": "europe",
|
|
20
|
+
"EUW1": "europe",
|
|
21
|
+
"TR1": "europe",
|
|
22
|
+
"RU": "europe",
|
|
23
|
+
"OC1": "sea",
|
|
24
|
+
"SG2": "sea",
|
|
25
|
+
"TW2": "sea",
|
|
26
|
+
"VN2": "sea",
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
RoutingLiteral = Literal["americas", "asia", "europe", "sea"]
|
|
30
|
+
RegionLiteral = Literal[
|
|
31
|
+
"NA1",
|
|
32
|
+
"BR1",
|
|
33
|
+
"LA1",
|
|
34
|
+
"LA2",
|
|
35
|
+
"KR",
|
|
36
|
+
"JP",
|
|
37
|
+
"ME1",
|
|
38
|
+
"EUN1",
|
|
39
|
+
"EUW1",
|
|
40
|
+
"TR1",
|
|
41
|
+
"RU",
|
|
42
|
+
"OC1",
|
|
43
|
+
"SG2",
|
|
44
|
+
"TW2",
|
|
45
|
+
"VN2",
|
|
46
|
+
]
|
|
47
|
+
QueueLiteral = Literal["RANKED_SOLO_5x5", "RANKED_FLEX_SR", "RANKED_FLEX_TT"]
|
|
48
|
+
DivisionLiteral = Literal["I", "II", "III", "IV"]
|
|
49
|
+
TierLiteral = Literal[
|
|
50
|
+
"DIAMOND", "EMERALD", "PLATINUM", "GOLD", "SILVER", "BRONZE", "IRON"
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
REGIONS = StrEnum("Regions", [(_, _) for _ in PLATFORM_ROUTING.keys()])
|
|
54
|
+
QUEUES = StrEnum(
|
|
55
|
+
"Queues", [(_, _) for _ in ["RANKED_SOLO_5x5", "RANKED_FLEX_SR", "RANKED_FLEX_TT"]]
|
|
56
|
+
)
|
|
57
|
+
DIVISIONS = StrEnum("Divisions", [(_, _) for _ in ["I", "II", "III", "IV"]])
|
|
58
|
+
TIERS = StrEnum(
|
|
59
|
+
"Tiers",
|
|
60
|
+
[
|
|
61
|
+
(_, _)
|
|
62
|
+
for _ in ["DIAMOND", "EMERALD", "PLATINUM", "GOLD", "SILVER", "BRONZE", "IRON"]
|
|
63
|
+
],
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def parse_match_id(match_id: str) -> tuple[str, str]:
|
|
68
|
+
split = match_id.split("_")
|
|
69
|
+
if len(split) != 2:
|
|
70
|
+
raise ValueError(f"Unable to parse {match_id}")
|
|
71
|
+
if split[0] not in REGIONS:
|
|
72
|
+
raise ValueError(f"Unknown region {split[0]} received")
|
|
73
|
+
return split[0], split[1]
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from sqlalchemy import create_engine
|
|
2
|
+
from sqlalchemy.orm import sessionmaker
|
|
3
|
+
from ..models import Base
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def get_session_factory(database_url: str, read_only: bool = False):
|
|
7
|
+
engine = create_engine(database_url, pool_recycle=3600)
|
|
8
|
+
if not read_only:
|
|
9
|
+
Base.metadata.create_all(bind=engine)
|
|
10
|
+
return sessionmaker(autocommit=False, autoflush=True, bind=engine)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from .esports_ingest import (
|
|
2
|
+
create_account,
|
|
3
|
+
create_player,
|
|
4
|
+
create_missing_accounts,
|
|
5
|
+
parse_game_participants,
|
|
6
|
+
get_common_prefix_length
|
|
7
|
+
)
|
|
8
|
+
from .ingest_match import (
|
|
9
|
+
insert_match_history,
|
|
10
|
+
update_account_names,
|
|
11
|
+
process_match,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"create_account",
|
|
16
|
+
"create_player",
|
|
17
|
+
"create_missing_accounts",
|
|
18
|
+
"parse_game_participants",
|
|
19
|
+
"get_common_prefix_length",
|
|
20
|
+
"insert_match_history",
|
|
21
|
+
"update_account_names",
|
|
22
|
+
"process_match",
|
|
23
|
+
]
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
from ..models import Player, Account, Participant
|
|
2
|
+
from sqlalchemy.orm import Session
|
|
3
|
+
from sqlalchemy import select
|
|
4
|
+
|
|
5
|
+
def create_player(name: str) -> Player:
|
|
6
|
+
"""Creates a player object
|
|
7
|
+
|
|
8
|
+
Args:
|
|
9
|
+
name (str): Player name
|
|
10
|
+
|
|
11
|
+
Returns:
|
|
12
|
+
Player: Created player object
|
|
13
|
+
"""
|
|
14
|
+
return Player(name=name)
|
|
15
|
+
|
|
16
|
+
def create_account(puuid: str, name: str, tagline: str, player_id: int, region: str = "TOURNAMENT", skip_update: bool = True) -> Account:
|
|
17
|
+
"""Creates an account object
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
puuid (str): Account identifier (PUUID / Account ID)
|
|
21
|
+
name (str): Account name
|
|
22
|
+
tagline (str): Account tagline
|
|
23
|
+
player_id (int): Player ID (foreign key)
|
|
24
|
+
region (str, optional): Account region. Defaults to "TOURNAMENT".
|
|
25
|
+
skip_update (bool, optional): Should be updated automatically?. Defaults to True.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
Account: Created account object
|
|
29
|
+
"""
|
|
30
|
+
return Account(
|
|
31
|
+
puuid=puuid,
|
|
32
|
+
name=name,
|
|
33
|
+
tagline=tagline,
|
|
34
|
+
region=region,
|
|
35
|
+
player_id=player_id,
|
|
36
|
+
skip_update=skip_update)
|
|
37
|
+
|
|
38
|
+
def get_puuid(participant) -> str:
|
|
39
|
+
return str(participant.get("puuid", participant["accountID"]))
|
|
40
|
+
def get_game_name(participant) -> str:
|
|
41
|
+
return participant.get("riotId", {"displayName": participant.get("summonerName")})["displayName"]
|
|
42
|
+
def get_tagline(participant) -> str:
|
|
43
|
+
return participant.get("riotId", {}).get("tagLine", "")
|
|
44
|
+
def get_team_id(participant) -> int:
|
|
45
|
+
return participant.get("teamID", participant.get("teamId"))
|
|
46
|
+
|
|
47
|
+
def parse_game_participants(participants: list[dict], game_id: str, winning_team_id: int, NAME_ID_MAP: dict[str, int]) -> list[Participant]:
|
|
48
|
+
"""Parses the participants into a list of Participant objects
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
participants (list[dict]): List of game participants
|
|
52
|
+
winning_team_id (int): 100 or 200 (blue/red winners)
|
|
53
|
+
NAME_ID_MAP (dict[str, int]): champion name -> champion id map
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
list[Participant]: Parsed participant objects
|
|
57
|
+
"""
|
|
58
|
+
game_participants = []
|
|
59
|
+
for participant in participants:
|
|
60
|
+
game_participants.append(Participant(
|
|
61
|
+
game_id = game_id,
|
|
62
|
+
puuid = get_puuid(participant),
|
|
63
|
+
participant_id = participant["participantID"],
|
|
64
|
+
riot_id_game_name = get_game_name(participant),
|
|
65
|
+
riot_id_tagline = get_tagline(participant),
|
|
66
|
+
summoner_id = participant["accountID"],
|
|
67
|
+
team_id = get_team_id(participant),
|
|
68
|
+
champion_id = NAME_ID_MAP[participant["championName"].lower()],
|
|
69
|
+
win = get_team_id(participant) == winning_team_id,
|
|
70
|
+
))
|
|
71
|
+
return game_participants
|
|
72
|
+
|
|
73
|
+
def get_common_prefix_length(player_names: list[str]) -> int:
|
|
74
|
+
"""Gets the number of charaters shared in the prefix of all items of a list
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
player_names (list[str]): A list of player names
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
int: The length of the shared prefix
|
|
81
|
+
"""
|
|
82
|
+
common_prefix_length = 0
|
|
83
|
+
for chars in zip(*player_names):
|
|
84
|
+
if len(set(chars)) == 1:
|
|
85
|
+
common_prefix_length += 1
|
|
86
|
+
else:
|
|
87
|
+
break
|
|
88
|
+
return common_prefix_length
|
|
89
|
+
|
|
90
|
+
def create_missing_accounts(session: Session, participants: dict):
|
|
91
|
+
"""Helper function to parse a list of participants and add to the session any missing players/accounts.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
session (Session): Active SQLAlchemy session object
|
|
95
|
+
participants (dict): A match-v5 like participant list
|
|
96
|
+
"""
|
|
97
|
+
stored_puuids = session.scalars(select(Account.puuid)).all()
|
|
98
|
+
for participant in participants:
|
|
99
|
+
puuid = get_puuid(participant)
|
|
100
|
+
if puuid not in stored_puuids:
|
|
101
|
+
game_name = get_game_name(participant)
|
|
102
|
+
player_names = [get_game_name(p) for p in participants if get_team_id(p) == get_team_id(participant)]
|
|
103
|
+
player_name = game_name[get_common_prefix_length(player_names):]
|
|
104
|
+
|
|
105
|
+
db_player = session.scalar(select(Player).where(Player.name == player_name))
|
|
106
|
+
|
|
107
|
+
if db_player is None:
|
|
108
|
+
db_player = create_player(player_name)
|
|
109
|
+
session.add(db_player)
|
|
110
|
+
session.flush()
|
|
111
|
+
|
|
112
|
+
session.add(create_account(puuid, game_name, get_tagline(participant), db_player.id))
|