fortnite-api-sdk 0.1.0__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.
- fortnite_api/__init__.py +9 -0
- fortnite_api/_transport.py +226 -0
- fortnite_api/client.py +102 -0
- fortnite_api/errors.py +16 -0
- fortnite_api/models.py +236 -0
- fortnite_api/py.typed +0 -0
- fortnite_api/resources/__init__.py +71 -0
- fortnite_api/resources/_base.py +6 -0
- fortnite_api/resources/account.py +128 -0
- fortnite_api/resources/aes.py +32 -0
- fortnite_api/resources/assets.py +32 -0
- fortnite_api/resources/battlepass.py +20 -0
- fortnite_api/resources/calendar.py +19 -0
- fortnite_api/resources/cosmetics.py +47 -0
- fortnite_api/resources/crew.py +32 -0
- fortnite_api/resources/events.py +56 -0
- fortnite_api/resources/fn.py +116 -0
- fortnite_api/resources/friends.py +104 -0
- fortnite_api/resources/map.py +39 -0
- fortnite_api/resources/news.py +56 -0
- fortnite_api/resources/oauth.py +92 -0
- fortnite_api/resources/parsing.py +145 -0
- fortnite_api/resources/playlists.py +44 -0
- fortnite_api/resources/profile.py +80 -0
- fortnite_api/resources/quests.py +20 -0
- fortnite_api/resources/replays.py +124 -0
- fortnite_api/resources/shop.py +19 -0
- fortnite_api/resources/stats.py +44 -0
- fortnite_api/resources/tournaments.py +212 -0
- fortnite_api/resources/weapons.py +43 -0
- fortnite_api_sdk-0.1.0.dist-info/METADATA +541 -0
- fortnite_api_sdk-0.1.0.dist-info/RECORD +34 -0
- fortnite_api_sdk-0.1.0.dist-info/WHEEL +4 -0
- fortnite_api_sdk-0.1.0.dist-info/licenses/LICENSE +21 -0
fortnite_api/__init__.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from . import models
|
|
4
|
+
from .client import AsyncFortniteAPI, FortniteAPI
|
|
5
|
+
from .errors import FortniteAPIError
|
|
6
|
+
|
|
7
|
+
__version__ = "0.1.0"
|
|
8
|
+
|
|
9
|
+
__all__ = ["FortniteAPI", "AsyncFortniteAPI", "FortniteAPIError", "models", "__version__"]
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from typing import Any, BinaryIO, Union
|
|
5
|
+
|
|
6
|
+
import httpx
|
|
7
|
+
from pydantic import BaseModel
|
|
8
|
+
|
|
9
|
+
from .errors import FortniteAPIError
|
|
10
|
+
|
|
11
|
+
DEFAULT_BASE_URL = "https://prod.api-fortnite.com/api"
|
|
12
|
+
|
|
13
|
+
FileInput = Union[bytes, bytearray, BinaryIO, str]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class _BaseTransport:
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
api_key: str,
|
|
20
|
+
base_url: str = DEFAULT_BASE_URL,
|
|
21
|
+
timeout: float = 30.0,
|
|
22
|
+
fortnite_token: str | None = None,
|
|
23
|
+
) -> None:
|
|
24
|
+
if not api_key:
|
|
25
|
+
raise ValueError("api_key is required")
|
|
26
|
+
self.api_key = api_key
|
|
27
|
+
self.base_url = base_url.rstrip("/")
|
|
28
|
+
self.root_url = self.base_url[:-4] if self.base_url.endswith("/api") else self.base_url
|
|
29
|
+
self.timeout = timeout
|
|
30
|
+
self.fortnite_token = fortnite_token
|
|
31
|
+
|
|
32
|
+
def _url(self, path: str, version: str | None) -> str:
|
|
33
|
+
if version is None:
|
|
34
|
+
return f"{self.root_url}{path}"
|
|
35
|
+
return f"{self.base_url}/{version}{path}"
|
|
36
|
+
|
|
37
|
+
def _headers(self, fortnite_token: str | None, json: bool = True) -> dict[str, str]:
|
|
38
|
+
headers = {"x-api-key": self.api_key}
|
|
39
|
+
if json:
|
|
40
|
+
headers["Content-Type"] = "application/json"
|
|
41
|
+
token = fortnite_token or self.fortnite_token
|
|
42
|
+
if token:
|
|
43
|
+
headers["x-fortnite-token"] = token
|
|
44
|
+
return headers
|
|
45
|
+
|
|
46
|
+
@staticmethod
|
|
47
|
+
def _clean(params: dict[str, Any] | None) -> dict[str, Any] | None:
|
|
48
|
+
if not params:
|
|
49
|
+
return None
|
|
50
|
+
cleaned = {k: v for k, v in params.items() if v is not None}
|
|
51
|
+
return cleaned or None
|
|
52
|
+
|
|
53
|
+
@staticmethod
|
|
54
|
+
def _error(resp: httpx.Response) -> FortniteAPIError:
|
|
55
|
+
try:
|
|
56
|
+
data: Any = resp.json()
|
|
57
|
+
except Exception:
|
|
58
|
+
data = {"error": "Request failed"}
|
|
59
|
+
message = None
|
|
60
|
+
if isinstance(data, dict):
|
|
61
|
+
message = data.get("error") or data.get("title") or data.get("detail")
|
|
62
|
+
return FortniteAPIError(message or f"Request failed with status {resp.status_code}", resp.status_code, data)
|
|
63
|
+
|
|
64
|
+
@staticmethod
|
|
65
|
+
def _parse(data: Any, model: type[BaseModel] | None, is_list: bool) -> Any:
|
|
66
|
+
if model is None:
|
|
67
|
+
return data
|
|
68
|
+
if is_list:
|
|
69
|
+
if isinstance(data, dict):
|
|
70
|
+
lists = [v for v in data.values() if isinstance(v, list)]
|
|
71
|
+
if len(lists) == 1:
|
|
72
|
+
data = lists[0]
|
|
73
|
+
return [model.model_validate(item) for item in data]
|
|
74
|
+
return model.model_validate(data)
|
|
75
|
+
|
|
76
|
+
@staticmethod
|
|
77
|
+
def _unwrap(data: Any) -> Any:
|
|
78
|
+
if isinstance(data, dict):
|
|
79
|
+
if "success" in data:
|
|
80
|
+
if not data.get("success"):
|
|
81
|
+
raise FortniteAPIError(data.get("error") or "Request failed", 422, data)
|
|
82
|
+
if "data" in data:
|
|
83
|
+
return data["data"]
|
|
84
|
+
if "results" in data:
|
|
85
|
+
return data["results"]
|
|
86
|
+
elif "data" in data and "status" in data:
|
|
87
|
+
return data["data"]
|
|
88
|
+
return data
|
|
89
|
+
|
|
90
|
+
@staticmethod
|
|
91
|
+
def _file_tuple(file: FileInput, filename: str | None) -> tuple[str, bytes, str]:
|
|
92
|
+
if isinstance(file, str):
|
|
93
|
+
with open(file, "rb") as handle:
|
|
94
|
+
content = handle.read()
|
|
95
|
+
name = filename or os.path.basename(file)
|
|
96
|
+
elif isinstance(file, (bytes, bytearray)):
|
|
97
|
+
content = bytes(file)
|
|
98
|
+
name = filename or "replay.replay"
|
|
99
|
+
else:
|
|
100
|
+
content = file.read()
|
|
101
|
+
name = filename or getattr(file, "name", "replay.replay")
|
|
102
|
+
return (name, content, "application/octet-stream")
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class SyncTransport(_BaseTransport):
|
|
106
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
107
|
+
super().__init__(*args, **kwargs)
|
|
108
|
+
self._client = httpx.Client(timeout=self.timeout, follow_redirects=True)
|
|
109
|
+
|
|
110
|
+
def close(self) -> None:
|
|
111
|
+
self._client.close()
|
|
112
|
+
|
|
113
|
+
def request(
|
|
114
|
+
self,
|
|
115
|
+
method: str,
|
|
116
|
+
path: str,
|
|
117
|
+
version: str | None,
|
|
118
|
+
*,
|
|
119
|
+
params: dict[str, Any] | None = None,
|
|
120
|
+
json_body: Any = None,
|
|
121
|
+
fortnite_token: str | None = None,
|
|
122
|
+
model: type[BaseModel] | None = None,
|
|
123
|
+
is_list: bool = False,
|
|
124
|
+
) -> Any:
|
|
125
|
+
resp = self._client.request(
|
|
126
|
+
method,
|
|
127
|
+
self._url(path, version),
|
|
128
|
+
params=self._clean(params),
|
|
129
|
+
json=json_body,
|
|
130
|
+
headers=self._headers(fortnite_token),
|
|
131
|
+
)
|
|
132
|
+
if not resp.is_success:
|
|
133
|
+
raise self._error(resp)
|
|
134
|
+
return self._parse(self._unwrap(resp.json()), model, is_list)
|
|
135
|
+
|
|
136
|
+
def request_binary(self, path: str, version: str | None, *, fortnite_token: str | None = None) -> bytes:
|
|
137
|
+
resp = self._client.get(self._url(path, version), headers=self._headers(fortnite_token, json=False))
|
|
138
|
+
if not resp.is_success:
|
|
139
|
+
raise self._error(resp)
|
|
140
|
+
return resp.content
|
|
141
|
+
|
|
142
|
+
def request_redirect(
|
|
143
|
+
self, path: str, version: str | None, *, params: dict[str, Any] | None = None, fortnite_token: str | None = None
|
|
144
|
+
) -> str | None:
|
|
145
|
+
resp = self._client.get(
|
|
146
|
+
self._url(path, version),
|
|
147
|
+
params=self._clean(params),
|
|
148
|
+
headers=self._headers(fortnite_token, json=False),
|
|
149
|
+
follow_redirects=False,
|
|
150
|
+
)
|
|
151
|
+
if resp.is_redirect:
|
|
152
|
+
return resp.headers.get("location")
|
|
153
|
+
if resp.is_success:
|
|
154
|
+
return str(resp.url)
|
|
155
|
+
raise self._error(resp)
|
|
156
|
+
|
|
157
|
+
def request_multipart(
|
|
158
|
+
self, path: str, files: Any, *, model: type[BaseModel] | None = None, is_list: bool = False, unwrap: bool = True
|
|
159
|
+
) -> Any:
|
|
160
|
+
resp = self._client.post(self._url(path, "v1"), headers=self._headers(None, json=False), files=files)
|
|
161
|
+
if not resp.is_success:
|
|
162
|
+
raise self._error(resp)
|
|
163
|
+
data = self._unwrap(resp.json()) if unwrap else resp.json()
|
|
164
|
+
return self._parse(data, model, is_list)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
class AsyncTransport(_BaseTransport):
|
|
168
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
169
|
+
super().__init__(*args, **kwargs)
|
|
170
|
+
self._client = httpx.AsyncClient(timeout=self.timeout, follow_redirects=True)
|
|
171
|
+
|
|
172
|
+
async def close(self) -> None:
|
|
173
|
+
await self._client.aclose()
|
|
174
|
+
|
|
175
|
+
async def request(
|
|
176
|
+
self,
|
|
177
|
+
method: str,
|
|
178
|
+
path: str,
|
|
179
|
+
version: str | None,
|
|
180
|
+
*,
|
|
181
|
+
params: dict[str, Any] | None = None,
|
|
182
|
+
json_body: Any = None,
|
|
183
|
+
fortnite_token: str | None = None,
|
|
184
|
+
model: type[BaseModel] | None = None,
|
|
185
|
+
is_list: bool = False,
|
|
186
|
+
) -> Any:
|
|
187
|
+
resp = await self._client.request(
|
|
188
|
+
method,
|
|
189
|
+
self._url(path, version),
|
|
190
|
+
params=self._clean(params),
|
|
191
|
+
json=json_body,
|
|
192
|
+
headers=self._headers(fortnite_token),
|
|
193
|
+
)
|
|
194
|
+
if not resp.is_success:
|
|
195
|
+
raise self._error(resp)
|
|
196
|
+
return self._parse(self._unwrap(resp.json()), model, is_list)
|
|
197
|
+
|
|
198
|
+
async def request_binary(self, path: str, version: str | None, *, fortnite_token: str | None = None) -> bytes:
|
|
199
|
+
resp = await self._client.get(self._url(path, version), headers=self._headers(fortnite_token, json=False))
|
|
200
|
+
if not resp.is_success:
|
|
201
|
+
raise self._error(resp)
|
|
202
|
+
return resp.content
|
|
203
|
+
|
|
204
|
+
async def request_redirect(
|
|
205
|
+
self, path: str, version: str | None, *, params: dict[str, Any] | None = None, fortnite_token: str | None = None
|
|
206
|
+
) -> str | None:
|
|
207
|
+
resp = await self._client.get(
|
|
208
|
+
self._url(path, version),
|
|
209
|
+
params=self._clean(params),
|
|
210
|
+
headers=self._headers(fortnite_token, json=False),
|
|
211
|
+
follow_redirects=False,
|
|
212
|
+
)
|
|
213
|
+
if resp.is_redirect:
|
|
214
|
+
return resp.headers.get("location")
|
|
215
|
+
if resp.is_success:
|
|
216
|
+
return str(resp.url)
|
|
217
|
+
raise self._error(resp)
|
|
218
|
+
|
|
219
|
+
async def request_multipart(
|
|
220
|
+
self, path: str, files: Any, *, model: type[BaseModel] | None = None, is_list: bool = False, unwrap: bool = True
|
|
221
|
+
) -> Any:
|
|
222
|
+
resp = await self._client.post(self._url(path, "v1"), headers=self._headers(None, json=False), files=files)
|
|
223
|
+
if not resp.is_success:
|
|
224
|
+
raise self._error(resp)
|
|
225
|
+
data = self._unwrap(resp.json()) if unwrap else resp.json()
|
|
226
|
+
return self._parse(data, model, is_list)
|
fortnite_api/client.py
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from ._transport import DEFAULT_BASE_URL, AsyncTransport, SyncTransport
|
|
6
|
+
from .resources import AccountResource, AsyncAccountResource, AesResource, AsyncAesResource, AssetsResource, AsyncAssetsResource, CalendarResource, AsyncCalendarResource, CosmeticsResource, AsyncCosmeticsResource, CrewResource, AsyncCrewResource, EventsResource, AsyncEventsResource, FNResource, AsyncFNResource, FriendsResource, AsyncFriendsResource, MapResource, AsyncMapResource, NewsResource, AsyncNewsResource, OAuthResource, AsyncOAuthResource, ParsingResource, AsyncParsingResource, PlaylistsResource, AsyncPlaylistsResource, ProfileResource, AsyncProfileResource, QuestsResource, AsyncQuestsResource, ReplaysResource, AsyncReplaysResource, ShopResource, AsyncShopResource, BattlePassResource, AsyncBattlePassResource, StatsResource, AsyncStatsResource, TournamentsResource, AsyncTournamentsResource, WeaponsResource, AsyncWeaponsResource
|
|
7
|
+
|
|
8
|
+
class FortniteAPI:
|
|
9
|
+
"""Client for the Fortnite API (https://api-fortnite.com)."""
|
|
10
|
+
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
api_key: str,
|
|
14
|
+
*,
|
|
15
|
+
base_url: str = DEFAULT_BASE_URL,
|
|
16
|
+
timeout: float = 30.0,
|
|
17
|
+
fortnite_token: str | None = None,
|
|
18
|
+
) -> None:
|
|
19
|
+
self._t = SyncTransport(api_key, base_url, timeout, fortnite_token)
|
|
20
|
+
self.account = AccountResource(self._t)
|
|
21
|
+
self.aes = AesResource(self._t)
|
|
22
|
+
self.assets = AssetsResource(self._t)
|
|
23
|
+
self.calendar = CalendarResource(self._t)
|
|
24
|
+
self.cosmetics = CosmeticsResource(self._t)
|
|
25
|
+
self.crew = CrewResource(self._t)
|
|
26
|
+
self.events = EventsResource(self._t)
|
|
27
|
+
self.fn = FNResource(self._t)
|
|
28
|
+
self.friends = FriendsResource(self._t)
|
|
29
|
+
self.map = MapResource(self._t)
|
|
30
|
+
self.news = NewsResource(self._t)
|
|
31
|
+
self.oauth = OAuthResource(self._t)
|
|
32
|
+
self.parsing = ParsingResource(self._t)
|
|
33
|
+
self.playlists = PlaylistsResource(self._t)
|
|
34
|
+
self.profile = ProfileResource(self._t)
|
|
35
|
+
self.quests = QuestsResource(self._t)
|
|
36
|
+
self.replays = ReplaysResource(self._t)
|
|
37
|
+
self.shop = ShopResource(self._t)
|
|
38
|
+
self.battlepass = BattlePassResource(self._t)
|
|
39
|
+
self.stats = StatsResource(self._t)
|
|
40
|
+
self.tournaments = TournamentsResource(self._t)
|
|
41
|
+
self.weapons = WeaponsResource(self._t)
|
|
42
|
+
|
|
43
|
+
def health(self) -> Any:
|
|
44
|
+
return self._t.request("GET", "/health", None, model=None, is_list=False)
|
|
45
|
+
|
|
46
|
+
def close(self) -> None:
|
|
47
|
+
self._t.close()
|
|
48
|
+
|
|
49
|
+
def __enter__(self) -> FortniteAPI:
|
|
50
|
+
return self
|
|
51
|
+
|
|
52
|
+
def __exit__(self, *exc: Any) -> None:
|
|
53
|
+
self.close()
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class AsyncFortniteAPI:
|
|
57
|
+
"""Client for the Fortnite API (https://api-fortnite.com)."""
|
|
58
|
+
|
|
59
|
+
def __init__(
|
|
60
|
+
self,
|
|
61
|
+
api_key: str,
|
|
62
|
+
*,
|
|
63
|
+
base_url: str = DEFAULT_BASE_URL,
|
|
64
|
+
timeout: float = 30.0,
|
|
65
|
+
fortnite_token: str | None = None,
|
|
66
|
+
) -> None:
|
|
67
|
+
self._t = AsyncTransport(api_key, base_url, timeout, fortnite_token)
|
|
68
|
+
self.account = AsyncAccountResource(self._t)
|
|
69
|
+
self.aes = AsyncAesResource(self._t)
|
|
70
|
+
self.assets = AsyncAssetsResource(self._t)
|
|
71
|
+
self.calendar = AsyncCalendarResource(self._t)
|
|
72
|
+
self.cosmetics = AsyncCosmeticsResource(self._t)
|
|
73
|
+
self.crew = AsyncCrewResource(self._t)
|
|
74
|
+
self.events = AsyncEventsResource(self._t)
|
|
75
|
+
self.fn = AsyncFNResource(self._t)
|
|
76
|
+
self.friends = AsyncFriendsResource(self._t)
|
|
77
|
+
self.map = AsyncMapResource(self._t)
|
|
78
|
+
self.news = AsyncNewsResource(self._t)
|
|
79
|
+
self.oauth = AsyncOAuthResource(self._t)
|
|
80
|
+
self.parsing = AsyncParsingResource(self._t)
|
|
81
|
+
self.playlists = AsyncPlaylistsResource(self._t)
|
|
82
|
+
self.profile = AsyncProfileResource(self._t)
|
|
83
|
+
self.quests = AsyncQuestsResource(self._t)
|
|
84
|
+
self.replays = AsyncReplaysResource(self._t)
|
|
85
|
+
self.shop = AsyncShopResource(self._t)
|
|
86
|
+
self.battlepass = AsyncBattlePassResource(self._t)
|
|
87
|
+
self.stats = AsyncStatsResource(self._t)
|
|
88
|
+
self.tournaments = AsyncTournamentsResource(self._t)
|
|
89
|
+
self.weapons = AsyncWeaponsResource(self._t)
|
|
90
|
+
|
|
91
|
+
async def health(self) -> Any:
|
|
92
|
+
return await self._t.request("GET", "/health", None, model=None, is_list=False)
|
|
93
|
+
|
|
94
|
+
async def close(self) -> None:
|
|
95
|
+
await self._t.close()
|
|
96
|
+
|
|
97
|
+
async def __aenter__(self) -> AsyncFortniteAPI:
|
|
98
|
+
return self
|
|
99
|
+
|
|
100
|
+
async def __aexit__(self, *exc: Any) -> None:
|
|
101
|
+
await self.close()
|
|
102
|
+
|
fortnite_api/errors.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class FortniteAPIError(Exception):
|
|
7
|
+
"""Raised when the Fortnite API returns a non-success HTTP status."""
|
|
8
|
+
|
|
9
|
+
def __init__(self, message: str, status: int, data: Any = None) -> None:
|
|
10
|
+
super().__init__(message)
|
|
11
|
+
self.message = message
|
|
12
|
+
self.status = status
|
|
13
|
+
self.data = data
|
|
14
|
+
|
|
15
|
+
def __str__(self) -> str:
|
|
16
|
+
return f"[{self.status}] {self.message}"
|
fortnite_api/models.py
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class FNModel(BaseModel):
|
|
9
|
+
model_config = ConfigDict(populate_by_name=True, extra="allow")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class CompleteOAuthRequest(FNModel):
|
|
13
|
+
flow_id: str | None = Field(default=None, alias="flowId")
|
|
14
|
+
|
|
15
|
+
class CosmeticDto(FNModel):
|
|
16
|
+
id: str | None = None
|
|
17
|
+
type: str | None = None
|
|
18
|
+
name: str | None = None
|
|
19
|
+
description: str | None = None
|
|
20
|
+
rarity: str | None = None
|
|
21
|
+
series: str | None = None
|
|
22
|
+
set: str | None = None
|
|
23
|
+
icon: str | None = None
|
|
24
|
+
introduction: CosmeticIntroductionDto | None = None
|
|
25
|
+
images: CosmeticImagesDto | None = None
|
|
26
|
+
tags: list[str] | None = None
|
|
27
|
+
|
|
28
|
+
class CosmeticDtoPaginatedResultDto(FNModel):
|
|
29
|
+
page: int | None = None
|
|
30
|
+
page_size: int | None = Field(default=None, alias="pageSize")
|
|
31
|
+
total: int | None = None
|
|
32
|
+
total_pages: int | None = Field(default=None, alias="totalPages")
|
|
33
|
+
data: list[CosmeticDto] | None = None
|
|
34
|
+
|
|
35
|
+
class CosmeticImagesDto(FNModel):
|
|
36
|
+
small_icon: str | None = Field(default=None, alias="smallIcon")
|
|
37
|
+
icon: str | None = None
|
|
38
|
+
large_icon: str | None = Field(default=None, alias="largeIcon")
|
|
39
|
+
|
|
40
|
+
class CosmeticIntroductionDto(FNModel):
|
|
41
|
+
chapter: int | None = None
|
|
42
|
+
season: int | None = None
|
|
43
|
+
absolute_season: int | None = Field(default=None, alias="absoluteSeason")
|
|
44
|
+
|
|
45
|
+
class ExchangeCodeRequest(FNModel):
|
|
46
|
+
code: str | None = None
|
|
47
|
+
redirect_uri: str | None = Field(default=None, alias="redirectUri")
|
|
48
|
+
client_id: str | None = Field(default=None, alias="clientId")
|
|
49
|
+
client_secret: str | None = Field(default=None, alias="clientSecret")
|
|
50
|
+
|
|
51
|
+
class LinkAccountRequest(FNModel):
|
|
52
|
+
code: str | None = None
|
|
53
|
+
redirect_uri: str | None = Field(default=None, alias="redirectUri")
|
|
54
|
+
client_id: str | None = Field(default=None, alias="clientId")
|
|
55
|
+
client_secret: str | None = Field(default=None, alias="clientSecret")
|
|
56
|
+
|
|
57
|
+
class MapDataDto(FNModel):
|
|
58
|
+
version: str | None = None
|
|
59
|
+
chapter: int | None = None
|
|
60
|
+
season: int | None = None
|
|
61
|
+
patch: str | None = None
|
|
62
|
+
release_date: str | None = Field(default=None, alias="releaseDate")
|
|
63
|
+
image_url: str | None = Field(default=None, alias="imageUrl")
|
|
64
|
+
pois: list[PoiDto] | None = None
|
|
65
|
+
|
|
66
|
+
class MapHistoryEntryDto(FNModel):
|
|
67
|
+
version: str | None = None
|
|
68
|
+
chapter: int | None = None
|
|
69
|
+
season: int | None = None
|
|
70
|
+
patch: str | None = None
|
|
71
|
+
release_date: str | None = Field(default=None, alias="releaseDate")
|
|
72
|
+
has_image: bool | None = Field(default=None, alias="hasImage")
|
|
73
|
+
image_url: str | None = Field(default=None, alias="imageUrl")
|
|
74
|
+
has_pois: bool | None = Field(default=None, alias="hasPois")
|
|
75
|
+
|
|
76
|
+
class PatchInfoDto(FNModel):
|
|
77
|
+
patch: str | None = None
|
|
78
|
+
is_current: bool | None = Field(default=None, alias="isCurrent")
|
|
79
|
+
archived_at: str | None = Field(default=None, alias="archivedAt")
|
|
80
|
+
weapon_count: int | None = Field(default=None, alias="weaponCount")
|
|
81
|
+
mode_counts: dict[str, int] | None = Field(default=None, alias="modeCounts")
|
|
82
|
+
|
|
83
|
+
class PoiDto(FNModel):
|
|
84
|
+
name: str | None = None
|
|
85
|
+
x: float | None = None
|
|
86
|
+
y: float | None = None
|
|
87
|
+
type: str | None = None
|
|
88
|
+
|
|
89
|
+
class ProblemDetails(FNModel):
|
|
90
|
+
type: str | None = None
|
|
91
|
+
title: str | None = None
|
|
92
|
+
status: int | None = None
|
|
93
|
+
detail: str | None = None
|
|
94
|
+
instance: str | None = None
|
|
95
|
+
|
|
96
|
+
class RarityDefinitionDto(FNModel):
|
|
97
|
+
name: str | None = None
|
|
98
|
+
color: str | None = None
|
|
99
|
+
sort_order: int | None = Field(default=None, alias="sortOrder")
|
|
100
|
+
|
|
101
|
+
class RefreshDeviceRequest(FNModel):
|
|
102
|
+
account_id: str | None = Field(default=None, alias="accountId")
|
|
103
|
+
device_id: str | None = Field(default=None, alias="deviceId")
|
|
104
|
+
secret: str | None = None
|
|
105
|
+
|
|
106
|
+
class RefreshTokenRequest(FNModel):
|
|
107
|
+
refresh_token: str | None = Field(default=None, alias="refreshToken")
|
|
108
|
+
|
|
109
|
+
class SeasonEntryDto(FNModel):
|
|
110
|
+
season_date_begin: str | None = Field(default=None, alias="seasonDateBegin")
|
|
111
|
+
season_date_end: str | None = Field(default=None, alias="seasonDateEnd")
|
|
112
|
+
season_number: int | None = Field(default=None, alias="seasonNumber")
|
|
113
|
+
ex_time: int | None = Field(default=None, alias="exTime")
|
|
114
|
+
|
|
115
|
+
class ShopBundleDto(FNModel):
|
|
116
|
+
name: str | None = None
|
|
117
|
+
info: str | None = None
|
|
118
|
+
items: int | None = None
|
|
119
|
+
regular_price: int | None = Field(default=None, alias="regularPrice")
|
|
120
|
+
final_price: int | None = Field(default=None, alias="finalPrice")
|
|
121
|
+
discount: int | None = None
|
|
122
|
+
|
|
123
|
+
class ShopCatalogEntryDto(FNModel):
|
|
124
|
+
offer_id: str | None = Field(default=None, alias="offerId")
|
|
125
|
+
dev_name: str | None = Field(default=None, alias="devName")
|
|
126
|
+
title: str | None = None
|
|
127
|
+
sort_priority: int | None = Field(default=None, alias="sortPriority")
|
|
128
|
+
prices: list[ShopPriceDto] | None = None
|
|
129
|
+
item_grants: list[ShopItemGrantDto] | None = Field(default=None, alias="itemGrants")
|
|
130
|
+
bundle: ShopBundleDto | None = None
|
|
131
|
+
section_id: str | None = Field(default=None, alias="sectionId")
|
|
132
|
+
section_display_name: str | None = Field(default=None, alias="sectionDisplayName")
|
|
133
|
+
section_priority: int | None = Field(default=None, alias="sectionPriority")
|
|
134
|
+
section_background: str | None = Field(default=None, alias="sectionBackground")
|
|
135
|
+
offer_visual: str | None = Field(default=None, alias="offerVisual")
|
|
136
|
+
style_visuals: list[str] | None = Field(default=None, alias="styleVisuals")
|
|
137
|
+
juno_visual: str | None = Field(default=None, alias="junoVisual")
|
|
138
|
+
tile_size: str | None = Field(default=None, alias="tileSize")
|
|
139
|
+
meta_info: list[ShopMetaInfoDto] | None = Field(default=None, alias="metaInfo")
|
|
140
|
+
|
|
141
|
+
class ShopCosmeticDto(FNModel):
|
|
142
|
+
type: str | None = None
|
|
143
|
+
name: str | None = None
|
|
144
|
+
display_name: str | None = Field(default=None, alias="displayName")
|
|
145
|
+
description: str | None = None
|
|
146
|
+
short_description: str | None = Field(default=None, alias="shortDescription")
|
|
147
|
+
rarity: str | None = None
|
|
148
|
+
images: ShopCosmeticImagesDto | None = None
|
|
149
|
+
set: str | None = None
|
|
150
|
+
introduction: ShopCosmeticIntroductionDto | None = None
|
|
151
|
+
tags: list[str] | None = None
|
|
152
|
+
|
|
153
|
+
class ShopCosmeticImagesDto(FNModel):
|
|
154
|
+
icon: str | None = None
|
|
155
|
+
large_icon: str | None = Field(default=None, alias="largeIcon")
|
|
156
|
+
|
|
157
|
+
class ShopCosmeticIntroductionDto(FNModel):
|
|
158
|
+
chapter: int | None = None
|
|
159
|
+
season: int | None = None
|
|
160
|
+
|
|
161
|
+
class ShopItemGrantDto(FNModel):
|
|
162
|
+
template_id: str | None = Field(default=None, alias="templateId")
|
|
163
|
+
quantity: int | None = None
|
|
164
|
+
cosmetic: ShopCosmeticDto | None = None
|
|
165
|
+
|
|
166
|
+
class ShopMetaInfoDto(FNModel):
|
|
167
|
+
key: str | None = None
|
|
168
|
+
value: str | None = None
|
|
169
|
+
|
|
170
|
+
class ShopPriceDto(FNModel):
|
|
171
|
+
currency_type: str | None = Field(default=None, alias="currencyType")
|
|
172
|
+
regular_price: int | None = Field(default=None, alias="regularPrice")
|
|
173
|
+
final_price: int | None = Field(default=None, alias="finalPrice")
|
|
174
|
+
sale_type: str | None = Field(default=None, alias="saleType")
|
|
175
|
+
|
|
176
|
+
class ShopResponseDto(FNModel):
|
|
177
|
+
refresh_interval_hrs: float | None = Field(default=None, alias="refreshIntervalHrs")
|
|
178
|
+
daily_purchase_hrs: float | None = Field(default=None, alias="dailyPurchaseHrs")
|
|
179
|
+
expiration: str | None = None
|
|
180
|
+
storefronts: list[ShopStorefrontDto] | None = None
|
|
181
|
+
|
|
182
|
+
class ShopStorefrontDto(FNModel):
|
|
183
|
+
name: str | None = None
|
|
184
|
+
catalog_entries: list[ShopCatalogEntryDto] | None = Field(default=None, alias="catalogEntries")
|
|
185
|
+
|
|
186
|
+
class WeaponListItemDto(FNModel):
|
|
187
|
+
id: str | None = None
|
|
188
|
+
display_name: str | None = Field(default=None, alias="displayName")
|
|
189
|
+
description: str | None = None
|
|
190
|
+
rarity: str | None = None
|
|
191
|
+
type: str | None = None
|
|
192
|
+
category: str | None = None
|
|
193
|
+
ammo_type: str | None = Field(default=None, alias="ammoType")
|
|
194
|
+
trigger_type: str | None = Field(default=None, alias="triggerType")
|
|
195
|
+
search_tags: str | None = Field(default=None, alias="searchTags")
|
|
196
|
+
in_current_loot_pool: bool | None = Field(default=None, alias="inCurrentLootPool")
|
|
197
|
+
item_type: str | None = Field(default=None, alias="itemType")
|
|
198
|
+
gamemodes: list[str] | None = None
|
|
199
|
+
patch: str | None = None
|
|
200
|
+
tags: list[str] | None = None
|
|
201
|
+
stats: Any | None = None
|
|
202
|
+
images: Any | None = None
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
__all__ = [
|
|
206
|
+
"CompleteOAuthRequest",
|
|
207
|
+
"CosmeticDto",
|
|
208
|
+
"CosmeticDtoPaginatedResultDto",
|
|
209
|
+
"CosmeticImagesDto",
|
|
210
|
+
"CosmeticIntroductionDto",
|
|
211
|
+
"ExchangeCodeRequest",
|
|
212
|
+
"LinkAccountRequest",
|
|
213
|
+
"MapDataDto",
|
|
214
|
+
"MapHistoryEntryDto",
|
|
215
|
+
"PatchInfoDto",
|
|
216
|
+
"PoiDto",
|
|
217
|
+
"ProblemDetails",
|
|
218
|
+
"RarityDefinitionDto",
|
|
219
|
+
"RefreshDeviceRequest",
|
|
220
|
+
"RefreshTokenRequest",
|
|
221
|
+
"SeasonEntryDto",
|
|
222
|
+
"ShopBundleDto",
|
|
223
|
+
"ShopCatalogEntryDto",
|
|
224
|
+
"ShopCosmeticDto",
|
|
225
|
+
"ShopCosmeticImagesDto",
|
|
226
|
+
"ShopCosmeticIntroductionDto",
|
|
227
|
+
"ShopItemGrantDto",
|
|
228
|
+
"ShopMetaInfoDto",
|
|
229
|
+
"ShopPriceDto",
|
|
230
|
+
"ShopResponseDto",
|
|
231
|
+
"ShopStorefrontDto",
|
|
232
|
+
"WeaponListItemDto",
|
|
233
|
+
]
|
|
234
|
+
|
|
235
|
+
for _m in list(__all__):
|
|
236
|
+
globals()[_m].model_rebuild()
|
fortnite_api/py.typed
ADDED
|
File without changes
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from .account import AccountResource, AsyncAccountResource
|
|
4
|
+
from .aes import AesResource, AsyncAesResource
|
|
5
|
+
from .assets import AssetsResource, AsyncAssetsResource
|
|
6
|
+
from .calendar import CalendarResource, AsyncCalendarResource
|
|
7
|
+
from .cosmetics import CosmeticsResource, AsyncCosmeticsResource
|
|
8
|
+
from .crew import CrewResource, AsyncCrewResource
|
|
9
|
+
from .events import EventsResource, AsyncEventsResource
|
|
10
|
+
from .fn import FNResource, AsyncFNResource
|
|
11
|
+
from .friends import FriendsResource, AsyncFriendsResource
|
|
12
|
+
from .map import MapResource, AsyncMapResource
|
|
13
|
+
from .news import NewsResource, AsyncNewsResource
|
|
14
|
+
from .oauth import OAuthResource, AsyncOAuthResource
|
|
15
|
+
from .parsing import ParsingResource, AsyncParsingResource
|
|
16
|
+
from .playlists import PlaylistsResource, AsyncPlaylistsResource
|
|
17
|
+
from .profile import ProfileResource, AsyncProfileResource
|
|
18
|
+
from .quests import QuestsResource, AsyncQuestsResource
|
|
19
|
+
from .replays import ReplaysResource, AsyncReplaysResource
|
|
20
|
+
from .shop import ShopResource, AsyncShopResource
|
|
21
|
+
from .battlepass import BattlePassResource, AsyncBattlePassResource
|
|
22
|
+
from .stats import StatsResource, AsyncStatsResource
|
|
23
|
+
from .tournaments import TournamentsResource, AsyncTournamentsResource
|
|
24
|
+
from .weapons import WeaponsResource, AsyncWeaponsResource
|
|
25
|
+
|
|
26
|
+
__all__ = [
|
|
27
|
+
"AccountResource",
|
|
28
|
+
"AsyncAccountResource",
|
|
29
|
+
"AesResource",
|
|
30
|
+
"AsyncAesResource",
|
|
31
|
+
"AssetsResource",
|
|
32
|
+
"AsyncAssetsResource",
|
|
33
|
+
"CalendarResource",
|
|
34
|
+
"AsyncCalendarResource",
|
|
35
|
+
"CosmeticsResource",
|
|
36
|
+
"AsyncCosmeticsResource",
|
|
37
|
+
"CrewResource",
|
|
38
|
+
"AsyncCrewResource",
|
|
39
|
+
"EventsResource",
|
|
40
|
+
"AsyncEventsResource",
|
|
41
|
+
"FNResource",
|
|
42
|
+
"AsyncFNResource",
|
|
43
|
+
"FriendsResource",
|
|
44
|
+
"AsyncFriendsResource",
|
|
45
|
+
"MapResource",
|
|
46
|
+
"AsyncMapResource",
|
|
47
|
+
"NewsResource",
|
|
48
|
+
"AsyncNewsResource",
|
|
49
|
+
"OAuthResource",
|
|
50
|
+
"AsyncOAuthResource",
|
|
51
|
+
"ParsingResource",
|
|
52
|
+
"AsyncParsingResource",
|
|
53
|
+
"PlaylistsResource",
|
|
54
|
+
"AsyncPlaylistsResource",
|
|
55
|
+
"ProfileResource",
|
|
56
|
+
"AsyncProfileResource",
|
|
57
|
+
"QuestsResource",
|
|
58
|
+
"AsyncQuestsResource",
|
|
59
|
+
"ReplaysResource",
|
|
60
|
+
"AsyncReplaysResource",
|
|
61
|
+
"ShopResource",
|
|
62
|
+
"AsyncShopResource",
|
|
63
|
+
"BattlePassResource",
|
|
64
|
+
"AsyncBattlePassResource",
|
|
65
|
+
"StatsResource",
|
|
66
|
+
"AsyncStatsResource",
|
|
67
|
+
"TournamentsResource",
|
|
68
|
+
"AsyncTournamentsResource",
|
|
69
|
+
"WeaponsResource",
|
|
70
|
+
"AsyncWeaponsResource",
|
|
71
|
+
]
|