ambr-py 1.7.3__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.
- ambr/__init__.py +3 -0
- ambr/client.py +657 -0
- ambr/exceptions.py +25 -0
- ambr/models/__init__.py +17 -0
- ambr/models/abyss.py +230 -0
- ambr/models/achievement.py +111 -0
- ambr/models/artifact.py +137 -0
- ambr/models/book.py +87 -0
- ambr/models/changelog.py +37 -0
- ambr/models/character.py +288 -0
- ambr/models/character_fetter.py +91 -0
- ambr/models/domain.py +55 -0
- ambr/models/food.py +111 -0
- ambr/models/furniture.py +162 -0
- ambr/models/material.py +116 -0
- ambr/models/monster.py +89 -0
- ambr/models/name_card.py +67 -0
- ambr/models/quest.py +41 -0
- ambr/models/tcg.py +166 -0
- ambr/models/upgrade.py +38 -0
- ambr/models/weapon.py +144 -0
- ambr/utils.py +33 -0
- ambr_py-1.7.3.dist-info/LICENSE +674 -0
- ambr_py-1.7.3.dist-info/METADATA +114 -0
- ambr_py-1.7.3.dist-info/RECORD +26 -0
- ambr_py-1.7.3.dist-info/WHEEL +4 -0
ambr/__init__.py
ADDED
ambr/client.py
ADDED
|
@@ -0,0 +1,657 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from enum import Enum
|
|
3
|
+
from typing import Any, Final
|
|
4
|
+
|
|
5
|
+
from aiohttp_client_cache.backends.sqlite import SQLiteBackend
|
|
6
|
+
from aiohttp_client_cache.session import CachedSession
|
|
7
|
+
|
|
8
|
+
from .exceptions import AmbrAPIError, ConnectionTimeoutError, DataNotFoundError
|
|
9
|
+
from .models import (
|
|
10
|
+
AbyssResponse,
|
|
11
|
+
AchievementCategory,
|
|
12
|
+
ArtifactSet,
|
|
13
|
+
ArtifactSetDetail,
|
|
14
|
+
Book,
|
|
15
|
+
BookDetail,
|
|
16
|
+
Changelog,
|
|
17
|
+
Character,
|
|
18
|
+
CharacterDetail,
|
|
19
|
+
CharacterFetter,
|
|
20
|
+
Domains,
|
|
21
|
+
Food,
|
|
22
|
+
FoodDetail,
|
|
23
|
+
Furniture,
|
|
24
|
+
FurnitureDetail,
|
|
25
|
+
Material,
|
|
26
|
+
MaterialDetail,
|
|
27
|
+
Monster,
|
|
28
|
+
MonsterDetail,
|
|
29
|
+
Namecard,
|
|
30
|
+
NamecardDetail,
|
|
31
|
+
Quest,
|
|
32
|
+
TCGCard,
|
|
33
|
+
TCGCardDetail,
|
|
34
|
+
UpgradeData,
|
|
35
|
+
Weapon,
|
|
36
|
+
WeaponDetail,
|
|
37
|
+
)
|
|
38
|
+
from .models.furniture import FurnitureSet, FurnitureSetDetail
|
|
39
|
+
from .utils import remove_html_tags
|
|
40
|
+
|
|
41
|
+
__all__ = ("AmbrAPI", "Language")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class Language(Enum):
|
|
45
|
+
CHT = "cht"
|
|
46
|
+
CHS = "chs"
|
|
47
|
+
DE = "de"
|
|
48
|
+
EN = "en"
|
|
49
|
+
ES = "es"
|
|
50
|
+
FR = "fr"
|
|
51
|
+
ID = "id"
|
|
52
|
+
JP = "jp"
|
|
53
|
+
KR = "kr"
|
|
54
|
+
PT = "pt"
|
|
55
|
+
RU = "ru"
|
|
56
|
+
TH = "th"
|
|
57
|
+
VI = "vi"
|
|
58
|
+
IT = "it"
|
|
59
|
+
TR = "tr"
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
LOGGER_ = logging.getLogger("ambr.py")
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class AmbrAPI:
|
|
66
|
+
BASE_URL: Final[str] = "https://api.ambr.top/v2"
|
|
67
|
+
|
|
68
|
+
def __init__(
|
|
69
|
+
self,
|
|
70
|
+
*,
|
|
71
|
+
lang: Language = Language.EN,
|
|
72
|
+
cache_ttl: int = 3600,
|
|
73
|
+
headers: dict[str, Any] | None = None,
|
|
74
|
+
) -> None:
|
|
75
|
+
self.lang = lang
|
|
76
|
+
self.cache_ttl = cache_ttl
|
|
77
|
+
|
|
78
|
+
self._session: CachedSession | None = None
|
|
79
|
+
self._cache = SQLiteBackend("./.cache/ambr/aiohttp-cache.db", expire_after=cache_ttl)
|
|
80
|
+
self._headers = headers or {"User-Agent": "ambr-py"}
|
|
81
|
+
|
|
82
|
+
async def __aenter__(self) -> "AmbrAPI":
|
|
83
|
+
await self.start()
|
|
84
|
+
return self
|
|
85
|
+
|
|
86
|
+
async def __aexit__(self, exc_type, exc, tb) -> None: # noqa: ANN001
|
|
87
|
+
await self.close()
|
|
88
|
+
|
|
89
|
+
async def _request(
|
|
90
|
+
self, endpoint: str, *, static: bool = False, use_cache: bool
|
|
91
|
+
) -> dict[str, Any]:
|
|
92
|
+
"""
|
|
93
|
+
A helper function to make requests to the API.
|
|
94
|
+
|
|
95
|
+
Parameters
|
|
96
|
+
----------
|
|
97
|
+
endpoint: :class:`str`
|
|
98
|
+
The endpoint to request from.
|
|
99
|
+
static: :class:`bool`
|
|
100
|
+
Whether to use the static endpoint or not. Defaults to ``False``.
|
|
101
|
+
use_cache: :class:`bool`
|
|
102
|
+
Whether to use the cache or not. Defaults to ``True``.
|
|
103
|
+
|
|
104
|
+
Returns
|
|
105
|
+
-------
|
|
106
|
+
Dict[str, Any]
|
|
107
|
+
The response from the API.
|
|
108
|
+
"""
|
|
109
|
+
if self._session is None:
|
|
110
|
+
msg = "Call `start` before making requests."
|
|
111
|
+
raise RuntimeError(msg)
|
|
112
|
+
|
|
113
|
+
if static:
|
|
114
|
+
url = f"{self.BASE_URL}/static/{endpoint}"
|
|
115
|
+
else:
|
|
116
|
+
url = f"{self.BASE_URL}/{self.lang.value}/{endpoint}"
|
|
117
|
+
|
|
118
|
+
LOGGER_.debug("Requesting %s...", url)
|
|
119
|
+
|
|
120
|
+
if not use_cache:
|
|
121
|
+
async with self._session.disabled(), self._session.get(url) as resp:
|
|
122
|
+
if resp.status != 200:
|
|
123
|
+
self._handle_error(resp.status)
|
|
124
|
+
data = await resp.json()
|
|
125
|
+
else:
|
|
126
|
+
async with self._session.get(url) as resp:
|
|
127
|
+
if resp.status != 200:
|
|
128
|
+
self._handle_error(resp.status)
|
|
129
|
+
data = await resp.json()
|
|
130
|
+
|
|
131
|
+
return data
|
|
132
|
+
|
|
133
|
+
def _handle_error(self, code: int) -> None:
|
|
134
|
+
"""
|
|
135
|
+
A helper function to handle errors.
|
|
136
|
+
"""
|
|
137
|
+
match code:
|
|
138
|
+
case 404:
|
|
139
|
+
raise DataNotFoundError
|
|
140
|
+
case 522 | 524:
|
|
141
|
+
raise ConnectionTimeoutError
|
|
142
|
+
case _:
|
|
143
|
+
raise AmbrAPIError(code)
|
|
144
|
+
|
|
145
|
+
async def start(self) -> None:
|
|
146
|
+
"""
|
|
147
|
+
Starts the client session.
|
|
148
|
+
"""
|
|
149
|
+
self._session = CachedSession(headers=self._headers, cache=self._cache)
|
|
150
|
+
|
|
151
|
+
async def close(self) -> None:
|
|
152
|
+
"""
|
|
153
|
+
Closes the client session.
|
|
154
|
+
"""
|
|
155
|
+
if self._session is not None:
|
|
156
|
+
await self._session.close()
|
|
157
|
+
|
|
158
|
+
async def fetch_achievement_categories(
|
|
159
|
+
self, use_cache: bool = True
|
|
160
|
+
) -> list[AchievementCategory]:
|
|
161
|
+
"""
|
|
162
|
+
Fetches all achievement categories.
|
|
163
|
+
|
|
164
|
+
Returns
|
|
165
|
+
-------
|
|
166
|
+
List[:class:`AchievementCategory`]
|
|
167
|
+
The achievement categories.
|
|
168
|
+
"""
|
|
169
|
+
data = await self._request("achievement", use_cache=use_cache)
|
|
170
|
+
return [
|
|
171
|
+
AchievementCategory(**achievement_category)
|
|
172
|
+
for achievement_category in data["data"].values()
|
|
173
|
+
]
|
|
174
|
+
|
|
175
|
+
async def fetch_artifact_sets(self, use_cache: bool = True) -> list[ArtifactSet]:
|
|
176
|
+
"""
|
|
177
|
+
Fetches all artifact sets.
|
|
178
|
+
|
|
179
|
+
Returns
|
|
180
|
+
-------
|
|
181
|
+
List[:class:`ArtifactSet`]
|
|
182
|
+
The artifact sets.
|
|
183
|
+
"""
|
|
184
|
+
data = await self._request("reliquary", use_cache=use_cache)
|
|
185
|
+
return [ArtifactSet(**artifact_set) for artifact_set in data["data"]["items"].values()]
|
|
186
|
+
|
|
187
|
+
async def fetch_artifact_set_detail(self, id: int, use_cache: bool = True) -> ArtifactSetDetail:
|
|
188
|
+
"""
|
|
189
|
+
Fetches an artifact set detail by ID.
|
|
190
|
+
|
|
191
|
+
Parameters
|
|
192
|
+
----------
|
|
193
|
+
id: :class:`int`
|
|
194
|
+
The ID of the artifact set detail to fetch.
|
|
195
|
+
|
|
196
|
+
Returns
|
|
197
|
+
-------
|
|
198
|
+
:class:`ArtifactSetDetail`
|
|
199
|
+
The artifact set detail.
|
|
200
|
+
"""
|
|
201
|
+
data = await self._request(f"reliquary/{id}", use_cache=use_cache)
|
|
202
|
+
return ArtifactSetDetail(**data["data"])
|
|
203
|
+
|
|
204
|
+
async def fetch_books(self, use_cache: bool = True) -> list[Book]:
|
|
205
|
+
"""
|
|
206
|
+
Fetches all books.
|
|
207
|
+
|
|
208
|
+
Returns
|
|
209
|
+
-------
|
|
210
|
+
List[:class:`Book`]
|
|
211
|
+
The books.
|
|
212
|
+
"""
|
|
213
|
+
data = await self._request("book", use_cache=use_cache)
|
|
214
|
+
return [Book(**book) for book in data["data"]["items"].values()]
|
|
215
|
+
|
|
216
|
+
async def fetch_book_detail(self, id: int, use_cache: bool = True) -> BookDetail:
|
|
217
|
+
"""
|
|
218
|
+
Fetches a book detail by ID.
|
|
219
|
+
|
|
220
|
+
Parameters
|
|
221
|
+
----------
|
|
222
|
+
id: :class:`int`
|
|
223
|
+
The ID of the book detail to fetch.
|
|
224
|
+
|
|
225
|
+
Returns
|
|
226
|
+
-------
|
|
227
|
+
:class:`BookDetail`
|
|
228
|
+
The book detail.
|
|
229
|
+
"""
|
|
230
|
+
data = await self._request(f"book/{id}", use_cache=use_cache)
|
|
231
|
+
return BookDetail(**data["data"])
|
|
232
|
+
|
|
233
|
+
async def fetch_characters(self, use_cache: bool = True) -> list[Character]:
|
|
234
|
+
"""
|
|
235
|
+
Fetches all characters.
|
|
236
|
+
|
|
237
|
+
Returns
|
|
238
|
+
-------
|
|
239
|
+
List[:class:`Character`]
|
|
240
|
+
The characters.
|
|
241
|
+
"""
|
|
242
|
+
data = await self._request("avatar", use_cache=use_cache)
|
|
243
|
+
return [Character(**character) for character in data["data"]["items"].values()]
|
|
244
|
+
|
|
245
|
+
async def fetch_character_detail(self, id: str, use_cache: bool = True) -> CharacterDetail:
|
|
246
|
+
"""
|
|
247
|
+
Fetches a character detail by ID.
|
|
248
|
+
|
|
249
|
+
Parameters
|
|
250
|
+
----------
|
|
251
|
+
id: :class:`str`
|
|
252
|
+
The ID of the character detail to fetch.
|
|
253
|
+
|
|
254
|
+
Returns
|
|
255
|
+
-------
|
|
256
|
+
:class:`CharacterDetail`
|
|
257
|
+
The character detail.
|
|
258
|
+
"""
|
|
259
|
+
data = await self._request(f"avatar/{id}", use_cache=use_cache)
|
|
260
|
+
return CharacterDetail(**data["data"])
|
|
261
|
+
|
|
262
|
+
async def fetch_character_fetter(self, id: str, use_cache: bool = True) -> CharacterFetter:
|
|
263
|
+
"""
|
|
264
|
+
Fetches a character fetter by ID.
|
|
265
|
+
|
|
266
|
+
Parameters
|
|
267
|
+
----------
|
|
268
|
+
id: :class:`str`
|
|
269
|
+
The ID of the character fetter to fetch.
|
|
270
|
+
|
|
271
|
+
Returns
|
|
272
|
+
-------
|
|
273
|
+
:class:`CharacterFetter`
|
|
274
|
+
The character fetter.
|
|
275
|
+
"""
|
|
276
|
+
data = await self._request(f"avatarFetter/{id}", use_cache=use_cache)
|
|
277
|
+
return CharacterFetter(**data["data"])
|
|
278
|
+
|
|
279
|
+
async def fetch_foods(self, use_cache: bool = True) -> list[Food]:
|
|
280
|
+
"""
|
|
281
|
+
Fetches all foods.
|
|
282
|
+
|
|
283
|
+
Returns
|
|
284
|
+
-------
|
|
285
|
+
List[:class:`Food`]
|
|
286
|
+
The foods.
|
|
287
|
+
"""
|
|
288
|
+
data = await self._request("food", use_cache=use_cache)
|
|
289
|
+
return [Food(**food) for food in data["data"]["items"].values()]
|
|
290
|
+
|
|
291
|
+
async def fetch_food_detail(self, id: int, use_cache: bool = True) -> FoodDetail:
|
|
292
|
+
"""
|
|
293
|
+
Fetches a food detail by ID.
|
|
294
|
+
|
|
295
|
+
Parameters
|
|
296
|
+
----------
|
|
297
|
+
id: :class:`int`
|
|
298
|
+
The ID of the food detail to fetch.
|
|
299
|
+
|
|
300
|
+
Returns
|
|
301
|
+
-------
|
|
302
|
+
:class:`FoodDetail`
|
|
303
|
+
The food detail.
|
|
304
|
+
"""
|
|
305
|
+
data = await self._request(f"food/{id}", use_cache=use_cache)
|
|
306
|
+
return FoodDetail(**data["data"])
|
|
307
|
+
|
|
308
|
+
async def fetch_furnitures(self, use_cache: bool = True) -> list[Furniture]:
|
|
309
|
+
"""
|
|
310
|
+
Fetches all furnitures.
|
|
311
|
+
|
|
312
|
+
Returns
|
|
313
|
+
-------
|
|
314
|
+
List[:class:`Furniture`]
|
|
315
|
+
The furnitures.
|
|
316
|
+
"""
|
|
317
|
+
data = await self._request("furniture", use_cache=use_cache)
|
|
318
|
+
return [Furniture(**furniture) for furniture in data["data"]["items"].values()]
|
|
319
|
+
|
|
320
|
+
async def fetch_furniture_detail(self, id: int, use_cache: bool = True) -> FurnitureDetail:
|
|
321
|
+
"""
|
|
322
|
+
Fetches a furniture detail by ID.
|
|
323
|
+
|
|
324
|
+
Parameters
|
|
325
|
+
----------
|
|
326
|
+
id: :class:`int`
|
|
327
|
+
The ID of the furniture detail to fetch.
|
|
328
|
+
|
|
329
|
+
Returns
|
|
330
|
+
-------
|
|
331
|
+
:class:`FurnitureDetail`
|
|
332
|
+
The furniture detail.
|
|
333
|
+
"""
|
|
334
|
+
data = await self._request(f"furniture/{id}", use_cache=use_cache)
|
|
335
|
+
return FurnitureDetail(**data["data"])
|
|
336
|
+
|
|
337
|
+
async def fetch_furniture_sets(self, use_cache: bool = True) -> list[FurnitureSet]:
|
|
338
|
+
"""
|
|
339
|
+
Fetches all furniture sets.
|
|
340
|
+
|
|
341
|
+
Returns
|
|
342
|
+
-------
|
|
343
|
+
List[:class:`FurnitureSet`]
|
|
344
|
+
The furniture sets.
|
|
345
|
+
"""
|
|
346
|
+
data = await self._request("furnitureSuite", use_cache=use_cache)
|
|
347
|
+
return [FurnitureSet(**furniture_set) for furniture_set in data["data"]["items"].values()]
|
|
348
|
+
|
|
349
|
+
async def fetch_furniture_set_detail(
|
|
350
|
+
self, id: int, use_cache: bool = True
|
|
351
|
+
) -> FurnitureSetDetail:
|
|
352
|
+
"""
|
|
353
|
+
Fetches a furniture set detail by ID.
|
|
354
|
+
|
|
355
|
+
Parameters
|
|
356
|
+
----------
|
|
357
|
+
id: :class:`int`
|
|
358
|
+
The ID of the furniture set detail to fetch.
|
|
359
|
+
|
|
360
|
+
Returns
|
|
361
|
+
-------
|
|
362
|
+
:class:`FurnitureSetDetail`
|
|
363
|
+
The furniture set detail.
|
|
364
|
+
"""
|
|
365
|
+
data = await self._request(f"furnitureSuite/{id}", use_cache=use_cache)
|
|
366
|
+
return FurnitureSetDetail(**data["data"])
|
|
367
|
+
|
|
368
|
+
async def fetch_materials(self, use_cache: bool = True) -> list[Material]:
|
|
369
|
+
"""
|
|
370
|
+
Fetches all materials.
|
|
371
|
+
|
|
372
|
+
Returns
|
|
373
|
+
-------
|
|
374
|
+
List[:class:`Material`]
|
|
375
|
+
The materials.
|
|
376
|
+
"""
|
|
377
|
+
data = await self._request("material", use_cache=use_cache)
|
|
378
|
+
return [Material(**material) for material in data["data"]["items"].values()]
|
|
379
|
+
|
|
380
|
+
async def fetch_material_detail(self, id: int, use_cache: bool = True) -> MaterialDetail:
|
|
381
|
+
"""
|
|
382
|
+
Fetches a material detail by ID.
|
|
383
|
+
|
|
384
|
+
Parameters
|
|
385
|
+
----------
|
|
386
|
+
id: :class:`int`
|
|
387
|
+
The ID of the material detail to fetch.
|
|
388
|
+
|
|
389
|
+
Returns
|
|
390
|
+
-------
|
|
391
|
+
:class:`MaterialDetail`
|
|
392
|
+
The material detail.
|
|
393
|
+
"""
|
|
394
|
+
data = await self._request(f"material/{id}", use_cache=use_cache)
|
|
395
|
+
return MaterialDetail(**data["data"])
|
|
396
|
+
|
|
397
|
+
async def fetch_monsters(self, use_cache: bool = True) -> list[Monster]:
|
|
398
|
+
"""
|
|
399
|
+
Fetches all monsters.
|
|
400
|
+
|
|
401
|
+
Returns
|
|
402
|
+
-------
|
|
403
|
+
List[:class:`Monster`]
|
|
404
|
+
The monsters.
|
|
405
|
+
"""
|
|
406
|
+
data = await self._request("monster", use_cache=use_cache)
|
|
407
|
+
return [Monster(**monster) for monster in data["data"]["items"].values()]
|
|
408
|
+
|
|
409
|
+
async def fetch_monster_detail(self, id: int, use_cache: bool = True) -> MonsterDetail:
|
|
410
|
+
"""
|
|
411
|
+
Fetches a monster detail by ID.
|
|
412
|
+
|
|
413
|
+
Parameters
|
|
414
|
+
----------
|
|
415
|
+
id: :class:`int`
|
|
416
|
+
The ID of the monster detail to fetch.
|
|
417
|
+
|
|
418
|
+
Returns
|
|
419
|
+
-------
|
|
420
|
+
:class:`MonsterDetail`
|
|
421
|
+
The monster detail.
|
|
422
|
+
"""
|
|
423
|
+
data = await self._request(f"monster/{id}", use_cache=use_cache)
|
|
424
|
+
return MonsterDetail(**data["data"])
|
|
425
|
+
|
|
426
|
+
async def fetch_namecards(self, use_cache: bool = True) -> list[Namecard]:
|
|
427
|
+
"""
|
|
428
|
+
Fetches all name cards.
|
|
429
|
+
|
|
430
|
+
Returns
|
|
431
|
+
-------
|
|
432
|
+
List[:class:`NameCard`]
|
|
433
|
+
The name cards.
|
|
434
|
+
"""
|
|
435
|
+
data = await self._request("namecard", use_cache=use_cache)
|
|
436
|
+
return [Namecard(**name_card) for name_card in data["data"]["items"].values()]
|
|
437
|
+
|
|
438
|
+
async def fetch_namecard_detail(self, id: int, use_cache: bool = True) -> NamecardDetail:
|
|
439
|
+
"""
|
|
440
|
+
Fetches a name card detail by ID.
|
|
441
|
+
|
|
442
|
+
Parameters
|
|
443
|
+
----------
|
|
444
|
+
id: :class:`int`
|
|
445
|
+
The ID of the name card detail to fetch.
|
|
446
|
+
|
|
447
|
+
Returns
|
|
448
|
+
-------
|
|
449
|
+
:class:`NameCardDetail`
|
|
450
|
+
The name card detail.
|
|
451
|
+
"""
|
|
452
|
+
data = await self._request(f"namecard/{id}", use_cache=use_cache)
|
|
453
|
+
return NamecardDetail(**data["data"])
|
|
454
|
+
|
|
455
|
+
async def fetch_quests(self, use_cache: bool = True) -> list[Quest]:
|
|
456
|
+
"""
|
|
457
|
+
Fetches all quests.
|
|
458
|
+
|
|
459
|
+
Returns
|
|
460
|
+
-------
|
|
461
|
+
List[:class:`Quest`]
|
|
462
|
+
The quests.
|
|
463
|
+
"""
|
|
464
|
+
data = await self._request("quest", use_cache=use_cache)
|
|
465
|
+
return [Quest(**quest) for quest in data["data"]["items"].values()]
|
|
466
|
+
|
|
467
|
+
async def fetch_tcg_cards(self, use_cache: bool = True) -> list[TCGCard]:
|
|
468
|
+
"""
|
|
469
|
+
Fetches all TCG cards.
|
|
470
|
+
|
|
471
|
+
Returns
|
|
472
|
+
-------
|
|
473
|
+
List[:class:`TCGCard`]
|
|
474
|
+
The TCG cards.
|
|
475
|
+
"""
|
|
476
|
+
data = await self._request("gcg", use_cache=use_cache)
|
|
477
|
+
return [TCGCard(**tcg_card) for tcg_card in data["data"]["items"].values()]
|
|
478
|
+
|
|
479
|
+
async def fetch_tcg_card_detail(self, id: int, use_cache: bool = True) -> TCGCardDetail:
|
|
480
|
+
"""
|
|
481
|
+
Fetches a TCG card detail by ID.
|
|
482
|
+
|
|
483
|
+
Parameters
|
|
484
|
+
----------
|
|
485
|
+
id: :class:`int`
|
|
486
|
+
The ID of the TCG card detail to fetch.
|
|
487
|
+
|
|
488
|
+
Returns
|
|
489
|
+
-------
|
|
490
|
+
:class:`TCGCardDetail`
|
|
491
|
+
The TCG card detail.
|
|
492
|
+
"""
|
|
493
|
+
data = await self._request(f"gcg/{id}", use_cache=use_cache)
|
|
494
|
+
return TCGCardDetail(**data["data"])
|
|
495
|
+
|
|
496
|
+
async def fetch_weapons(self, use_cache: bool = True) -> list[Weapon]:
|
|
497
|
+
"""
|
|
498
|
+
Fetches all weapons.
|
|
499
|
+
|
|
500
|
+
Returns
|
|
501
|
+
-------
|
|
502
|
+
List[:class:`Weapon`]
|
|
503
|
+
The weapons.
|
|
504
|
+
"""
|
|
505
|
+
data = await self._request("weapon", use_cache=use_cache)
|
|
506
|
+
return [Weapon(**weapon) for weapon in data["data"]["items"].values()]
|
|
507
|
+
|
|
508
|
+
async def fetch_weapon_types(self, use_cache: bool = True) -> dict[str, str]:
|
|
509
|
+
"""
|
|
510
|
+
Fetches all weapon types.
|
|
511
|
+
|
|
512
|
+
Returns
|
|
513
|
+
-------
|
|
514
|
+
Dict[:class:`str`, :class:`str`]
|
|
515
|
+
All of the weapon types.
|
|
516
|
+
"""
|
|
517
|
+
data = await self._request("weapon", use_cache=use_cache)
|
|
518
|
+
return data["data"]["types"]
|
|
519
|
+
|
|
520
|
+
async def fetch_weapon_detail(self, id: int, use_cache: bool = True) -> WeaponDetail:
|
|
521
|
+
"""
|
|
522
|
+
Fetches a weapon detail by ID.
|
|
523
|
+
|
|
524
|
+
Parameters
|
|
525
|
+
----------
|
|
526
|
+
id: :class:`int`
|
|
527
|
+
The ID of the weapon detail to fetch.
|
|
528
|
+
|
|
529
|
+
Returns
|
|
530
|
+
-------
|
|
531
|
+
:class:`WeaponDetail`
|
|
532
|
+
The weapon detail.
|
|
533
|
+
"""
|
|
534
|
+
data = await self._request(f"weapon/{id}", use_cache=use_cache)
|
|
535
|
+
return WeaponDetail(**data["data"])
|
|
536
|
+
|
|
537
|
+
async def fetch_domains(self, use_cache: bool = True) -> Domains:
|
|
538
|
+
"""
|
|
539
|
+
Fetches all domains.
|
|
540
|
+
|
|
541
|
+
Returns
|
|
542
|
+
-------
|
|
543
|
+
:class:`Domains`
|
|
544
|
+
The domains.
|
|
545
|
+
"""
|
|
546
|
+
data = await self._request("dailyDungeon", use_cache=use_cache)
|
|
547
|
+
return Domains(**data["data"])
|
|
548
|
+
|
|
549
|
+
async def fetch_changelogs(self, use_cache: bool = True) -> list[Changelog]:
|
|
550
|
+
"""
|
|
551
|
+
Fetch changelogs from the API.
|
|
552
|
+
|
|
553
|
+
Returns
|
|
554
|
+
-------
|
|
555
|
+
List[Changelog]
|
|
556
|
+
A list of Changelog objects.
|
|
557
|
+
"""
|
|
558
|
+
data = await self._request("changelog", static=True, use_cache=use_cache)
|
|
559
|
+
changelogs: list[Changelog] = []
|
|
560
|
+
for changelog_id, log in data["data"].items():
|
|
561
|
+
changelogs.append(Changelog(id=int(changelog_id), **log))
|
|
562
|
+
return changelogs
|
|
563
|
+
|
|
564
|
+
async def fetch_upgrade_data(self, use_cache: bool = True) -> UpgradeData:
|
|
565
|
+
"""
|
|
566
|
+
Fetch upgrade data from the API.
|
|
567
|
+
|
|
568
|
+
Returns
|
|
569
|
+
-------
|
|
570
|
+
UpgradeData
|
|
571
|
+
The upgrade data.
|
|
572
|
+
"""
|
|
573
|
+
data = await self._request("upgrade", use_cache=use_cache)
|
|
574
|
+
return UpgradeData(**data["data"])
|
|
575
|
+
|
|
576
|
+
async def fetch_manual_weapon(self, use_cache: bool = True) -> dict[str, str]:
|
|
577
|
+
"""
|
|
578
|
+
Fetch manual weapon data from the API.
|
|
579
|
+
|
|
580
|
+
Returns
|
|
581
|
+
-------
|
|
582
|
+
Dict[str, str]
|
|
583
|
+
The manual weapon data.
|
|
584
|
+
"""
|
|
585
|
+
data = await self._request("manualWeapon", use_cache=use_cache)
|
|
586
|
+
return data["data"]
|
|
587
|
+
|
|
588
|
+
async def fetch_readable(self, id: str, use_cache: bool = True) -> str:
|
|
589
|
+
"""
|
|
590
|
+
Fetch a readable from the API.
|
|
591
|
+
|
|
592
|
+
Parameters
|
|
593
|
+
----------
|
|
594
|
+
id: :class:`str`
|
|
595
|
+
The ID of the readable to fetch.
|
|
596
|
+
|
|
597
|
+
Returns
|
|
598
|
+
-------
|
|
599
|
+
:class:`str`
|
|
600
|
+
The readable.
|
|
601
|
+
"""
|
|
602
|
+
data = await self._request(f"readable/{id}", use_cache=use_cache)
|
|
603
|
+
return remove_html_tags(data["data"])
|
|
604
|
+
|
|
605
|
+
async def fetch_avatar_curve(
|
|
606
|
+
self, use_cache: bool = True
|
|
607
|
+
) -> dict[str, dict[str, dict[str, float]]]:
|
|
608
|
+
"""
|
|
609
|
+
Fetch avatar curve from the API.
|
|
610
|
+
|
|
611
|
+
Returns
|
|
612
|
+
-------
|
|
613
|
+
Dict[str, Dict[str, Dict[str, float]]]
|
|
614
|
+
The avatar curve.
|
|
615
|
+
"""
|
|
616
|
+
data = await self._request("avatarCurve", static=True, use_cache=use_cache)
|
|
617
|
+
return data["data"]
|
|
618
|
+
|
|
619
|
+
async def fetch_weapon_curve(
|
|
620
|
+
self, use_cache: bool = True
|
|
621
|
+
) -> dict[str, dict[str, dict[str, float]]]:
|
|
622
|
+
"""
|
|
623
|
+
Fetch weapon curve from the API.
|
|
624
|
+
|
|
625
|
+
Returns
|
|
626
|
+
-------
|
|
627
|
+
Dict[str, Dict[str, Dict[str, float]]]
|
|
628
|
+
The weapon curve.
|
|
629
|
+
"""
|
|
630
|
+
data = await self._request("weaponCurve", static=True, use_cache=use_cache)
|
|
631
|
+
return data["data"]
|
|
632
|
+
|
|
633
|
+
async def fetch_monster_curve(
|
|
634
|
+
self, use_cache: bool = True
|
|
635
|
+
) -> dict[str, dict[str, dict[str, float]]]:
|
|
636
|
+
"""
|
|
637
|
+
Fetch monster curve from the API.
|
|
638
|
+
|
|
639
|
+
Returns
|
|
640
|
+
-------
|
|
641
|
+
Dict[str, Dict[str, Dict[str, float]]]
|
|
642
|
+
The monster curve.
|
|
643
|
+
"""
|
|
644
|
+
data = await self._request("monsterCurve", static=True, use_cache=use_cache)
|
|
645
|
+
return data["data"]
|
|
646
|
+
|
|
647
|
+
async def fetch_abyss_data(self, use_cache: bool = True) -> AbyssResponse:
|
|
648
|
+
"""
|
|
649
|
+
Fetches abyss data from the API.
|
|
650
|
+
|
|
651
|
+
Returns
|
|
652
|
+
-------
|
|
653
|
+
AbyssResponse
|
|
654
|
+
The abyss data.
|
|
655
|
+
"""
|
|
656
|
+
data = await self._request("tower", use_cache=use_cache)
|
|
657
|
+
return AbyssResponse(**data["data"])
|
ambr/exceptions.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
__all__ = ("AmbrAPIError", "DataNotFoundError", "ConnectionTimeoutError")
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class AmbrAPIError(Exception):
|
|
5
|
+
def __init__(self, code: int) -> None:
|
|
6
|
+
self.code = code
|
|
7
|
+
|
|
8
|
+
def __str__(self) -> str:
|
|
9
|
+
return f"An error occurred while requesting the API, status code: {self.code}"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class DataNotFoundError(AmbrAPIError):
|
|
13
|
+
def __init__(self) -> None:
|
|
14
|
+
self.code = 404
|
|
15
|
+
|
|
16
|
+
def __str__(self) -> str:
|
|
17
|
+
return "Data not found"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ConnectionTimeoutError(AmbrAPIError):
|
|
21
|
+
def __init__(self) -> None:
|
|
22
|
+
self.code = 522
|
|
23
|
+
|
|
24
|
+
def __str__(self) -> str:
|
|
25
|
+
return "Connection to the API timed out"
|
ambr/models/__init__.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from .abyss import *
|
|
2
|
+
from .achievement import *
|
|
3
|
+
from .artifact import *
|
|
4
|
+
from .book import *
|
|
5
|
+
from .changelog import *
|
|
6
|
+
from .character import *
|
|
7
|
+
from .character_fetter import *
|
|
8
|
+
from .domain import *
|
|
9
|
+
from .food import *
|
|
10
|
+
from .furniture import *
|
|
11
|
+
from .material import *
|
|
12
|
+
from .monster import *
|
|
13
|
+
from .name_card import *
|
|
14
|
+
from .quest import *
|
|
15
|
+
from .tcg import *
|
|
16
|
+
from .upgrade import *
|
|
17
|
+
from .weapon import *
|