wbapi-async 0.7.2__tar.gz → 0.7.4__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.
- {wbapi_async-0.7.2 → wbapi_async-0.7.4}/PKG-INFO +4 -10
- {wbapi_async-0.7.2 → wbapi_async-0.7.4}/README.md +3 -9
- {wbapi_async-0.7.2 → wbapi_async-0.7.4}/pyproject.toml +1 -1
- {wbapi_async-0.7.2 → wbapi_async-0.7.4}/src/wbapi_async/client/session/base.py +8 -2
- {wbapi_async-0.7.2 → wbapi_async-0.7.4}/src/wbapi_async/method.py +9 -2
- {wbapi_async-0.7.2 → wbapi_async-0.7.4}/.gitignore +0 -0
- {wbapi_async-0.7.2 → wbapi_async-0.7.4}/LICENSE +0 -0
- {wbapi_async-0.7.2 → wbapi_async-0.7.4}/src/wbapi_async/__init__.py +0 -0
- {wbapi_async-0.7.2 → wbapi_async-0.7.4}/src/wbapi_async/api.py +0 -0
- {wbapi_async-0.7.2 → wbapi_async-0.7.4}/src/wbapi_async/client/__init__.py +0 -0
- {wbapi_async-0.7.2 → wbapi_async-0.7.4}/src/wbapi_async/client/session/__init__.py +0 -0
- {wbapi_async-0.7.2 → wbapi_async-0.7.4}/src/wbapi_async/client/session/headers.py +0 -0
- {wbapi_async-0.7.2 → wbapi_async-0.7.4}/src/wbapi_async/exceptions.py +0 -0
- {wbapi_async-0.7.2 → wbapi_async-0.7.4}/src/wbapi_async/py.typed +0 -0
- {wbapi_async-0.7.2 → wbapi_async-0.7.4}/src/wbapi_async/type.py +0 -0
- {wbapi_async-0.7.2 → wbapi_async-0.7.4}/src/wbapi_async/utils/__init__.py +0 -0
- {wbapi_async-0.7.2 → wbapi_async-0.7.4}/src/wbapi_async/utils/paginate.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wbapi-async
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.4
|
|
4
4
|
Summary: Asynchronous client for Wildberries API
|
|
5
5
|
Project-URL: Documentation, https://serdukow.github.io/wbapi-async/
|
|
6
6
|
Project-URL: Repository, https://github.com/serdukow/wbapi-async
|
|
@@ -42,7 +42,7 @@ Requires-Dist: python-dotenv<2.0.0,>=1.2.1; extra == 'test'
|
|
|
42
42
|
Description-Content-Type: text/markdown
|
|
43
43
|
|
|
44
44
|
<p align="center">
|
|
45
|
-
<a href="https://dev.wildberries.ru/"><img src="
|
|
45
|
+
<a href="https://dev.wildberries.ru/"><img src="https://dev.wildberries.ru/images/open-graph.png" alt="WbAPI" width="600"></a>
|
|
46
46
|
</p>
|
|
47
47
|
|
|
48
48
|
<div align="center">
|
|
@@ -62,9 +62,9 @@ Just pass the path from the docs and get data back.
|
|
|
62
62
|
## Features
|
|
63
63
|
|
|
64
64
|
- **Zero boilerplate** — WB API changes constantly; typed models break on every schema update. Instead, responses are plain attribute-accessible dicts — `result.fieldName` just works, no models to maintain
|
|
65
|
-
- **Auto-pagination** — `get_all()` fetches all
|
|
65
|
+
- **Auto-pagination** — `get_all()` fetches all pages. Auto-detects all known strategies; you can easily add your own via a custom paginator — [see docs](https://serdukow.github.io/wbapi-async/advanced/pagination/)
|
|
66
66
|
- **Rate limiting** — per-endpoint limits from the spec, powered by `aiolimiter`
|
|
67
|
-
- **Auto-retry** — automatic retry on HTTP 429
|
|
67
|
+
- **Auto-retry** — automatic retry on HTTP 429
|
|
68
68
|
- **Always up to date** — path registry is [auto-generated](https://github.com/serdukow/wbapi-codegen) from WB OpenAPI specs daily
|
|
69
69
|
- **Fully async** — built on `httpx` + `asyncio`
|
|
70
70
|
|
|
@@ -83,12 +83,6 @@ async with WbAPI(token="...") as api:
|
|
|
83
83
|
|
|
84
84
|
supplies = await api.get_all("/api/v3/supplies")
|
|
85
85
|
print(f"supplies: {supplies!r}")
|
|
86
|
-
|
|
87
|
-
result = await api.post("/adv/v0/rename", body={"advertId": 2233344, "name": "newname"})
|
|
88
|
-
print(f"rename: {result!r}")
|
|
89
|
-
|
|
90
|
-
await api.put("/api/v3/stocks/507", body={"stocks": [{"sku": "WB007", "amount": 10}]})
|
|
91
|
-
await api.delete("/content/v2/tag/99")
|
|
92
86
|
```
|
|
93
87
|
|
|
94
88
|
Just copy the path straight from the [WB API](https://dev.wildberries.ru) — the correct base URL and subdomain are resolved automatically.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<a href="https://dev.wildberries.ru/"><img src="
|
|
2
|
+
<a href="https://dev.wildberries.ru/"><img src="https://dev.wildberries.ru/images/open-graph.png" alt="WbAPI" width="600"></a>
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<div align="center">
|
|
@@ -19,9 +19,9 @@ Just pass the path from the docs and get data back.
|
|
|
19
19
|
## Features
|
|
20
20
|
|
|
21
21
|
- **Zero boilerplate** — WB API changes constantly; typed models break on every schema update. Instead, responses are plain attribute-accessible dicts — `result.fieldName` just works, no models to maintain
|
|
22
|
-
- **Auto-pagination** — `get_all()` fetches all
|
|
22
|
+
- **Auto-pagination** — `get_all()` fetches all pages. Auto-detects all known strategies; you can easily add your own via a custom paginator — [see docs](https://serdukow.github.io/wbapi-async/advanced/pagination/)
|
|
23
23
|
- **Rate limiting** — per-endpoint limits from the spec, powered by `aiolimiter`
|
|
24
|
-
- **Auto-retry** — automatic retry on HTTP 429
|
|
24
|
+
- **Auto-retry** — automatic retry on HTTP 429
|
|
25
25
|
- **Always up to date** — path registry is [auto-generated](https://github.com/serdukow/wbapi-codegen) from WB OpenAPI specs daily
|
|
26
26
|
- **Fully async** — built on `httpx` + `asyncio`
|
|
27
27
|
|
|
@@ -40,12 +40,6 @@ async with WbAPI(token="...") as api:
|
|
|
40
40
|
|
|
41
41
|
supplies = await api.get_all("/api/v3/supplies")
|
|
42
42
|
print(f"supplies: {supplies!r}")
|
|
43
|
-
|
|
44
|
-
result = await api.post("/adv/v0/rename", body={"advertId": 2233344, "name": "newname"})
|
|
45
|
-
print(f"rename: {result!r}")
|
|
46
|
-
|
|
47
|
-
await api.put("/api/v3/stocks/507", body={"stocks": [{"sku": "WB007", "amount": 10}]})
|
|
48
|
-
await api.delete("/content/v2/tag/99")
|
|
49
43
|
```
|
|
50
44
|
|
|
51
45
|
Just copy the path straight from the [WB API](https://dev.wildberries.ru) — the correct base URL and subdomain are resolved automatically.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
from datetime import datetime, timedelta
|
|
2
3
|
import logging
|
|
3
4
|
from typing import Any
|
|
4
5
|
|
|
@@ -10,6 +11,7 @@ from ...exceptions import WbAPIError
|
|
|
10
11
|
from .headers import Headers
|
|
11
12
|
|
|
12
13
|
|
|
14
|
+
log = logging.getLogger("wbapi.session")
|
|
13
15
|
logging.getLogger("httpx").setLevel(logging.WARNING)
|
|
14
16
|
logging.getLogger("httpcore").setLevel(logging.WARNING)
|
|
15
17
|
|
|
@@ -57,9 +59,13 @@ class BaseSession:
|
|
|
57
59
|
|
|
58
60
|
if response.status_code == 429:
|
|
59
61
|
retry_after = int(response.headers.get("X-Ratelimit-Retry", "1"))
|
|
60
|
-
log = logging.getLogger("wbapi.session")
|
|
61
62
|
if retry_after > 60:
|
|
62
|
-
|
|
63
|
+
retry_at = datetime.now() + timedelta(seconds=retry_after)
|
|
64
|
+
log.warning(
|
|
65
|
+
"Rate limit exceeded. Retrying in %s seconds (at %s)",
|
|
66
|
+
retry_after,
|
|
67
|
+
retry_at,
|
|
68
|
+
)
|
|
63
69
|
await asyncio.sleep(retry_after)
|
|
64
70
|
return await self._request(method, url, params=params, json=json, limit=limit)
|
|
65
71
|
|
|
@@ -543,9 +543,16 @@ class MethodDispatcher:
|
|
|
543
543
|
*,
|
|
544
544
|
params: dict[str, Any] | None = None,
|
|
545
545
|
json: Any | None = None,
|
|
546
|
-
|
|
546
|
+
no_auth: bool = False,
|
|
547
547
|
) -> Any:
|
|
548
|
-
|
|
548
|
+
from urllib.parse import urlparse
|
|
549
|
+
|
|
550
|
+
if not no_auth and path.startswith(("https://", "http://")):
|
|
551
|
+
no_auth = urlparse(path).netloc in _EXTRA_ALLOWED_HOSTS
|
|
552
|
+
|
|
553
|
+
if no_auth:
|
|
554
|
+
self._session.headers.authorization = None
|
|
555
|
+
else:
|
|
549
556
|
self._session.headers.set_token(self._token)
|
|
550
557
|
url = resolve_url(path)
|
|
551
558
|
limiter = _get_limiter(path)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|