ddapi 0.12.0__tar.gz → 0.12.1__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.
- {ddapi-0.12.0 → ddapi-0.12.1}/PKG-INFO +2 -2
- {ddapi-0.12.0 → ddapi-0.12.1}/ddapi/ddapi/__init__.py +2 -1
- {ddapi-0.12.0 → ddapi-0.12.1}/ddapi/ddapi/api.py +6 -13
- {ddapi-0.12.0 → ddapi-0.12.1}/ddapi/ddapi/main.py +52 -71
- {ddapi-0.12.0 → ddapi-0.12.1}/ddapi/ddapi/scheme/base.py +17 -1
- {ddapi-0.12.0 → ddapi-0.12.1}/ddapi/ddapi/scheme/ddnet.py +7 -22
- {ddapi-0.12.0 → ddapi-0.12.1}/ddapi/ddapi.egg-info/PKG-INFO +2 -2
- {ddapi-0.12.0 → ddapi-0.12.1}/setup.cfg +2 -2
- {ddapi-0.12.0 → ddapi-0.12.1}/setup.py +3 -5
- {ddapi-0.12.0 → ddapi-0.12.1}/LICENSE +0 -0
- {ddapi-0.12.0 → ddapi-0.12.1}/README.md +0 -0
- {ddapi-0.12.0 → ddapi-0.12.1}/ddapi/ddapi/scheme/__init__.py +0 -0
- {ddapi-0.12.0 → ddapi-0.12.1}/ddapi/ddapi/scheme/ddstats_tw.py +0 -0
- {ddapi-0.12.0 → ddapi-0.12.1}/ddapi/ddapi/scheme/status_tw.py +0 -0
- {ddapi-0.12.0 → ddapi-0.12.1}/ddapi/ddapi/types.py +0 -0
- {ddapi-0.12.0 → ddapi-0.12.1}/ddapi/ddapi.egg-info/SOURCES.txt +0 -0
- {ddapi-0.12.0 → ddapi-0.12.1}/ddapi/ddapi.egg-info/dependency_links.txt +0 -0
- {ddapi-0.12.0 → ddapi-0.12.1}/ddapi/ddapi.egg-info/top_level.txt +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ddapi
|
|
3
|
-
Version: 0.12.
|
|
3
|
+
Version: 0.12.1
|
|
4
4
|
Summary: DDnet api
|
|
5
5
|
Home-page: https://github.com/ByFox213/ddapi
|
|
6
6
|
Author: ByFox
|
|
7
7
|
License: MIT
|
|
8
8
|
Project-URL: Github, https://github.com/ByFox213/ddapi
|
|
9
|
-
Requires-Python: >=3.
|
|
9
|
+
Requires-Python: >=3.10
|
|
10
10
|
Description-Content-Type: text/markdown
|
|
11
11
|
License-File: LICENSE
|
|
12
12
|
Dynamic: author
|
|
@@ -17,10 +17,10 @@ except ImportError:
|
|
|
17
17
|
|
|
18
18
|
class API(ABC):
|
|
19
19
|
def __init__(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
self,
|
|
21
|
+
session: ClientSession = None,
|
|
22
|
+
autoclose: bool = True,
|
|
23
|
+
json_loads: Any = DEFAULT_JSON_DECODER,
|
|
24
24
|
):
|
|
25
25
|
self.__session = session
|
|
26
26
|
self.json_loads = json_loads
|
|
@@ -49,17 +49,10 @@ class API(ABC):
|
|
|
49
49
|
async def _get(self, url: str) -> Optional[dict]:
|
|
50
50
|
"""Send a GET request to the given URL and return the response as JSON."""
|
|
51
51
|
async with self.__session.get(url) as req:
|
|
52
|
-
return (
|
|
53
|
-
await req.json(loads=self.json_loads)
|
|
54
|
-
if req.status == 200
|
|
55
|
-
else None
|
|
56
|
-
)
|
|
52
|
+
return await req.json(loads=self.json_loads) if req.status == 200 else None
|
|
57
53
|
|
|
58
54
|
async def _generate_model_instance(
|
|
59
|
-
|
|
60
|
-
url: str,
|
|
61
|
-
model: Type[T],
|
|
62
|
-
k: Optional[str] = None
|
|
55
|
+
self, url: str, model: Type[T], k: Optional[str] = None
|
|
63
56
|
) -> Optional[T]:
|
|
64
57
|
"""Generate a model instance from the given URL and optional keyword arguments.
|
|
65
58
|
|
|
@@ -2,17 +2,34 @@ from enum import StrEnum
|
|
|
2
2
|
from urllib.parse import quote
|
|
3
3
|
|
|
4
4
|
from .api import API
|
|
5
|
-
from .scheme import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
5
|
+
from .scheme import (
|
|
6
|
+
DDPlayer,
|
|
7
|
+
DDStatus,
|
|
8
|
+
ReleasesMaps,
|
|
9
|
+
Query,
|
|
10
|
+
QueryMap,
|
|
11
|
+
QueryMapper,
|
|
12
|
+
Master,
|
|
13
|
+
DMap,
|
|
14
|
+
DProfile,
|
|
15
|
+
SMap,
|
|
16
|
+
Maps,
|
|
17
|
+
Player,
|
|
18
|
+
Info,
|
|
19
|
+
BannedMaster,
|
|
20
|
+
List,
|
|
21
|
+
ListData,
|
|
22
|
+
ListPl,
|
|
23
|
+
ListPlData,
|
|
24
|
+
MasterTw,
|
|
25
|
+
ServerTwOne,
|
|
26
|
+
Charts,
|
|
27
|
+
ChartEnum,
|
|
28
|
+
Stats,
|
|
14
29
|
)
|
|
15
30
|
|
|
31
|
+
__all__ = ("MasterEnum", "DDnetApi", "DDstats", "Status")
|
|
32
|
+
|
|
16
33
|
|
|
17
34
|
class MasterEnum(StrEnum):
|
|
18
35
|
master1 = "1"
|
|
@@ -33,28 +50,22 @@ class DDnetApi(API):
|
|
|
33
50
|
async def player(self, player: str) -> DDPlayer:
|
|
34
51
|
"""Fetch player data from the API and return it as a dictionary."""
|
|
35
52
|
return await self._generate_model_instance(
|
|
36
|
-
f"https://{self.domain}/players/?json2={quote(player)}",
|
|
37
|
-
DDPlayer
|
|
53
|
+
f"https://{self.domain}/players/?json2={quote(player)}", DDPlayer
|
|
38
54
|
)
|
|
39
55
|
|
|
40
56
|
async def status(self) -> DDStatus:
|
|
41
57
|
return await self._generate_model_instance(
|
|
42
|
-
f"https://{self.domain}/status/json/stats.json",
|
|
43
|
-
DDStatus
|
|
58
|
+
f"https://{self.domain}/status/json/stats.json", DDStatus
|
|
44
59
|
)
|
|
45
60
|
|
|
46
61
|
async def releases_map(self) -> ReleasesMaps:
|
|
47
62
|
return await self._generate_model_instance(
|
|
48
|
-
f"https://{self.domain}/releases/maps.json",
|
|
49
|
-
ReleasesMaps,
|
|
50
|
-
"maps"
|
|
63
|
+
f"https://{self.domain}/releases/maps.json", ReleasesMaps, "maps"
|
|
51
64
|
)
|
|
52
65
|
|
|
53
66
|
async def query(self, player: str) -> Query:
|
|
54
67
|
return await self._generate_model_instance(
|
|
55
|
-
f"https://{self.domain}/players/?query={quote(player)}",
|
|
56
|
-
Query,
|
|
57
|
-
"players"
|
|
68
|
+
f"https://{self.domain}/players/?query={quote(player)}", Query, "players"
|
|
58
69
|
)
|
|
59
70
|
|
|
60
71
|
async def query_map(self, map_name: str) -> QueryMap:
|
|
@@ -73,14 +84,12 @@ class DDnetApi(API):
|
|
|
73
84
|
|
|
74
85
|
async def master(self, number: MasterEnum = MasterEnum.master1) -> Master:
|
|
75
86
|
return await self._generate_model_instance(
|
|
76
|
-
f"https://master{number}.{self.domain}/ddnet/15/servers.json",
|
|
77
|
-
Master
|
|
87
|
+
f"https://master{number}.{self.domain}/ddnet/15/servers.json", Master
|
|
78
88
|
)
|
|
79
89
|
|
|
80
90
|
async def map(self, map_name: str) -> DMap:
|
|
81
91
|
return await self._generate_model_instance(
|
|
82
|
-
f"https://{self.domain}/maps/?json={quote(map_name)}",
|
|
83
|
-
DMap
|
|
92
|
+
f"https://{self.domain}/maps/?json={quote(map_name)}", DMap
|
|
84
93
|
)
|
|
85
94
|
|
|
86
95
|
|
|
@@ -97,27 +106,23 @@ class DDstats(API):
|
|
|
97
106
|
return await self._generate_model_instance(
|
|
98
107
|
f"https://{self.domain}/profile/json?player={quote(player_name)}",
|
|
99
108
|
DProfile,
|
|
100
|
-
"profile"
|
|
109
|
+
"profile",
|
|
101
110
|
)
|
|
102
111
|
|
|
103
112
|
async def map(self, map_name: str) -> SMap:
|
|
104
113
|
return await self._generate_model_instance(
|
|
105
|
-
f"https://{self.domain}/map/json?map={quote(map_name)}",
|
|
106
|
-
SMap
|
|
114
|
+
f"https://{self.domain}/map/json?map={quote(map_name)}", SMap
|
|
107
115
|
)
|
|
108
116
|
|
|
109
117
|
async def maps(self) -> Maps:
|
|
110
118
|
return await self._generate_model_instance(
|
|
111
|
-
f"https://{self.domain}/maps/json",
|
|
112
|
-
Maps,
|
|
113
|
-
"maps"
|
|
119
|
+
f"https://{self.domain}/maps/json", Maps, "maps"
|
|
114
120
|
)
|
|
115
121
|
|
|
116
122
|
async def player(self, player_name: str) -> Player:
|
|
117
123
|
"""Fetch player data from the API and return it as a dictionary."""
|
|
118
124
|
return await self._generate_model_instance(
|
|
119
|
-
f"https://{self.domain}/player/json?player={quote(player_name)}",
|
|
120
|
-
Player
|
|
125
|
+
f"https://{self.domain}/player/json?player={quote(player_name)}", Player
|
|
121
126
|
)
|
|
122
127
|
|
|
123
128
|
|
|
@@ -132,62 +137,48 @@ class Status(API):
|
|
|
132
137
|
|
|
133
138
|
async def info(self) -> Info:
|
|
134
139
|
return await self._generate_model_instance(
|
|
135
|
-
f"https://api.{self.domain}/info",
|
|
136
|
-
Info
|
|
140
|
+
f"https://api.{self.domain}/info", Info
|
|
137
141
|
)
|
|
138
142
|
|
|
139
143
|
async def master_bans(self) -> BannedMaster:
|
|
140
144
|
return await self._generate_model_instance(
|
|
141
|
-
f"https://api.{self.domain}/master/bans/list",
|
|
142
|
-
BannedMaster,
|
|
143
|
-
"servers"
|
|
145
|
+
f"https://api.{self.domain}/master/bans/list", BannedMaster, "servers"
|
|
144
146
|
)
|
|
145
147
|
|
|
146
148
|
async def map_list(self) -> List:
|
|
147
149
|
return await self._generate_model_instance(
|
|
148
|
-
f"https://api.{self.domain}/map/list",
|
|
149
|
-
List,
|
|
150
|
-
"data"
|
|
150
|
+
f"https://api.{self.domain}/map/list", List, "data"
|
|
151
151
|
)
|
|
152
152
|
|
|
153
153
|
async def map(self, name: str) -> ListData:
|
|
154
154
|
return await self._generate_model_instance(
|
|
155
|
-
f"https://api.{self.domain}/map/name/{quote(name)}",
|
|
156
|
-
ListData
|
|
155
|
+
f"https://api.{self.domain}/map/name/{quote(name)}", ListData
|
|
157
156
|
)
|
|
158
157
|
|
|
159
158
|
async def gametype_list(self) -> List:
|
|
160
159
|
return await self._generate_model_instance(
|
|
161
|
-
f"https://api.{self.domain}/gametype/list",
|
|
162
|
-
List,
|
|
163
|
-
"data"
|
|
160
|
+
f"https://api.{self.domain}/gametype/list", List, "data"
|
|
164
161
|
)
|
|
165
162
|
|
|
166
163
|
async def gametype(self, name: str) -> ListData:
|
|
167
164
|
return await self._generate_model_instance(
|
|
168
|
-
f"https://api.{self.domain}/gametype/name/{quote(name)}",
|
|
169
|
-
ListData
|
|
165
|
+
f"https://api.{self.domain}/gametype/name/{quote(name)}", ListData
|
|
170
166
|
)
|
|
171
167
|
|
|
172
168
|
async def version_list(self) -> List:
|
|
173
169
|
return await self._generate_model_instance(
|
|
174
|
-
f"https://api.{self.domain}/version/list",
|
|
175
|
-
List,
|
|
176
|
-
"data"
|
|
170
|
+
f"https://api.{self.domain}/version/list", List, "data"
|
|
177
171
|
)
|
|
178
172
|
|
|
179
173
|
async def version(self, name: str) -> ListData:
|
|
180
174
|
return await self._generate_model_instance(
|
|
181
|
-
f"https://api.{self.domain}/version/name/{quote(name)}",
|
|
182
|
-
ListData
|
|
175
|
+
f"https://api.{self.domain}/version/name/{quote(name)}", ListData
|
|
183
176
|
)
|
|
184
177
|
|
|
185
178
|
async def server_list(self) -> MasterTw:
|
|
186
179
|
"""Fetch player data from the API and return it as a dictionary."""
|
|
187
180
|
return await self._generate_model_instance(
|
|
188
|
-
f"https://api.{self.domain}/server/list",
|
|
189
|
-
MasterTw,
|
|
190
|
-
"servers"
|
|
181
|
+
f"https://api.{self.domain}/server/list", MasterTw, "servers"
|
|
191
182
|
)
|
|
192
183
|
|
|
193
184
|
async def server(self, ip: str, port: int | str) -> ServerTwOne:
|
|
@@ -197,15 +188,12 @@ class Status(API):
|
|
|
197
188
|
)
|
|
198
189
|
|
|
199
190
|
async def server_charts(
|
|
200
|
-
|
|
201
|
-
ip: str,
|
|
202
|
-
port: int | str,
|
|
203
|
-
chart: ChartEnum = ChartEnum.day
|
|
191
|
+
self, ip: str, port: int | str, chart: ChartEnum = ChartEnum.day
|
|
204
192
|
) -> Charts:
|
|
205
193
|
return await self._generate_model_instance(
|
|
206
194
|
f"https://api.{self.domain}/server/{quote(ip)}/{port}/chart/{chart}",
|
|
207
195
|
Charts,
|
|
208
|
-
"charts"
|
|
196
|
+
"charts",
|
|
209
197
|
)
|
|
210
198
|
|
|
211
199
|
async def server_history(self, ip: str, port: int | str) -> None:
|
|
@@ -218,28 +206,22 @@ class Status(API):
|
|
|
218
206
|
|
|
219
207
|
async def clan_list(self) -> ListPl:
|
|
220
208
|
return await self._generate_model_instance(
|
|
221
|
-
f"https://api.{self.domain}/clan/list",
|
|
222
|
-
ListPl,
|
|
223
|
-
"data"
|
|
209
|
+
f"https://api.{self.domain}/clan/list", ListPl, "data"
|
|
224
210
|
)
|
|
225
211
|
|
|
226
212
|
async def clan(self, name: str) -> ListPlData:
|
|
227
213
|
return await self._generate_model_instance(
|
|
228
|
-
f"https://api.{self.domain}/clan/name/{quote(name)}",
|
|
229
|
-
ListPlData
|
|
214
|
+
f"https://api.{self.domain}/clan/name/{quote(name)}", ListPlData
|
|
230
215
|
)
|
|
231
216
|
|
|
232
217
|
async def player_list(self) -> ListPl:
|
|
233
218
|
return await self._generate_model_instance(
|
|
234
|
-
f"https://api.{self.domain}/player/list",
|
|
235
|
-
ListPl,
|
|
236
|
-
"data"
|
|
219
|
+
f"https://api.{self.domain}/player/list", ListPl, "data"
|
|
237
220
|
)
|
|
238
221
|
|
|
239
222
|
async def player(self, name: str) -> ListPlData:
|
|
240
223
|
return await self._generate_model_instance(
|
|
241
|
-
f"https://api.{self.domain}/player/name/{quote(name)}",
|
|
242
|
-
ListPlData
|
|
224
|
+
f"https://api.{self.domain}/player/name/{quote(name)}", ListPlData
|
|
243
225
|
)
|
|
244
226
|
|
|
245
227
|
async def player_history(self, name: str) -> None:
|
|
@@ -248,8 +230,7 @@ class Status(API):
|
|
|
248
230
|
|
|
249
231
|
async def stats(self) -> Stats:
|
|
250
232
|
return await self._generate_model_instance(
|
|
251
|
-
f"https://api.{self.domain}/stats",
|
|
252
|
-
Stats
|
|
233
|
+
f"https://api.{self.domain}/stats", Stats
|
|
253
234
|
)
|
|
254
235
|
|
|
255
236
|
async def stats_players(self, t: str) -> None:
|
|
@@ -2,7 +2,23 @@ from typing import Optional
|
|
|
2
2
|
|
|
3
3
|
from pydantic import BaseModel, Field
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
class DRank(BaseModel):
|
|
7
|
+
points: Optional[int] = None
|
|
8
|
+
rank: Optional[int] = None
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class DPoints(BaseModel):
|
|
12
|
+
total: int
|
|
13
|
+
points: Optional[int] = Field(default=None)
|
|
14
|
+
rank: Optional[int] = Field(default=None)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class DData(BaseModel):
|
|
18
|
+
points: Optional[DPoints] = Field(default=None)
|
|
19
|
+
team_rank: Optional[DRank] = Field(default=None)
|
|
20
|
+
rank: Optional[DRank] = Field(default=None)
|
|
21
|
+
maps: Optional[dict] = Field(default=None)
|
|
6
22
|
|
|
7
23
|
|
|
8
24
|
class DDType(BaseModel):
|
|
@@ -5,17 +5,11 @@ from typing import Optional, Any
|
|
|
5
5
|
|
|
6
6
|
from pydantic import BaseModel, Field
|
|
7
7
|
|
|
8
|
-
from .base import DDType
|
|
8
|
+
from .base import DRank, DDType, DPoints
|
|
9
9
|
|
|
10
10
|
rm_list = ["DD-Persian", "/vDQMHSss8W", ""]
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
class DPoints(BaseModel):
|
|
14
|
-
total: int
|
|
15
|
-
points: Optional[int] = Field(default=None)
|
|
16
|
-
rank: Optional[int] = Field(default=None)
|
|
17
|
-
|
|
18
|
-
|
|
19
13
|
class MaxFinishes(BaseModel):
|
|
20
14
|
rank: int
|
|
21
15
|
player: str
|
|
@@ -65,11 +59,6 @@ class DMap(BaseModel):
|
|
|
65
59
|
max_finishes: list[MaxFinishes]
|
|
66
60
|
|
|
67
61
|
|
|
68
|
-
class DRank(BaseModel):
|
|
69
|
-
points: Optional[int] = None
|
|
70
|
-
rank: Optional[int] = None
|
|
71
|
-
|
|
72
|
-
|
|
73
62
|
class FirstFinish(BaseModel):
|
|
74
63
|
timestamp: float
|
|
75
64
|
map: str
|
|
@@ -89,13 +78,6 @@ class FavoritePartner(BaseModel):
|
|
|
89
78
|
finishes: int
|
|
90
79
|
|
|
91
80
|
|
|
92
|
-
class DData(BaseModel):
|
|
93
|
-
points: Optional[DPoints] = Field(default=None)
|
|
94
|
-
team_rank: Optional[DRank] = Field(default=None)
|
|
95
|
-
rank: Optional[DRank] = Field(default=None)
|
|
96
|
-
maps: Optional[dict] = Field(default=None)
|
|
97
|
-
|
|
98
|
-
|
|
99
81
|
class Activity(BaseModel):
|
|
100
82
|
date: str
|
|
101
83
|
hours_played: int
|
|
@@ -221,17 +203,20 @@ class Master(BaseModel):
|
|
|
221
203
|
count_clients=i.count_client,
|
|
222
204
|
address=i.addresses[0],
|
|
223
205
|
game_type=i.info.game_type,
|
|
224
|
-
name=i.info.name
|
|
206
|
+
name=i.info.name,
|
|
225
207
|
)
|
|
226
208
|
if isinstance(i.addresses, list)
|
|
227
209
|
else CountServers(
|
|
228
210
|
count_clients=i.count_client,
|
|
229
211
|
address=i.addresses,
|
|
230
212
|
game_type=i.info.game_type,
|
|
231
|
-
name=i.info.name
|
|
213
|
+
name=i.info.name,
|
|
232
214
|
)
|
|
233
215
|
for i in self.servers
|
|
234
|
-
),
|
|
216
|
+
),
|
|
217
|
+
key=lambda x: x.count_clients,
|
|
218
|
+
reverse=True,
|
|
219
|
+
)
|
|
235
220
|
|
|
236
221
|
@property
|
|
237
222
|
def count_clients(self) -> int:
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ddapi
|
|
3
|
-
Version: 0.12.
|
|
3
|
+
Version: 0.12.1
|
|
4
4
|
Summary: DDnet api
|
|
5
5
|
Home-page: https://github.com/ByFox213/ddapi
|
|
6
6
|
Author: ByFox
|
|
7
7
|
License: MIT
|
|
8
8
|
Project-URL: Github, https://github.com/ByFox213/ddapi
|
|
9
|
-
Requires-Python: >=3.
|
|
9
|
+
Requires-Python: >=3.10
|
|
10
10
|
Description-Content-Type: text/markdown
|
|
11
11
|
License-File: LICENSE
|
|
12
12
|
Dynamic: author
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[metadata]
|
|
2
2
|
name = ddapi
|
|
3
|
-
version = 0.12.
|
|
3
|
+
version = 0.12.1
|
|
4
4
|
author = ByFox
|
|
5
5
|
description = DDnet api
|
|
6
6
|
long_description = file: README.md
|
|
@@ -14,7 +14,7 @@ license_files = LICENSE
|
|
|
14
14
|
package_dir =
|
|
15
15
|
= ddapi
|
|
16
16
|
packages = find:
|
|
17
|
-
python_requires = >=3.
|
|
17
|
+
python_requires = >=3.10
|
|
18
18
|
|
|
19
19
|
[options.packages.find]
|
|
20
20
|
where = ddapi
|
|
@@ -5,17 +5,15 @@ with open("README.md", "r", encoding="utf-8") as fh:
|
|
|
5
5
|
|
|
6
6
|
setuptools.setup(
|
|
7
7
|
name="ddapi",
|
|
8
|
-
version="0.12.
|
|
8
|
+
version="0.12.1",
|
|
9
9
|
author="ByFox",
|
|
10
10
|
description="DDnet api",
|
|
11
11
|
long_description=long_description,
|
|
12
12
|
long_description_content_type="text/markdown",
|
|
13
13
|
url="https://github.com/ByFox213/ddapi",
|
|
14
14
|
license="MIT",
|
|
15
|
-
project_urls={
|
|
16
|
-
"Github": "https://github.com/ByFox213/ddapi"
|
|
17
|
-
},
|
|
15
|
+
project_urls={"Github": "https://github.com/ByFox213/ddapi"},
|
|
18
16
|
package_dir={"": "ddapi"},
|
|
19
17
|
packages=setuptools.find_packages(where="ddapi"),
|
|
20
|
-
python_requires=">=3.
|
|
18
|
+
python_requires=">=3.10",
|
|
21
19
|
)
|
|
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
|