aiosofascore 0.0.4__py3-none-any.whl
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.
- aiosofascore/__init__.py +3 -0
- aiosofascore/api/__init__.py +0 -0
- aiosofascore/api/mixins.py +30 -0
- aiosofascore/api/soccer/__init__.py +0 -0
- aiosofascore/api/soccer/base.py +17 -0
- aiosofascore/api/soccer/categories.py +21 -0
- aiosofascore/api/soccer/event.py +19 -0
- aiosofascore/api/soccer/schemas/__init__.py +1 -0
- aiosofascore/api/soccer/schemas/base.py +289 -0
- aiosofascore/api/soccer/tournaments.py +60 -0
- aiosofascore/exeptions.py +19 -0
- aiosofascore-0.0.4.dist-info/LICENSE +21 -0
- aiosofascore-0.0.4.dist-info/METADATA +77 -0
- aiosofascore-0.0.4.dist-info/RECORD +16 -0
- aiosofascore-0.0.4.dist-info/WHEEL +5 -0
- aiosofascore-0.0.4.dist-info/top_level.txt +1 -0
aiosofascore/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from aiohttp import ClientSession, ClientResponse
|
|
2
|
+
|
|
3
|
+
from ..exeptions import ResponseParseContentError
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ClientSessionManagerMixin:
|
|
7
|
+
async def __aenter__(self):
|
|
8
|
+
headers = {
|
|
9
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 YaBrowser/24.12.0.0 Safari/537.36"
|
|
10
|
+
}
|
|
11
|
+
self.session = ClientSession(headers=headers)
|
|
12
|
+
|
|
13
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
14
|
+
await self.session.close()
|
|
15
|
+
|
|
16
|
+
async def _get(self, path: str, params: dict = None) -> ClientResponse:
|
|
17
|
+
"""
|
|
18
|
+
Executes an HTTP GET request to the given API path.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
path (str): The API path to request.
|
|
22
|
+
params (dict, optional): Query parameters for the request.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
ClientResponse: The response from the API.
|
|
26
|
+
"""
|
|
27
|
+
result = await self.session.get(self.BASE_URL + path, params=params)
|
|
28
|
+
if result.ok:
|
|
29
|
+
return await result.json()
|
|
30
|
+
raise ResponseParseContentError(result, path)
|
|
File without changes
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from aiosofascore.api.mixins import ClientSessionManagerMixin
|
|
2
|
+
from aiosofascore.api.soccer.categories import SoccerCategoriesApi
|
|
3
|
+
from aiosofascore.api.soccer.event import SoccerEventApi
|
|
4
|
+
from aiosofascore.api.soccer.tournaments import SoccerTournamentApi
|
|
5
|
+
|
|
6
|
+
__all__ = ["BaseSoccerApi"]
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BaseSoccerApi(
|
|
10
|
+
ClientSessionManagerMixin, SoccerCategoriesApi, SoccerTournamentApi, SoccerEventApi
|
|
11
|
+
):
|
|
12
|
+
"""
|
|
13
|
+
Base API client for interacting with SofaScore's soccer API.
|
|
14
|
+
Provides methods for fetching soccer categories and tournaments.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
BASE_URL = "https://api.sofascore.com/"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from typing import Union
|
|
2
|
+
|
|
3
|
+
from aiosofascore.api.soccer.schemas.base import CategoryList, Category
|
|
4
|
+
|
|
5
|
+
__all__ = ["SoccerCategoriesApi"]
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SoccerCategoriesApi:
|
|
9
|
+
async def get_categories(self) -> Union[CategoryList, list]:
|
|
10
|
+
"""
|
|
11
|
+
Fetches a list of soccer categories.
|
|
12
|
+
|
|
13
|
+
Returns:
|
|
14
|
+
CategoryList: A list of soccer categories encapsulated in a CategoryList object.
|
|
15
|
+
Returns an empty list if an error occurs during the request or JSON parsing.
|
|
16
|
+
"""
|
|
17
|
+
async with self:
|
|
18
|
+
content = await self._get("api/v1/sport/football/categories/")
|
|
19
|
+
return CategoryList(
|
|
20
|
+
categories=[Category(**category) for category in content["categories"]]
|
|
21
|
+
)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from aiosofascore.api.soccer.schemas.base import PregameTeamForm, H2H, EventManagers
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class SoccerEventApi:
|
|
5
|
+
|
|
6
|
+
async def get_pregame_form(self, event_id: str) -> PregameTeamForm:
|
|
7
|
+
async with self:
|
|
8
|
+
result = self._get(f"api/v1/event/{event_id}/pregame-form")
|
|
9
|
+
return PregameTeamForm(**result)
|
|
10
|
+
|
|
11
|
+
async def get_h2h(self, event_id: str) -> H2H:
|
|
12
|
+
async with self:
|
|
13
|
+
result = self._get(f"api/v1/event/{event_id}/h2h")
|
|
14
|
+
return H2H(**result)
|
|
15
|
+
|
|
16
|
+
async def get_managers(self, event_id: str) -> EventManagers:
|
|
17
|
+
async with self:
|
|
18
|
+
result = self._get(f"api/v1/event/{event_id}/managers")
|
|
19
|
+
return EventManagers(**result)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .base import *
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
from typing import Optional, Iterator
|
|
2
|
+
from pydantic import BaseModel, fields, Field
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Sport(BaseModel):
|
|
6
|
+
"""
|
|
7
|
+
Represents a sport entity with essential attributes.
|
|
8
|
+
|
|
9
|
+
Attributes:
|
|
10
|
+
name (str): Name of the sport.
|
|
11
|
+
slug (str): URL-friendly identifier for the sport.
|
|
12
|
+
id (int): Unique identifier for the sport.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
name: str
|
|
16
|
+
slug: str
|
|
17
|
+
id: int
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Category(BaseModel):
|
|
21
|
+
"""
|
|
22
|
+
Represents a category associated with a sport.
|
|
23
|
+
|
|
24
|
+
Attributes:
|
|
25
|
+
name (str): Name of the category.
|
|
26
|
+
slug (str): URL-friendly identifier for the category.
|
|
27
|
+
sport (Sport): The sport associated with this category.
|
|
28
|
+
priority (Optional[int]): Priority level for the category (if available).
|
|
29
|
+
id (int): Unique identifier for the category.
|
|
30
|
+
flag (str): Country flag or symbol associated with the category.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
name: str
|
|
34
|
+
slug: str
|
|
35
|
+
sport: Sport
|
|
36
|
+
priority: Optional[int] = None
|
|
37
|
+
id: int
|
|
38
|
+
flag: str
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class CategoryList(BaseModel):
|
|
42
|
+
"""
|
|
43
|
+
Represents a list of Category objects with search functionality.
|
|
44
|
+
|
|
45
|
+
Attributes:
|
|
46
|
+
categories (list[Category]): A list containing Category objects.
|
|
47
|
+
|
|
48
|
+
Methods:
|
|
49
|
+
find_all_by_name(name: str, search_amateur: bool = False) -> list[Category]:
|
|
50
|
+
Finds categories by name with an optional search for amateur categories.
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
categories: list[Category]
|
|
54
|
+
|
|
55
|
+
def find_all_by_name(self, name: str, search_amateur=False) -> list[Category]:
|
|
56
|
+
"""
|
|
57
|
+
Finds all categories whose names contain the given substring.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
name (str): The substring to search for in category names.
|
|
61
|
+
search_amateur (bool, optional): Whether to include only amateur categories. Defaults to False.
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
list[Category]: A list of categories matching the criteria.
|
|
65
|
+
"""
|
|
66
|
+
return [
|
|
67
|
+
c
|
|
68
|
+
for c in self.categories
|
|
69
|
+
if name.lower() in c.name.lower()
|
|
70
|
+
and ("amateur" in c.name.lower()) == search_amateur
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
def __iter__(self) -> Iterator[Category]:
|
|
74
|
+
return iter(self.categories)
|
|
75
|
+
|
|
76
|
+
def __getitem__(self, index: int) -> Category:
|
|
77
|
+
return self.categories[index]
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class UniqueTournament(BaseModel):
|
|
81
|
+
"""
|
|
82
|
+
Represents a unique soccer tournament.
|
|
83
|
+
|
|
84
|
+
Attributes:
|
|
85
|
+
name (str): Name of the tournament.
|
|
86
|
+
slug (str): URL-friendly identifier for the tournament.
|
|
87
|
+
primaryColorHex (Optional[str]): Primary color in hexadecimal format.
|
|
88
|
+
secondaryColorHex (Optional[str]): Secondary color in hexadecimal format.
|
|
89
|
+
category (Category): The category associated with the tournament.
|
|
90
|
+
userCount (int): Number of users following the tournament.
|
|
91
|
+
id (int): Unique identifier for the tournament.
|
|
92
|
+
displayInverseHomeAwayTeams (bool): Flag indicating if home/away teams should be inversed in display.
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
name: str
|
|
96
|
+
slug: str
|
|
97
|
+
primaryColorHex: Optional[str] = None
|
|
98
|
+
secondaryColorHex: Optional[str] = None
|
|
99
|
+
category: Category
|
|
100
|
+
userCount: int
|
|
101
|
+
id: int
|
|
102
|
+
displayInverseHomeAwayTeams: bool
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class UniqueTournamentsList(BaseModel):
|
|
106
|
+
unique_tournaments: list[UniqueTournament]
|
|
107
|
+
|
|
108
|
+
def __iter__(self) -> Iterator[UniqueTournament]:
|
|
109
|
+
return iter(self.unique_tournaments)
|
|
110
|
+
|
|
111
|
+
def __getitem__(self, index: int) -> UniqueTournament:
|
|
112
|
+
return self.unique_tournaments[index]
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class Tournament(BaseModel):
|
|
116
|
+
category: Category
|
|
117
|
+
id: int
|
|
118
|
+
is_group: bool = Field(..., alias="isGroup")
|
|
119
|
+
is_live: bool = Field(..., alias="isLive")
|
|
120
|
+
name: str
|
|
121
|
+
priority: int
|
|
122
|
+
slug: str
|
|
123
|
+
uniqueTournament: UniqueTournament
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class Promotion(BaseModel):
|
|
127
|
+
id: int
|
|
128
|
+
text: str
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class Team(BaseModel):
|
|
132
|
+
disabled: bool
|
|
133
|
+
entityType: str
|
|
134
|
+
gender: str
|
|
135
|
+
id: int
|
|
136
|
+
name: str
|
|
137
|
+
name_code: str = Field(..., alias="nameCode")
|
|
138
|
+
national: bool
|
|
139
|
+
short_name: str = Field(..., alias="shortName")
|
|
140
|
+
slug: str
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class StandingsRow(BaseModel):
|
|
144
|
+
descriptions: list[str]
|
|
145
|
+
draws: int
|
|
146
|
+
id: int
|
|
147
|
+
losses: int
|
|
148
|
+
matches: int
|
|
149
|
+
points: int
|
|
150
|
+
position: int
|
|
151
|
+
promotion: Promotion = None
|
|
152
|
+
score_diff_formatted: str = Field(..., alias="scoreDiffFormatted")
|
|
153
|
+
scores_against: int = Field(..., alias="scoresAgainst")
|
|
154
|
+
scores_for: int = Field(..., alias="scoresFor")
|
|
155
|
+
team: Team
|
|
156
|
+
wins: int
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class Standings(BaseModel):
|
|
160
|
+
descriptions: list[str]
|
|
161
|
+
id: int
|
|
162
|
+
name: str
|
|
163
|
+
rows: list[StandingsRow]
|
|
164
|
+
tournament: Tournament
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
class Season(BaseModel):
|
|
168
|
+
name: str
|
|
169
|
+
year: str
|
|
170
|
+
editor: bool
|
|
171
|
+
id: int
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class SeasonList(BaseModel):
|
|
175
|
+
seasons: list[Season]
|
|
176
|
+
|
|
177
|
+
def get_season_by_year(self, year: str) -> Season:
|
|
178
|
+
return next((season for season in self.seasons if season.year == year), None)
|
|
179
|
+
|
|
180
|
+
def get_current_season(self) -> Season:
|
|
181
|
+
return self.seasons[0]
|
|
182
|
+
|
|
183
|
+
def __iter__(self) -> Iterator[Season]:
|
|
184
|
+
return iter(self.seasons)
|
|
185
|
+
|
|
186
|
+
def __getitem__(self, index: int) -> Season:
|
|
187
|
+
return self.seasons[index]
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
class TeamForm(BaseModel):
|
|
191
|
+
avg_rating: str = Field(alias="avgRating")
|
|
192
|
+
form: list[str]
|
|
193
|
+
position: int
|
|
194
|
+
value: str
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
class PregameTeamForm(BaseModel):
|
|
198
|
+
away_team: TeamForm = Field(alias="awayTeam")
|
|
199
|
+
home_team: TeamForm = Field(alias="homeTeam")
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class Duel(BaseModel):
|
|
203
|
+
away_wins: int = Field(alias="awayWins")
|
|
204
|
+
draws: int
|
|
205
|
+
home_wins: int = Field(alias="homeWins")
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class H2H(BaseModel):
|
|
209
|
+
manager_duel: Duel = Field(alias="managerDuel")
|
|
210
|
+
team_duel: Duel = Field(alias="teamDuel")
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
class Manager(BaseModel):
|
|
214
|
+
name: str
|
|
215
|
+
slug: str
|
|
216
|
+
short_name: str = Field(alias="shortName")
|
|
217
|
+
id: str
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
class EventManagers(BaseModel):
|
|
221
|
+
home_manager: Manager = Field(alias="homeManager")
|
|
222
|
+
away_manager: Manager = Field(alias="awayManager")
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
class RoundInfo(BaseModel):
|
|
226
|
+
round: int
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
class City(BaseModel):
|
|
230
|
+
name: str
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
class VenueCoordinates(BaseModel):
|
|
234
|
+
latitude: str
|
|
235
|
+
longtitude: str
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
class Country(BaseModel):
|
|
239
|
+
alpha2: str
|
|
240
|
+
alpha3: str
|
|
241
|
+
name: str
|
|
242
|
+
slug: str
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class Stadium(BaseModel):
|
|
246
|
+
name: str
|
|
247
|
+
capacity: int
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
class Venue(BaseModel):
|
|
251
|
+
city: City
|
|
252
|
+
venue_coordinates: VenueCoordinates = Field(alias="venueCoordinates")
|
|
253
|
+
hidden: bool
|
|
254
|
+
slug: str
|
|
255
|
+
name: str
|
|
256
|
+
capacity: int
|
|
257
|
+
id: int
|
|
258
|
+
country: Country
|
|
259
|
+
stadium: Stadium
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
class Referee(BaseModel):
|
|
263
|
+
name: str
|
|
264
|
+
slug: str
|
|
265
|
+
yellow_cards: int = Field(alias="yellowCards")
|
|
266
|
+
red_cards: int = Field(alias="redCards")
|
|
267
|
+
yellow_red_cards: int = Field(alias="yellowRedCards")
|
|
268
|
+
games: int
|
|
269
|
+
sport: Sport
|
|
270
|
+
id: int
|
|
271
|
+
country: Country
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
class EventTeam(Team):
|
|
275
|
+
sport: Sport
|
|
276
|
+
manager: Manager
|
|
277
|
+
venue: Venue
|
|
278
|
+
country: Country
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
# TODO: Create Prematch,live,fulltime Event
|
|
282
|
+
class Event(BaseModel):
|
|
283
|
+
tournament: Tournament
|
|
284
|
+
season: Season
|
|
285
|
+
round_info: RoundInfo = Field(alias="roundInfo")
|
|
286
|
+
custom_id: str = Field(alias="customId")
|
|
287
|
+
venue: Venue
|
|
288
|
+
home_team: EventTeam = Field(alias="homeTeam")
|
|
289
|
+
away_team: EventTeam = Field(alias="awayTeam")
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from aiosofascore.api.soccer.schemas.base import (
|
|
2
|
+
UniqueTournament,
|
|
3
|
+
Category,
|
|
4
|
+
SeasonList,
|
|
5
|
+
Standings,
|
|
6
|
+
UniqueTournamentsList,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
__all__ = ["SoccerTournamentApi"]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SoccerTournamentApi:
|
|
13
|
+
async def get_tournaments_by_category(
|
|
14
|
+
self, category: Category
|
|
15
|
+
) -> UniqueTournamentsList:
|
|
16
|
+
"""
|
|
17
|
+
Fetches a list of unique tournaments for a given soccer category.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
category (Category): The soccer category for which to retrieve tournaments.
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
list[UniqueTournament]: A list of unique tournaments for the given category.
|
|
24
|
+
"""
|
|
25
|
+
async with self:
|
|
26
|
+
content = await self._get(
|
|
27
|
+
f"api/v1/category/{category.id}/unique-tournaments"
|
|
28
|
+
)
|
|
29
|
+
return UniqueTournamentsList(
|
|
30
|
+
unique_tournaments=content["groups"][0]["uniqueTournaments"]
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
async def get_tournament_seasons(
|
|
34
|
+
self, unique_tournament: UniqueTournament
|
|
35
|
+
) -> SeasonList:
|
|
36
|
+
async with self:
|
|
37
|
+
response = await self._get(
|
|
38
|
+
f"api/v1/unique-tournament/{unique_tournament.id}/seasons"
|
|
39
|
+
)
|
|
40
|
+
seasons = response["seasons"]
|
|
41
|
+
return SeasonList(seasons=seasons)
|
|
42
|
+
|
|
43
|
+
async def get_tournament_standings(
|
|
44
|
+
self, unique_tournament: UniqueTournament, season_year: str = None
|
|
45
|
+
):
|
|
46
|
+
if season_year:
|
|
47
|
+
season = await (
|
|
48
|
+
await self.get_tournament_seasons(unique_tournament)
|
|
49
|
+
).get_season_by_year(season_year)
|
|
50
|
+
else:
|
|
51
|
+
season = await (
|
|
52
|
+
await self.get_tournament_seasons(unique_tournament)
|
|
53
|
+
).get_current_season()
|
|
54
|
+
|
|
55
|
+
async with self:
|
|
56
|
+
response = await self._get(
|
|
57
|
+
f"api/v1/unique-tournament/{unique_tournament.id}/season/{season.id}/standings/home"
|
|
58
|
+
)
|
|
59
|
+
standings = response["standings"][0]
|
|
60
|
+
return Standings(**standings)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from aiohttp import ClientResponse
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ResponseParseContentError(Exception):
|
|
5
|
+
def __init__(self, response: ClientResponse, path: str):
|
|
6
|
+
self._response = response
|
|
7
|
+
self._path = path
|
|
8
|
+
|
|
9
|
+
@property
|
|
10
|
+
def response(self):
|
|
11
|
+
return self._response
|
|
12
|
+
|
|
13
|
+
def __str__(self):
|
|
14
|
+
return (
|
|
15
|
+
"Response processing error:\n"
|
|
16
|
+
f"api call: {self._path}"
|
|
17
|
+
f"response status:{self._response.status}"
|
|
18
|
+
f"response content:{self._response.content}"
|
|
19
|
+
)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: aiosofascore
|
|
3
|
+
Version: 0.0.4
|
|
4
|
+
Summary: API client for SofaScore soccer data
|
|
5
|
+
Home-page: https://github.com/Rooney27/aio_sofascore
|
|
6
|
+
Author: Philip
|
|
7
|
+
Author-email: vasilewskij.fil@gmail.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: aiohttp
|
|
15
|
+
Requires-Dist: pydantic
|
|
16
|
+
Dynamic: author
|
|
17
|
+
Dynamic: author-email
|
|
18
|
+
Dynamic: classifier
|
|
19
|
+
Dynamic: description
|
|
20
|
+
Dynamic: description-content-type
|
|
21
|
+
Dynamic: home-page
|
|
22
|
+
Dynamic: requires-dist
|
|
23
|
+
Dynamic: requires-python
|
|
24
|
+
Dynamic: summary
|
|
25
|
+
|
|
26
|
+

|
|
27
|
+

|
|
28
|
+
|
|
29
|
+
# Aiosofascore
|
|
30
|
+
|
|
31
|
+
**Aiosofascore** is an API client for SofaScore's soccer data, designed to provide easy access to soccer categories, tournaments, events, and much more. It is built with `aiohttp` for asynchronous HTTP requests and can be integrated into any Python project that needs soccer-related data.
|
|
32
|
+
|
|
33
|
+
## Features
|
|
34
|
+
|
|
35
|
+
- Fetch soccer categories and tournaments
|
|
36
|
+
- Get detailed tournament standings and seasons
|
|
37
|
+
- Retrieve pregame forms, head-to-head stats, and event managers
|
|
38
|
+
- Built using Python's asynchronous capabilities with `aiohttp`
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
To install **aiosofascore** from PyPI, run the following command:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install aiosofascore
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
## Usage Example
|
|
49
|
+
|
|
50
|
+
Here's how you can use aiosofascore to get data about football tournaments
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
import asyncio
|
|
54
|
+
from aiosofascore import BaseSoccerApi
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
async def main():
|
|
58
|
+
# Create a client
|
|
59
|
+
client = BaseSoccerApi()
|
|
60
|
+
|
|
61
|
+
# Fetch categories
|
|
62
|
+
categories = await client.get_categories()
|
|
63
|
+
for category in categories:
|
|
64
|
+
print(f"Category: {category.name}")
|
|
65
|
+
|
|
66
|
+
# Fetch tournaments by category
|
|
67
|
+
tournaments = await client.get_tournaments_by_category(categories[0])
|
|
68
|
+
for tournament in tournaments:
|
|
69
|
+
print(f"Tournament: {tournament.name}")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
if __name__ == "__main__":
|
|
73
|
+
asyncio.run(main())
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## License
|
|
77
|
+
This project is licensed under the MIT License — see the LICENSE file for details.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
aiosofascore/__init__.py,sha256=7arRme7PkLjECpXc3uVx1e3ym1OAsIwKrHOHgq3SEEY,72
|
|
2
|
+
aiosofascore/exeptions.py,sha256=g038BodDoqW_HegQX8XGx0QAMnWlHwLJWYrknGx6si8,515
|
|
3
|
+
aiosofascore/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
aiosofascore/api/mixins.py,sha256=FvCyIY4x_Z3G3TOhqAvykQwSK6ZlRdRaFJja3XoNHC4,1067
|
|
5
|
+
aiosofascore/api/soccer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
aiosofascore/api/soccer/base.py,sha256=jPHewJQ7sgibEDG52zk3uuM-DcZWMYLyFG6htocWnz8,592
|
|
7
|
+
aiosofascore/api/soccer/categories.py,sha256=G02dSCJ9HQFsT_US5IWB9ktegUNINhPUNLNcXV8JUs4,731
|
|
8
|
+
aiosofascore/api/soccer/event.py,sha256=zL0GczfnmwPGnhAPBBD11vByu0fvWXBJnzZj4gociwk,700
|
|
9
|
+
aiosofascore/api/soccer/tournaments.py,sha256=zK-OF7vFVD6d4MQT-pF7nAGdd94RcscrirqkuxyRKmE,1969
|
|
10
|
+
aiosofascore/api/soccer/schemas/__init__.py,sha256=ERmmOxz_9mUkIuccNbzUa5Y6gVLLVDdyc4cCxbCCUbY,20
|
|
11
|
+
aiosofascore/api/soccer/schemas/base.py,sha256=WHWLcwcHGT0TTvXqQTtDR-lPpslMYWmY7nn_gocqmb4,7055
|
|
12
|
+
aiosofascore-0.0.4.dist-info/LICENSE,sha256=O-0zMbcEi6wXz1DiSdVgzMlQjJcNqNe5KDv08uYzqR0,1055
|
|
13
|
+
aiosofascore-0.0.4.dist-info/METADATA,sha256=_ZFBttObMPr29YeeoNBs5N72sQKao1t2VvsFHVDH9uA,2195
|
|
14
|
+
aiosofascore-0.0.4.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
15
|
+
aiosofascore-0.0.4.dist-info/top_level.txt,sha256=ClavTMe9yHQjALo6Pa4E1h-HW1HU8Hf5Gx9-j6sRpSQ,13
|
|
16
|
+
aiosofascore-0.0.4.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
aiosofascore
|