blizzardapi3 3.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- blizzardapi3-3.0.0/PKG-INFO +426 -0
- blizzardapi3-3.0.0/README.md +393 -0
- blizzardapi3-3.0.0/blizzardapi3/__init__.py +13 -0
- blizzardapi3-3.0.0/blizzardapi3/api/__init__.py +5 -0
- blizzardapi3-3.0.0/blizzardapi3/api/wow.py +76 -0
- blizzardapi3-3.0.0/blizzardapi3/blizzard_api.py +53 -0
- blizzardapi3-3.0.0/blizzardapi3/core/__init__.py +17 -0
- blizzardapi3-3.0.0/blizzardapi3/core/auth.py +177 -0
- blizzardapi3-3.0.0/blizzardapi3/core/client.py +144 -0
- blizzardapi3-3.0.0/blizzardapi3/core/context.py +23 -0
- blizzardapi3-3.0.0/blizzardapi3/core/executor.py +249 -0
- blizzardapi3-3.0.0/blizzardapi3/core/factory.py +377 -0
- blizzardapi3-3.0.0/blizzardapi3/core/registry.py +203 -0
- blizzardapi3-3.0.0/blizzardapi3/exceptions/__init__.py +28 -0
- blizzardapi3-3.0.0/blizzardapi3/exceptions/auth.py +64 -0
- blizzardapi3-3.0.0/blizzardapi3/exceptions/base.py +33 -0
- blizzardapi3-3.0.0/blizzardapi3/exceptions/request.py +89 -0
- blizzardapi3-3.0.0/blizzardapi3/exceptions/validation.py +85 -0
- blizzardapi3-3.0.0/blizzardapi3/types.py +83 -0
- blizzardapi3-3.0.0/blizzardapi3.egg-info/PKG-INFO +426 -0
- blizzardapi3-3.0.0/blizzardapi3.egg-info/SOURCES.txt +24 -0
- blizzardapi3-3.0.0/blizzardapi3.egg-info/dependency_links.txt +1 -0
- blizzardapi3-3.0.0/blizzardapi3.egg-info/requires.txt +14 -0
- blizzardapi3-3.0.0/blizzardapi3.egg-info/top_level.txt +1 -0
- blizzardapi3-3.0.0/pyproject.toml +69 -0
- blizzardapi3-3.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: blizzardapi3
|
|
3
|
+
Version: 3.0.0
|
|
4
|
+
Summary: A modern, config-driven Python wrapper for the Blizzard API with async support
|
|
5
|
+
Author-email: lostcol0ny <c098os0k@4wrd.cc>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/lostcol0ny/blizzardapi3
|
|
8
|
+
Project-URL: Documentation, https://github.com/lostcol0ny/blizzardapi3#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/lostcol0ny/blizzardapi3
|
|
10
|
+
Project-URL: Issues, https://github.com/lostcol0ny/blizzardapi3/issues
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Development Status :: 4 - Beta
|
|
17
|
+
Classifier: Intended Audience :: Developers
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
Requires-Dist: requests<3.0.0,>=2.32.3
|
|
22
|
+
Requires-Dist: aiohttp<4.0.0,>=3.12.12
|
|
23
|
+
Requires-Dist: pydantic<3.0.0,>=2.11.6
|
|
24
|
+
Requires-Dist: pyyaml<7.0.0,>=6.0
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest<10.0.0,>=8.2.2; extra == "dev"
|
|
27
|
+
Requires-Dist: pytest-mock<4.0.0,>=3.14.0; extra == "dev"
|
|
28
|
+
Requires-Dist: pytest-asyncio<2.0.0,>=0.23.5; extra == "dev"
|
|
29
|
+
Requires-Dist: black<26.0.0,>=24.4.2; extra == "dev"
|
|
30
|
+
Requires-Dist: ruff<1.0.0,>=0.3.0; extra == "dev"
|
|
31
|
+
Provides-Extra: examples
|
|
32
|
+
Requires-Dist: python-dotenv<2.0.0,>=1.0.0; extra == "examples"
|
|
33
|
+
|
|
34
|
+
# BlizzardAPI v3
|
|
35
|
+
|
|
36
|
+
A modern, config-driven Python wrapper for the Blizzard API with full async support, type safety via Pydantic, and comprehensive error handling.
|
|
37
|
+
|
|
38
|
+
## Table of Contents
|
|
39
|
+
|
|
40
|
+
- [Features](#features)
|
|
41
|
+
- [Installation](#installation)
|
|
42
|
+
- [Quick Start](#quick-start)
|
|
43
|
+
- [Using Search Endpoints](#using-search-endpoints)
|
|
44
|
+
- [Error Handling](#error-handling)
|
|
45
|
+
- [Comprehensive Examples](#comprehensive-examples)
|
|
46
|
+
- [Supported Games](#supported-games)
|
|
47
|
+
- [Documentation](#documentation)
|
|
48
|
+
- [Development](#development)
|
|
49
|
+
- [Architecture](#architecture)
|
|
50
|
+
|
|
51
|
+
## Features
|
|
52
|
+
|
|
53
|
+
- 🚀 **Async/Await Support** - First-class async support with both sync and async methods
|
|
54
|
+
- 🔒 **Type Safety** - Full Pydantic models with IDE autocomplete
|
|
55
|
+
- 📝 **Config-Driven** - YAML-defined endpoints, easy to extend
|
|
56
|
+
- 🎯 **Better Errors** - Specific exception types with detailed context
|
|
57
|
+
- ⚡ **Efficient** - Single session management, proper resource cleanup
|
|
58
|
+
- 🎮 **Complete Coverage** - Supports WoW, Diablo 3, Hearthstone, and StarCraft 2
|
|
59
|
+
|
|
60
|
+
## Installation
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pip install blizzardapi3
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Quick Start
|
|
67
|
+
|
|
68
|
+
### Synchronous Usage
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from blizzardapi3 import BlizzardAPI
|
|
72
|
+
|
|
73
|
+
# Use context manager for proper cleanup
|
|
74
|
+
with BlizzardAPI(client_id="your_id", client_secret="your_secret") as api:
|
|
75
|
+
# Get WoW achievement
|
|
76
|
+
achievement = api.wow.game_data.get_achievement(
|
|
77
|
+
region="us",
|
|
78
|
+
locale="en_US",
|
|
79
|
+
achievement_id=6
|
|
80
|
+
)
|
|
81
|
+
print(achievement["name"]["en_US"])
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Asynchronous Usage
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
import asyncio
|
|
88
|
+
from blizzardapi3 import BlizzardAPI
|
|
89
|
+
|
|
90
|
+
async def main():
|
|
91
|
+
async with BlizzardAPI(client_id="your_id", client_secret="your_secret") as api:
|
|
92
|
+
# Async methods end with _async
|
|
93
|
+
achievement = await api.wow.game_data.get_achievement_async(
|
|
94
|
+
region="us",
|
|
95
|
+
locale="en_US",
|
|
96
|
+
achievement_id=6
|
|
97
|
+
)
|
|
98
|
+
print(achievement["name"]["en_US"])
|
|
99
|
+
|
|
100
|
+
asyncio.run(main())
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Using Search Endpoints
|
|
104
|
+
|
|
105
|
+
BlizzardAPI v3 provides powerful search functionality for various game resources. Search methods accept flexible keyword arguments for filtering and pagination.
|
|
106
|
+
|
|
107
|
+
### Basic Search
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
from blizzardapi3 import BlizzardAPI, Region, Locale
|
|
111
|
+
|
|
112
|
+
with BlizzardAPI(client_id, client_secret) as api:
|
|
113
|
+
# Search for decor items containing "wall"
|
|
114
|
+
results = api.wow.game_data.search_decor(
|
|
115
|
+
region=Region.US,
|
|
116
|
+
locale=Locale.EN_US,
|
|
117
|
+
**{"name.en_US": "wall"}
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
print(f"Found {len(results['results'])} items")
|
|
121
|
+
for item in results['results']:
|
|
122
|
+
data = item['data']
|
|
123
|
+
print(f"{data['name']['en_US']} (ID: {data['id']})")
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Pagination and Ordering
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
with BlizzardAPI(client_id, client_secret) as api:
|
|
130
|
+
# Get first page, ordered by ID
|
|
131
|
+
results = api.wow.game_data.search_decor(
|
|
132
|
+
region=Region.US,
|
|
133
|
+
locale=Locale.EN_US,
|
|
134
|
+
orderby="id",
|
|
135
|
+
_page=1
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
print(f"Page {results['page']} of {results['pageCount']}")
|
|
139
|
+
print(f"Results per page: {results['pageSize']}")
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Advanced Filtering
|
|
143
|
+
|
|
144
|
+
Search endpoints support locale-specific filtering using dot notation:
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
with BlizzardAPI(client_id, client_secret) as api:
|
|
148
|
+
# Search with multiple filters
|
|
149
|
+
results = api.wow.game_data.search_decor(
|
|
150
|
+
region=Region.US,
|
|
151
|
+
locale=Locale.EN_US,
|
|
152
|
+
**{
|
|
153
|
+
"name.en_US": "mirror",
|
|
154
|
+
"orderby": "id:desc",
|
|
155
|
+
"_page": 1
|
|
156
|
+
}
|
|
157
|
+
)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Available Search Methods
|
|
161
|
+
|
|
162
|
+
#### World of Warcraft Game Data
|
|
163
|
+
|
|
164
|
+
- `search_azerite_essence()` - Search azerite essences
|
|
165
|
+
- `search_covenant()` - Search covenants
|
|
166
|
+
- `search_creature()` - Search creatures
|
|
167
|
+
- `search_decor()` - Search housing decor items
|
|
168
|
+
- `search_item()` - Search items
|
|
169
|
+
- `search_media()` - Search media assets
|
|
170
|
+
- `search_mount()` - Search mounts
|
|
171
|
+
- `search_pet()` - Search battle pets
|
|
172
|
+
- `search_profession()` - Search professions
|
|
173
|
+
- `search_spell()` - Search spells
|
|
174
|
+
|
|
175
|
+
### Common Search Parameters
|
|
176
|
+
|
|
177
|
+
| Parameter | Description | Example |
|
|
178
|
+
| --------------- | ------------------------ | -------------------- |
|
|
179
|
+
| `name.{locale}` | Filter by localized name | `name.en_US: "wall"` |
|
|
180
|
+
| `orderby` | Sort results | `"id"`, `"id:desc"` |
|
|
181
|
+
| `_page` | Page number (1-indexed) | `1`, `2`, `3` |
|
|
182
|
+
|
|
183
|
+
### Search Response Structure
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
{
|
|
187
|
+
"page": 1,
|
|
188
|
+
"pageSize": 100,
|
|
189
|
+
"maxPageSize": 100,
|
|
190
|
+
"pageCount": 10,
|
|
191
|
+
"results": [
|
|
192
|
+
{
|
|
193
|
+
"key": {"href": "..."},
|
|
194
|
+
"data": {
|
|
195
|
+
"id": 534,
|
|
196
|
+
"name": {"en_US": "Plain Interior Wall"},
|
|
197
|
+
# ... additional fields
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
]
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Error Handling
|
|
205
|
+
|
|
206
|
+
```python
|
|
207
|
+
from blizzardapi3 import BlizzardAPI
|
|
208
|
+
from blizzardapi3.exceptions import NotFoundError, RateLimitError
|
|
209
|
+
|
|
210
|
+
with BlizzardAPI(client_id, client_secret) as api:
|
|
211
|
+
try:
|
|
212
|
+
data = api.wow.game_data.get_achievement(
|
|
213
|
+
region="us",
|
|
214
|
+
locale="en_US",
|
|
215
|
+
achievement_id=999999
|
|
216
|
+
)
|
|
217
|
+
except NotFoundError:
|
|
218
|
+
print("Achievement not found")
|
|
219
|
+
except RateLimitError as e:
|
|
220
|
+
print(f"Rate limited. Retry after {e.retry_after} seconds")
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Comprehensive Examples
|
|
224
|
+
|
|
225
|
+
### Character Profile Information
|
|
226
|
+
|
|
227
|
+
```python
|
|
228
|
+
from blizzardapi3 import BlizzardAPI, Region, Locale
|
|
229
|
+
|
|
230
|
+
with BlizzardAPI(client_id, client_secret) as api:
|
|
231
|
+
# Get character appearance
|
|
232
|
+
appearance = api.wow.profile.get_character_appearance_summary(
|
|
233
|
+
region=Region.US,
|
|
234
|
+
locale=Locale.EN_US,
|
|
235
|
+
realm_slug="illidan",
|
|
236
|
+
character_name="beyloc"
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
print(f"Character: {appearance['character']['name']}")
|
|
240
|
+
print(f"Race: {appearance['playable_race']['name']}")
|
|
241
|
+
print(f"Class: {appearance['playable_class']['name']}")
|
|
242
|
+
print(f"Spec: {appearance['active_spec']['name']}")
|
|
243
|
+
|
|
244
|
+
# Get character equipment
|
|
245
|
+
equipment = api.wow.profile.get_character_equipment_summary(
|
|
246
|
+
region=Region.US,
|
|
247
|
+
locale=Locale.EN_US,
|
|
248
|
+
realm_slug="illidan",
|
|
249
|
+
character_name="beyloc"
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
for item in equipment['equipped_items']:
|
|
253
|
+
print(f"{item['slot']['name']}: {item['name']}")
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Building a Decor Browser
|
|
257
|
+
|
|
258
|
+
```python
|
|
259
|
+
from blizzardapi3 import BlizzardAPI, Region, Locale
|
|
260
|
+
|
|
261
|
+
def search_decor_by_name(api, search_term, page=1):
|
|
262
|
+
"""Search for decor items by name with pagination."""
|
|
263
|
+
results = api.wow.game_data.search_decor(
|
|
264
|
+
region=Region.US,
|
|
265
|
+
locale=Locale.EN_US,
|
|
266
|
+
**{
|
|
267
|
+
"name.en_US": search_term,
|
|
268
|
+
"orderby": "id",
|
|
269
|
+
"_page": page
|
|
270
|
+
}
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
items = []
|
|
274
|
+
for result in results['results']:
|
|
275
|
+
data = result['data']
|
|
276
|
+
items.append({
|
|
277
|
+
'id': data['id'],
|
|
278
|
+
'name': data['name']['en_US'],
|
|
279
|
+
'href': result['key']['href']
|
|
280
|
+
})
|
|
281
|
+
|
|
282
|
+
return {
|
|
283
|
+
'items': items,
|
|
284
|
+
'page': results['page'],
|
|
285
|
+
'total_pages': results['pageCount'],
|
|
286
|
+
'has_more': results['page'] < results['pageCount']
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
with BlizzardAPI(client_id, client_secret) as api:
|
|
290
|
+
# Search for walls
|
|
291
|
+
result = search_decor_by_name(api, "wall", page=1)
|
|
292
|
+
|
|
293
|
+
for item in result['items']:
|
|
294
|
+
print(f"{item['name']} (ID: {item['id']})")
|
|
295
|
+
|
|
296
|
+
if result['has_more']:
|
|
297
|
+
print(f"\nShowing page {result['page']} of {result['total_pages']}")
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Item Search with Filtering
|
|
301
|
+
|
|
302
|
+
```python
|
|
303
|
+
with BlizzardAPI(client_id, client_secret) as api:
|
|
304
|
+
# Search for epic quality items
|
|
305
|
+
items = api.wow.game_data.search_item(
|
|
306
|
+
region=Region.US,
|
|
307
|
+
locale=Locale.EN_US,
|
|
308
|
+
**{
|
|
309
|
+
"name.en_US": "sword",
|
|
310
|
+
"orderby": "id:desc",
|
|
311
|
+
"_page": 1
|
|
312
|
+
}
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
for result in items['results'][:10]:
|
|
316
|
+
item = result['data']
|
|
317
|
+
print(f"{item['name']['en_US']} (ID: {item['id']})")
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Async Batch Operations
|
|
321
|
+
|
|
322
|
+
```python
|
|
323
|
+
import asyncio
|
|
324
|
+
from blizzardapi3 import BlizzardAPI, Region, Locale
|
|
325
|
+
|
|
326
|
+
async def get_multiple_achievements(api, achievement_ids):
|
|
327
|
+
"""Fetch multiple achievements concurrently."""
|
|
328
|
+
tasks = [
|
|
329
|
+
api.wow.game_data.get_achievement_async(
|
|
330
|
+
region=Region.US,
|
|
331
|
+
locale=Locale.EN_US,
|
|
332
|
+
achievement_id=aid
|
|
333
|
+
)
|
|
334
|
+
for aid in achievement_ids
|
|
335
|
+
]
|
|
336
|
+
return await asyncio.gather(*tasks)
|
|
337
|
+
|
|
338
|
+
async def main():
|
|
339
|
+
async with BlizzardAPI(client_id, client_secret) as api:
|
|
340
|
+
achievement_ids = [6, 7, 8, 9, 10]
|
|
341
|
+
achievements = await get_multiple_achievements(api, achievement_ids)
|
|
342
|
+
|
|
343
|
+
for ach in achievements:
|
|
344
|
+
print(f"{ach['name']} - {ach['points']} points")
|
|
345
|
+
|
|
346
|
+
asyncio.run(main())
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### Guild Information
|
|
350
|
+
|
|
351
|
+
```python
|
|
352
|
+
with BlizzardAPI(client_id, client_secret) as api:
|
|
353
|
+
# Get guild roster
|
|
354
|
+
roster = api.wow.profile.get_guild_roster(
|
|
355
|
+
region=Region.US,
|
|
356
|
+
locale=Locale.EN_US,
|
|
357
|
+
realm_slug="illidan",
|
|
358
|
+
name_slug="your-guild-name"
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
for member in roster['members']:
|
|
362
|
+
char = member['character']
|
|
363
|
+
print(f"{char['name']} - Level {char['level']} {char.get('playable_class', {}).get('name', 'Unknown')}")
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
## Supported Games
|
|
367
|
+
|
|
368
|
+
- **World of Warcraft** - Game Data & Profile APIs (208 endpoints)
|
|
369
|
+
- Game Data: Achievements, Items, Mounts, Pets, Auctions, Housing/Decor, and more
|
|
370
|
+
- Profile: Characters, Guilds, Mythic+, PvP, Collections, Equipment
|
|
371
|
+
- **Diablo 3** - Community & Game Data APIs (24 endpoints)
|
|
372
|
+
- **Hearthstone** - Game Data API (8 endpoints)
|
|
373
|
+
- **StarCraft 2** - Community & Game Data APIs (11 endpoints)
|
|
374
|
+
|
|
375
|
+
**Total: 242 endpoints**
|
|
376
|
+
|
|
377
|
+
## Documentation
|
|
378
|
+
|
|
379
|
+
### Core Documentation
|
|
380
|
+
|
|
381
|
+
- **[Search Guide](docs/SEARCH_GUIDE.md)** - Comprehensive guide to using search endpoints with real-world examples
|
|
382
|
+
- **[Search Quick Reference](docs/SEARCH_QUICK_REFERENCE.md)** - Quick reference for all search methods and parameters
|
|
383
|
+
- **[OAuth Guide](docs/OAUTH_GUIDE.md)** - Complete guide to OAuth authorization code flow for user-specific endpoints
|
|
384
|
+
- **[Migration Guide](MIGRATION.md)** - Detailed guide for migrating from blizzardapi2
|
|
385
|
+
|
|
386
|
+
### Additional Resources
|
|
387
|
+
|
|
388
|
+
- [Blizzard API Official Documentation](https://develop.battle.net/documentation)
|
|
389
|
+
- [GitHub Repository](https://github.com/lostcol0ny/blizzardapi3)
|
|
390
|
+
- [Issue Tracker](https://github.com/lostcol0ny/blizzardapi3/issues)
|
|
391
|
+
|
|
392
|
+
## Migration from v2
|
|
393
|
+
|
|
394
|
+
See [MIGRATION.md](MIGRATION.md) for a detailed guide on migrating from blizzardapi2.
|
|
395
|
+
|
|
396
|
+
## Development
|
|
397
|
+
|
|
398
|
+
```bash
|
|
399
|
+
# Clone the repository
|
|
400
|
+
git clone https://github.com/lostcol0ny/blizzardapi3.git
|
|
401
|
+
cd blizzardapi3
|
|
402
|
+
|
|
403
|
+
# Install development dependencies
|
|
404
|
+
pip install -e ".[dev]"
|
|
405
|
+
|
|
406
|
+
# Run tests
|
|
407
|
+
pytest
|
|
408
|
+
|
|
409
|
+
# Format code
|
|
410
|
+
black .
|
|
411
|
+
ruff check .
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
## Architecture
|
|
415
|
+
|
|
416
|
+
BlizzardAPI v3 uses a config-driven architecture:
|
|
417
|
+
|
|
418
|
+
- **YAML Endpoint Definitions** - All API endpoints defined in YAML configs
|
|
419
|
+
- **Dynamic Method Generation** - Methods generated at runtime from configs
|
|
420
|
+
- **Pydantic Models** - Type-safe response models
|
|
421
|
+
- **Custom Exceptions** - Detailed error hierarchy
|
|
422
|
+
- **Single Session** - Efficient session management with proper cleanup
|
|
423
|
+
|
|
424
|
+
## License
|
|
425
|
+
|
|
426
|
+
MIT License - see [LICENSE](LICENSE) for details
|