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.
@@ -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
+ ]
@@ -0,0 +1,6 @@
1
+ from __future__ import annotations
2
+
3
+
4
+ class Resource:
5
+ def __init__(self, transport: object) -> None:
6
+ self._t = transport