vtexpy 0.0.0b25__tar.gz → 0.0.0b27__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.
Potentially problematic release.
This version of vtexpy might be problematic. Click here for more details.
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/PKG-INFO +2 -1
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/pyproject.toml +2 -1
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_api/__init__.py +1 -0
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_api/base.py +55 -19
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_api/custom.py +2 -2
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_api/orders.py +7 -4
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_api/payments_gateway.py +11 -8
- vtexpy-0.0.0b27/vtex/_api/pricing.py +19 -0
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_config.py +25 -0
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_constants.py +2 -0
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_utils.py +4 -0
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_vtex.py +7 -0
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/LICENSE +0 -0
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/README.md +0 -0
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/__init__.py +0 -0
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_api/catalog.py +7 -7
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_api/checkout.py +1 -1
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_api/license_manager.py +3 -3
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_api/logistics.py +8 -8
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_api/master_data.py +1 -1
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_api/promotions_and_taxes.py +4 -4
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_api/types/__init__.py +0 -0
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_api/types/catalog.py +0 -0
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_api/types/generic.py +0 -0
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_api/types/license_manager.py +0 -0
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_dto.py +0 -0
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_exceptions.py +0 -0
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_logging.py +0 -0
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_sentinels.py +0 -0
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/_types.py +0 -0
- {vtexpy-0.0.0b25 → vtexpy-0.0.0b27}/vtex/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: vtexpy
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.0b27
|
|
4
4
|
Summary: Unofficial VTEX API's Python SDK
|
|
5
5
|
Home-page: https://github.com/lvieirajr/vtex-python
|
|
6
6
|
License: Apache
|
|
@@ -27,6 +27,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
27
27
|
Classifier: Typing :: Typed
|
|
28
28
|
Requires-Dist: cachetools (>=5.0,<6.0)
|
|
29
29
|
Requires-Dist: httpx (>=0.17,<1.0)
|
|
30
|
+
Requires-Dist: limits (>=3.7,<4.0)
|
|
30
31
|
Requires-Dist: pydantic (>=2.0,<3.0)
|
|
31
32
|
Requires-Dist: python-dateutil (>=2.9,<3.0)
|
|
32
33
|
Requires-Dist: tenacity (>=8.0,<10.0)
|
|
@@ -5,7 +5,7 @@ build-backend = "poetry.core.masonry.api"
|
|
|
5
5
|
[tool.poetry]
|
|
6
6
|
name = "vtexpy"
|
|
7
7
|
description = "Unofficial VTEX API's Python SDK"
|
|
8
|
-
version = "0.0.
|
|
8
|
+
version = "0.0.0b27"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "Apache"
|
|
11
11
|
authors = [
|
|
@@ -42,6 +42,7 @@ packages = [
|
|
|
42
42
|
python = ">=3.9,<3.14"
|
|
43
43
|
cachetools = {version = ">=5.0,<6.0"}
|
|
44
44
|
httpx = {version = ">=0.17,<1.0"}
|
|
45
|
+
limits = {version = ">=3.7,<4.0"}
|
|
45
46
|
pydantic = {version = ">=2.0,<3.0"}
|
|
46
47
|
python-dateutil = {version = ">=2.9,<3.0"}
|
|
47
48
|
tenacity = {version = ">=8.0,<10.0"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from http import HTTPStatus
|
|
2
2
|
from json import JSONDecodeError
|
|
3
|
+
from time import sleep
|
|
3
4
|
from typing import Any, Type, Union, cast
|
|
4
|
-
from urllib.parse import urljoin
|
|
5
5
|
|
|
6
6
|
from httpx import (
|
|
7
7
|
Client,
|
|
@@ -18,6 +18,7 @@ from httpx._types import (
|
|
|
18
18
|
RequestData,
|
|
19
19
|
RequestFiles,
|
|
20
20
|
)
|
|
21
|
+
from limits import RateLimitItem, storage, strategies
|
|
21
22
|
from tenacity import (
|
|
22
23
|
retry,
|
|
23
24
|
retry_if_exception_type,
|
|
@@ -31,7 +32,7 @@ from .._dto import VTEXDataResponse, VTEXResponseType
|
|
|
31
32
|
from .._exceptions import VTEXRequestError, VTEXResponseError
|
|
32
33
|
from .._logging import disable_loggers, get_logger, log_before_retry
|
|
33
34
|
from .._types import HTTPMethodType
|
|
34
|
-
from .._utils import redact_headers, to_snake_case, to_snake_case_deep
|
|
35
|
+
from .._utils import join_url, redact_headers, to_snake_case, to_snake_case_deep
|
|
35
36
|
from .._vtex import VTEX
|
|
36
37
|
|
|
37
38
|
|
|
@@ -50,8 +51,8 @@ class BaseAPI:
|
|
|
50
51
|
def _request(
|
|
51
52
|
self,
|
|
52
53
|
method: HTTPMethodType,
|
|
53
|
-
environment: str,
|
|
54
54
|
endpoint: str,
|
|
55
|
+
environment: Union[str, None] = None,
|
|
55
56
|
headers: Union[HeaderTypes, None] = None,
|
|
56
57
|
cookies: Union[CookieTypes, None] = None,
|
|
57
58
|
params: Union[QueryParamTypes, None] = None,
|
|
@@ -60,15 +61,23 @@ class BaseAPI:
|
|
|
60
61
|
content: Union[RequestContent, None] = None,
|
|
61
62
|
files: Union[RequestFiles, None] = None,
|
|
62
63
|
config: Union[VTEXConfig, None] = None,
|
|
64
|
+
rate_limit: Union[RateLimitItem, None] = None,
|
|
63
65
|
response_class: Union[Type[VTEXResponseType], None] = None,
|
|
64
66
|
**kwargs: Any,
|
|
65
67
|
) -> VTEXResponseType:
|
|
66
68
|
request_config = (config or self.client.config).with_overrides(**kwargs)
|
|
67
69
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
if environment:
|
|
71
|
+
url = join_url(
|
|
72
|
+
f"https://{request_config.account_name}.{environment}.com.br",
|
|
73
|
+
endpoint,
|
|
74
|
+
)
|
|
75
|
+
else:
|
|
76
|
+
url = join_url(
|
|
77
|
+
"https://api.vtex.com/",
|
|
78
|
+
request_config.account_name,
|
|
79
|
+
endpoint,
|
|
80
|
+
)
|
|
72
81
|
|
|
73
82
|
headers = Headers(headers=headers)
|
|
74
83
|
headers[APP_KEY_HEADER] = request_config.app_key.get_secret_value()
|
|
@@ -76,6 +85,14 @@ class BaseAPI:
|
|
|
76
85
|
headers["Content-Type"] = "application/json; charset=utf-8"
|
|
77
86
|
headers["Accept"] = "application/json"
|
|
78
87
|
|
|
88
|
+
rate_limiter = (
|
|
89
|
+
None
|
|
90
|
+
if not (rate_limit and request_config.rate_limit_storage_url)
|
|
91
|
+
else strategies.MovingWindowRateLimiter(
|
|
92
|
+
storage.storage_from_string(request_config.rate_limit_storage_url),
|
|
93
|
+
)
|
|
94
|
+
)
|
|
95
|
+
|
|
79
96
|
@retry(
|
|
80
97
|
stop=stop_after_attempt(
|
|
81
98
|
max_attempt_number=request_config.retry_attempts + 1,
|
|
@@ -102,17 +119,36 @@ class BaseAPI:
|
|
|
102
119
|
def send_vtex_request() -> Response:
|
|
103
120
|
with Client(timeout=request_config.timeout) as client:
|
|
104
121
|
with disable_loggers(["httpcore", "httpx"]):
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
122
|
+
while (
|
|
123
|
+
rate_limiter
|
|
124
|
+
and rate_limit
|
|
125
|
+
and not rate_limiter.test(
|
|
126
|
+
rate_limit,
|
|
127
|
+
request_config.account_name,
|
|
128
|
+
endpoint,
|
|
129
|
+
)
|
|
130
|
+
):
|
|
131
|
+
sleep(1)
|
|
132
|
+
|
|
133
|
+
try:
|
|
134
|
+
response = client.request(
|
|
135
|
+
method.upper(),
|
|
136
|
+
url,
|
|
137
|
+
headers=headers,
|
|
138
|
+
cookies=cookies,
|
|
139
|
+
params=params,
|
|
140
|
+
json=json,
|
|
141
|
+
data=data,
|
|
142
|
+
content=content,
|
|
143
|
+
files=files,
|
|
144
|
+
)
|
|
145
|
+
finally:
|
|
146
|
+
if rate_limiter and rate_limit:
|
|
147
|
+
rate_limiter.hit(
|
|
148
|
+
rate_limit,
|
|
149
|
+
request_config.account_name,
|
|
150
|
+
endpoint,
|
|
151
|
+
)
|
|
116
152
|
|
|
117
153
|
response.request.headers = Headers(
|
|
118
154
|
redact_headers(dict(response.request.headers)),
|
|
@@ -183,7 +219,7 @@ class BaseAPI:
|
|
|
183
219
|
method=str(response.request.method).upper(),
|
|
184
220
|
url=str(response.request.url),
|
|
185
221
|
request_headers=response.request.headers,
|
|
186
|
-
|
|
222
|
+
status_code=response.status_code,
|
|
187
223
|
data=data,
|
|
188
224
|
response_headers=response.headers,
|
|
189
225
|
) from None
|
|
@@ -28,8 +28,8 @@ class CustomAPI(BaseAPI):
|
|
|
28
28
|
def request(
|
|
29
29
|
self,
|
|
30
30
|
method: HTTPMethodType,
|
|
31
|
-
environment: str,
|
|
32
31
|
endpoint: str,
|
|
32
|
+
environment: Union[str, None] = None,
|
|
33
33
|
headers: Union[HeaderTypes, None] = None,
|
|
34
34
|
cookies: Union[CookieTypes, None] = None,
|
|
35
35
|
params: Union[QueryParamTypes, None] = None,
|
|
@@ -42,8 +42,8 @@ class CustomAPI(BaseAPI):
|
|
|
42
42
|
) -> VTEXResponseType:
|
|
43
43
|
return self._request(
|
|
44
44
|
method=method,
|
|
45
|
-
environment=environment,
|
|
46
45
|
endpoint=endpoint,
|
|
46
|
+
environment=environment,
|
|
47
47
|
headers=headers,
|
|
48
48
|
cookies=cookies,
|
|
49
49
|
params=params,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from datetime import datetime, timedelta, timezone
|
|
2
2
|
from typing import Any, Dict, List, Union
|
|
3
3
|
|
|
4
|
+
from limits import parse
|
|
5
|
+
|
|
4
6
|
from .._constants import (
|
|
5
7
|
LIST_FEED_ORDERS_MAX_PAGE_SIZE,
|
|
6
8
|
LIST_ORDERS_MAX_PAGE,
|
|
@@ -82,10 +84,11 @@ class OrdersAPI(BaseAPI):
|
|
|
82
84
|
|
|
83
85
|
response = self._request(
|
|
84
86
|
method="GET",
|
|
85
|
-
environment=self.ENVIRONMENT,
|
|
86
87
|
endpoint="/api/oms/pvt/orders/",
|
|
88
|
+
environment=self.ENVIRONMENT,
|
|
87
89
|
params=params,
|
|
88
90
|
config=self.client.config.with_overrides(**kwargs),
|
|
91
|
+
rate_limit=parse("80 per second"),
|
|
89
92
|
response_class=VTEXPaginatedItemsResponse[Any, Any],
|
|
90
93
|
)
|
|
91
94
|
|
|
@@ -98,8 +101,8 @@ class OrdersAPI(BaseAPI):
|
|
|
98
101
|
def get_order(self, order_id: str, **kwargs: Any) -> VTEXDataResponse[Any]:
|
|
99
102
|
return self._request(
|
|
100
103
|
method="GET",
|
|
101
|
-
environment=self.ENVIRONMENT,
|
|
102
104
|
endpoint=f"/api/oms/pvt/orders/{order_id}",
|
|
105
|
+
environment=self.ENVIRONMENT,
|
|
103
106
|
config=self.client.config.with_overrides(**kwargs),
|
|
104
107
|
response_class=VTEXDataResponse[Any],
|
|
105
108
|
)
|
|
@@ -111,8 +114,8 @@ class OrdersAPI(BaseAPI):
|
|
|
111
114
|
) -> VTEXItemsResponse[Any, Any]:
|
|
112
115
|
return self._request(
|
|
113
116
|
method="GET",
|
|
114
|
-
environment=self.ENVIRONMENT,
|
|
115
117
|
endpoint="/api/orders/feed/",
|
|
118
|
+
environment=self.ENVIRONMENT,
|
|
116
119
|
params={
|
|
117
120
|
"maxlot": max(
|
|
118
121
|
min(page_size, LIST_FEED_ORDERS_MAX_PAGE_SIZE),
|
|
@@ -140,8 +143,8 @@ class OrdersAPI(BaseAPI):
|
|
|
140
143
|
|
|
141
144
|
return self._request(
|
|
142
145
|
method="POST",
|
|
143
|
-
environment=self.ENVIRONMENT,
|
|
144
146
|
endpoint="/api/orders/feed/",
|
|
147
|
+
environment=self.ENVIRONMENT,
|
|
145
148
|
json={"handles": handles},
|
|
146
149
|
config=self.client.config.with_overrides(**kwargs),
|
|
147
150
|
response_class=VTEXDataResponse[Any],
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from typing import Any
|
|
2
2
|
|
|
3
|
+
from limits import parse
|
|
4
|
+
|
|
3
5
|
from .._dto import VTEXDataResponse, VTEXItemsResponse
|
|
4
6
|
from .base import BaseAPI
|
|
5
7
|
|
|
@@ -19,8 +21,8 @@ class PaymentsGatewayAPI(BaseAPI):
|
|
|
19
21
|
) -> VTEXDataResponse[Any]:
|
|
20
22
|
return self._request(
|
|
21
23
|
method="GET",
|
|
22
|
-
environment=self.ENVIRONMENT,
|
|
23
24
|
endpoint=f"/api/pvt/transactions/{transaction_id}",
|
|
25
|
+
environment=self.ENVIRONMENT,
|
|
24
26
|
config=self.client.config.with_overrides(**kwargs),
|
|
25
27
|
response_class=VTEXDataResponse[Any],
|
|
26
28
|
)
|
|
@@ -32,9 +34,10 @@ class PaymentsGatewayAPI(BaseAPI):
|
|
|
32
34
|
) -> VTEXItemsResponse[Any, Any]:
|
|
33
35
|
return self._request(
|
|
34
36
|
method="GET",
|
|
35
|
-
environment=self.ENVIRONMENT,
|
|
36
37
|
endpoint=f"/api/pvt/transactions/{transaction_id}/interactions",
|
|
38
|
+
environment=self.ENVIRONMENT,
|
|
37
39
|
config=self.client.config.with_overrides(**kwargs),
|
|
40
|
+
rate_limit=parse("60 per second"),
|
|
38
41
|
response_class=VTEXItemsResponse[Any, Any],
|
|
39
42
|
)
|
|
40
43
|
|
|
@@ -45,8 +48,8 @@ class PaymentsGatewayAPI(BaseAPI):
|
|
|
45
48
|
) -> VTEXItemsResponse[Any, Any]:
|
|
46
49
|
return self._request(
|
|
47
50
|
method="GET",
|
|
48
|
-
environment=self.ENVIRONMENT,
|
|
49
51
|
endpoint=f"/api/pvt/transactions/{transaction_id}/payments",
|
|
52
|
+
environment=self.ENVIRONMENT,
|
|
50
53
|
config=self.client.config.with_overrides(**kwargs),
|
|
51
54
|
response_class=VTEXItemsResponse[Any, Any],
|
|
52
55
|
)
|
|
@@ -59,8 +62,8 @@ class PaymentsGatewayAPI(BaseAPI):
|
|
|
59
62
|
) -> VTEXDataResponse[Any]:
|
|
60
63
|
return self._request(
|
|
61
64
|
method="GET",
|
|
62
|
-
environment=self.ENVIRONMENT,
|
|
63
65
|
endpoint=f"/api/pvt/transactions/{transaction_id}/payments/{payment_id}",
|
|
66
|
+
environment=self.ENVIRONMENT,
|
|
64
67
|
config=self.client.config.with_overrides(**kwargs),
|
|
65
68
|
response_class=VTEXDataResponse[Any],
|
|
66
69
|
)
|
|
@@ -72,8 +75,8 @@ class PaymentsGatewayAPI(BaseAPI):
|
|
|
72
75
|
) -> VTEXDataResponse[Any]:
|
|
73
76
|
return self._request(
|
|
74
77
|
method="GET",
|
|
75
|
-
environment=self.ENVIRONMENT,
|
|
76
78
|
endpoint=f"/api/pvt/transactions/{transaction_id}/capabilities",
|
|
79
|
+
environment=self.ENVIRONMENT,
|
|
77
80
|
config=self.client.config.with_overrides(**kwargs),
|
|
78
81
|
response_class=VTEXDataResponse[Any],
|
|
79
82
|
)
|
|
@@ -85,8 +88,8 @@ class PaymentsGatewayAPI(BaseAPI):
|
|
|
85
88
|
) -> VTEXDataResponse[Any]:
|
|
86
89
|
return self._request(
|
|
87
90
|
method="GET",
|
|
88
|
-
environment=self.ENVIRONMENT,
|
|
89
91
|
endpoint=f"/api/pvt/transactions/{transaction_id}/cancellations",
|
|
92
|
+
environment=self.ENVIRONMENT,
|
|
90
93
|
config=self.client.config.with_overrides(**kwargs),
|
|
91
94
|
response_class=VTEXDataResponse[Any],
|
|
92
95
|
)
|
|
@@ -98,8 +101,8 @@ class PaymentsGatewayAPI(BaseAPI):
|
|
|
98
101
|
) -> VTEXDataResponse[Any]:
|
|
99
102
|
return self._request(
|
|
100
103
|
method="GET",
|
|
101
|
-
environment=self.ENVIRONMENT,
|
|
102
104
|
endpoint=f"/api/pvt/transactions/{transaction_id}/refunds",
|
|
105
|
+
environment=self.ENVIRONMENT,
|
|
103
106
|
config=self.client.config.with_overrides(**kwargs),
|
|
104
107
|
response_class=VTEXDataResponse[Any],
|
|
105
108
|
)
|
|
@@ -111,8 +114,8 @@ class PaymentsGatewayAPI(BaseAPI):
|
|
|
111
114
|
) -> VTEXDataResponse[Any]:
|
|
112
115
|
return self._request(
|
|
113
116
|
method="GET",
|
|
114
|
-
environment=self.ENVIRONMENT,
|
|
115
117
|
endpoint=f"/api/pvt/transactions/{transaction_id}/settlements",
|
|
118
|
+
environment=self.ENVIRONMENT,
|
|
116
119
|
config=self.client.config.with_overrides(**kwargs),
|
|
117
120
|
response_class=VTEXDataResponse[Any],
|
|
118
121
|
)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from .._dto import VTEXDataResponse
|
|
4
|
+
from .base import BaseAPI
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class PricingAPI(BaseAPI):
|
|
8
|
+
"""
|
|
9
|
+
Client for the Pricing API.
|
|
10
|
+
https://developers.vtex.com/docs/api-reference/pricing-api
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def get_price(self, sku_id: str, **kwargs: Any) -> VTEXDataResponse[Any]:
|
|
14
|
+
return self._request(
|
|
15
|
+
method="GET",
|
|
16
|
+
endpoint=f"/pricing/prices/{sku_id}",
|
|
17
|
+
config=self.client.config.with_overrides(**kwargs),
|
|
18
|
+
response_class=VTEXDataResponse[Any],
|
|
19
|
+
)
|
|
@@ -15,6 +15,7 @@ from ._constants import (
|
|
|
15
15
|
DEFAULT_LOG_5XX,
|
|
16
16
|
DEFAULT_LOG_RETRIES,
|
|
17
17
|
DEFAULT_RAISE_FOR_STATUS_CODE,
|
|
18
|
+
DEFAULT_RATE_LIMIT_STORAGE_URL,
|
|
18
19
|
DEFAULT_RETRY_ATTEMPTS,
|
|
19
20
|
DEFAULT_RETRY_BACKOFF_MAX,
|
|
20
21
|
DEFAULT_RETRY_BACKOFF_MIN,
|
|
@@ -27,6 +28,7 @@ from ._constants import (
|
|
|
27
28
|
LOG_5XX_ENV_VAR,
|
|
28
29
|
LOG_RETRIES_ENV_VAR,
|
|
29
30
|
RAISE_FOR_STATUS_CODE_ENV_VAR,
|
|
31
|
+
RATE_LIMIT_STORAGE_URL_ENV_VAR,
|
|
30
32
|
RETRY_ATTEMPTS_ENV_VAR,
|
|
31
33
|
RETRY_BACKOFF_MAX_ENV_VAR,
|
|
32
34
|
RETRY_BACKOFF_MIN_ENV_VAR,
|
|
@@ -55,6 +57,8 @@ class VTEXConfig(BaseModel):
|
|
|
55
57
|
|
|
56
58
|
raise_for_status_code: bool = Field(UNDEFINED, validate_default=True)
|
|
57
59
|
|
|
60
|
+
rate_limit_storage_url: Union[str, None] = Field(UNDEFINED, validate_default=True)
|
|
61
|
+
|
|
58
62
|
log_retries: FalseOrLogLevel = Field(UNDEFINED, validate_default=True)
|
|
59
63
|
log_1xx: FalseOrLogLevel = Field(UNDEFINED, validate_default=True)
|
|
60
64
|
log_2xx: FalseOrLogLevel = Field(UNDEFINED, validate_default=True)
|
|
@@ -73,6 +77,7 @@ class VTEXConfig(BaseModel):
|
|
|
73
77
|
retry_backoff_max: Union[float, int, UndefinedSentinel] = UNDEFINED,
|
|
74
78
|
retry_status_codes: Union[List[int], UndefinedSentinel] = UNDEFINED,
|
|
75
79
|
raise_for_status_code: Union[bool, UndefinedSentinel] = UNDEFINED,
|
|
80
|
+
rate_limit_storage_url: Union[str, UndefinedSentinel] = UNDEFINED,
|
|
76
81
|
log_retries: FalseOrLogLevelOrUndefined = UNDEFINED,
|
|
77
82
|
log_1xx: FalseOrLogLevelOrUndefined = UNDEFINED,
|
|
78
83
|
log_2xx: FalseOrLogLevelOrUndefined = UNDEFINED,
|
|
@@ -93,6 +98,7 @@ class VTEXConfig(BaseModel):
|
|
|
93
98
|
"retry_backoff_max": retry_backoff_max,
|
|
94
99
|
"retry_status_codes": retry_status_codes,
|
|
95
100
|
"raise_for_status_code": raise_for_status_code,
|
|
101
|
+
"rate_limit_storage_url": rate_limit_storage_url,
|
|
96
102
|
"log_retries": log_retries,
|
|
97
103
|
"log_1xx": log_1xx,
|
|
98
104
|
"log_2xx": log_2xx,
|
|
@@ -218,6 +224,25 @@ class VTEXConfig(BaseModel):
|
|
|
218
224
|
|
|
219
225
|
raise cls._prepare_value_error(value, RAISE_FOR_STATUS_CODE_ENV_VAR)
|
|
220
226
|
|
|
227
|
+
@field_validator("rate_limit_storage_url", mode="before")
|
|
228
|
+
@classmethod
|
|
229
|
+
def validate_rate_limit_storage_url(cls, value: Any) -> Union[str, None]:
|
|
230
|
+
if isinstance(value, UndefinedSentinel):
|
|
231
|
+
value = getenv(
|
|
232
|
+
RATE_LIMIT_STORAGE_URL_ENV_VAR,
|
|
233
|
+
DEFAULT_RATE_LIMIT_STORAGE_URL,
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
if value is None:
|
|
237
|
+
return None
|
|
238
|
+
elif isinstance(value, str):
|
|
239
|
+
if value.lower() in {"", "none", "null"}:
|
|
240
|
+
return None
|
|
241
|
+
|
|
242
|
+
return value
|
|
243
|
+
|
|
244
|
+
raise cls._prepare_value_error(value, RATE_LIMIT_STORAGE_URL_ENV_VAR)
|
|
245
|
+
|
|
221
246
|
@field_validator("log_retries", mode="before")
|
|
222
247
|
@classmethod
|
|
223
248
|
def validate_log_retries(cls, value: Any) -> FalseOrLogLevel:
|
|
@@ -20,6 +20,7 @@ RETRY_BACKOFF_MIN_ENV_VAR = "VTEX_RETRY_BACKOFF_MIN"
|
|
|
20
20
|
RETRY_BACKOFF_MAX_ENV_VAR = "VTEX_RETRY_BACKOFF_MAX"
|
|
21
21
|
RETRY_STATUS_CODES_ENV_VAR = "VTEX_RETRY_STATUS_CODES"
|
|
22
22
|
RAISE_FOR_STATUS_CODE_ENV_VAR = "VTEX_RAISE_FOR_STATUS_CODE"
|
|
23
|
+
RATE_LIMIT_STORAGE_URL_ENV_VAR = "VTEX_RATE_LIMIT_STORAGE_URL"
|
|
23
24
|
LOG_RETRIES_ENV_VAR = "VTEX_LOG_RETRIES"
|
|
24
25
|
LOG_1XX_ENV_VAR = "VTEX_LOG_1XX"
|
|
25
26
|
LOG_2XX_ENV_VAR = "VTEX_LOG_2XX"
|
|
@@ -46,6 +47,7 @@ DEFAULT_RETRY_STATUS_CODES = [
|
|
|
46
47
|
525,
|
|
47
48
|
]
|
|
48
49
|
DEFAULT_RAISE_FOR_STATUS_CODE = True
|
|
50
|
+
DEFAULT_RATE_LIMIT_STORAGE_URL = None
|
|
49
51
|
DEFAULT_LOG_RETRIES = WARNING
|
|
50
52
|
DEFAULT_LOG_1XX = INFO
|
|
51
53
|
DEFAULT_LOG_2XX = INFO
|
|
@@ -14,6 +14,7 @@ if TYPE_CHECKING:
|
|
|
14
14
|
MasterDataAPI,
|
|
15
15
|
OrdersAPI,
|
|
16
16
|
PaymentsGatewayAPI,
|
|
17
|
+
PricingAPI,
|
|
17
18
|
PromotionsAndTaxesAPI,
|
|
18
19
|
)
|
|
19
20
|
|
|
@@ -76,6 +77,12 @@ class VTEX:
|
|
|
76
77
|
|
|
77
78
|
return OrdersAPI(client=self)
|
|
78
79
|
|
|
80
|
+
@cached_property
|
|
81
|
+
def pricing(self) -> "PricingAPI":
|
|
82
|
+
from ._api import PricingAPI
|
|
83
|
+
|
|
84
|
+
return PricingAPI(client=self)
|
|
85
|
+
|
|
79
86
|
@cached_property
|
|
80
87
|
def payments_gateway(self) -> "PaymentsGatewayAPI":
|
|
81
88
|
from ._api import PaymentsGatewayAPI
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -32,8 +32,8 @@ class CatalogAPI(BaseAPI):
|
|
|
32
32
|
) -> VTEXItemsResponse[List[Seller], Seller]:
|
|
33
33
|
return self._request(
|
|
34
34
|
method="GET",
|
|
35
|
-
environment=self.ENVIRONMENT,
|
|
36
35
|
endpoint="/api/catalog_system/pvt/seller/list",
|
|
36
|
+
environment=self.ENVIRONMENT,
|
|
37
37
|
params=omitting_undefined({
|
|
38
38
|
"sc": sales_channel,
|
|
39
39
|
"sellerType": seller_type,
|
|
@@ -49,8 +49,8 @@ class CatalogAPI(BaseAPI):
|
|
|
49
49
|
) -> VTEXItemsResponse[List[SalesChannel], SalesChannel]:
|
|
50
50
|
return self._request(
|
|
51
51
|
method="GET",
|
|
52
|
-
environment=self.ENVIRONMENT,
|
|
53
52
|
endpoint="/api/catalog_system/pvt/saleschannel/list",
|
|
53
|
+
environment=self.ENVIRONMENT,
|
|
54
54
|
config=self.client.config.with_overrides(**kwargs),
|
|
55
55
|
response_class=VTEXItemsResponse[Any, Any],
|
|
56
56
|
)
|
|
@@ -63,8 +63,8 @@ class CatalogAPI(BaseAPI):
|
|
|
63
63
|
) -> VTEXItemsResponse[List[int], int]:
|
|
64
64
|
return self._request(
|
|
65
65
|
method="GET",
|
|
66
|
-
environment=self.ENVIRONMENT,
|
|
67
66
|
endpoint="/api/catalog_system/pvt/sku/stockkeepingunitids",
|
|
67
|
+
environment=self.ENVIRONMENT,
|
|
68
68
|
params={
|
|
69
69
|
"page": max(page, LIST_SKU_IDS_START_PAGE),
|
|
70
70
|
"pagesize": max(
|
|
@@ -83,8 +83,8 @@ class CatalogAPI(BaseAPI):
|
|
|
83
83
|
) -> VTEXDataResponse[Any]:
|
|
84
84
|
return self._request(
|
|
85
85
|
method="GET",
|
|
86
|
-
environment=self.ENVIRONMENT,
|
|
87
86
|
endpoint=f"/api/catalog_system/pvt/sku/stockkeepingunitbyid/{sku_id}",
|
|
87
|
+
environment=self.ENVIRONMENT,
|
|
88
88
|
config=self.client.config.with_overrides(**kwargs),
|
|
89
89
|
response_class=VTEXDataResponse[Any],
|
|
90
90
|
)
|
|
@@ -97,8 +97,8 @@ class CatalogAPI(BaseAPI):
|
|
|
97
97
|
) -> VTEXPaginatedItemsResponse[Any, Any]:
|
|
98
98
|
return self._request(
|
|
99
99
|
method="GET",
|
|
100
|
-
environment=self.ENVIRONMENT,
|
|
101
100
|
endpoint="/api/catalog/pvt/category",
|
|
101
|
+
environment=self.ENVIRONMENT,
|
|
102
102
|
params={
|
|
103
103
|
"page": max(page, LIST_CATEGORIES_START_PAGE),
|
|
104
104
|
"pagesize": max(
|
|
@@ -117,8 +117,8 @@ class CatalogAPI(BaseAPI):
|
|
|
117
117
|
) -> VTEXDataResponse[Any]:
|
|
118
118
|
return self._request(
|
|
119
119
|
method="GET",
|
|
120
|
-
environment=self.ENVIRONMENT,
|
|
121
120
|
endpoint=f"/api/catalog_system/pub/category/tree/{levels}",
|
|
121
|
+
environment=self.ENVIRONMENT,
|
|
122
122
|
config=self.client.config.with_overrides(**kwargs),
|
|
123
123
|
response_class=VTEXDataResponse[Any],
|
|
124
124
|
)
|
|
@@ -130,8 +130,8 @@ class CatalogAPI(BaseAPI):
|
|
|
130
130
|
) -> VTEXDataResponse[Any]:
|
|
131
131
|
return self._request(
|
|
132
132
|
method="GET",
|
|
133
|
-
environment=self.ENVIRONMENT,
|
|
134
133
|
endpoint=f"/api/catalog/pvt/category/{category_id}",
|
|
134
|
+
environment=self.ENVIRONMENT,
|
|
135
135
|
config=self.client.config.with_overrides(**kwargs),
|
|
136
136
|
response_class=VTEXDataResponse[Any],
|
|
137
137
|
)
|
|
@@ -27,8 +27,8 @@ class CheckoutAPI(BaseAPI):
|
|
|
27
27
|
) -> VTEXDataResponse[Any]:
|
|
28
28
|
return self._request(
|
|
29
29
|
method="POST",
|
|
30
|
-
environment=self.ENVIRONMENT,
|
|
31
30
|
endpoint="/api/checkout/pub/orderForms/simulation",
|
|
31
|
+
environment=self.ENVIRONMENT,
|
|
32
32
|
params=omitting_undefined({
|
|
33
33
|
"RnbBehavior": rnb_behavior,
|
|
34
34
|
"sc": sales_channel,
|
|
@@ -27,8 +27,8 @@ class LicenseManagerAPI(BaseAPI):
|
|
|
27
27
|
def get_account(self, **kwargs: Any) -> VTEXDataResponse[GetAccountData]:
|
|
28
28
|
return self._request(
|
|
29
29
|
method="GET",
|
|
30
|
-
environment=self.ENVIRONMENT,
|
|
31
30
|
endpoint="/api/vlm/account",
|
|
31
|
+
environment=self.ENVIRONMENT,
|
|
32
32
|
config=self.client.config.with_overrides(**kwargs),
|
|
33
33
|
response_class=VTEXDataResponse[GetAccountData],
|
|
34
34
|
)
|
|
@@ -50,8 +50,8 @@ class LicenseManagerAPI(BaseAPI):
|
|
|
50
50
|
|
|
51
51
|
return self._request(
|
|
52
52
|
method="GET",
|
|
53
|
-
environment=self.ENVIRONMENT,
|
|
54
53
|
endpoint=f"/api/license-manager/users/{user_id}/roles",
|
|
54
|
+
environment=self.ENVIRONMENT,
|
|
55
55
|
config=config,
|
|
56
56
|
response_class=VTEXItemsResponse[List[UserRole], UserRole],
|
|
57
57
|
)
|
|
@@ -66,8 +66,8 @@ class LicenseManagerAPI(BaseAPI):
|
|
|
66
66
|
) -> VTEXPaginatedItemsResponse[ListRolesData, Role]:
|
|
67
67
|
return self._request(
|
|
68
68
|
method="GET",
|
|
69
|
-
environment=self.ENVIRONMENT,
|
|
70
69
|
endpoint="/api/license-manager/site/pvt/roles/list/paged",
|
|
70
|
+
environment=self.ENVIRONMENT,
|
|
71
71
|
params={
|
|
72
72
|
"sort": order_by_field,
|
|
73
73
|
"sortType": order_by_direction,
|
|
@@ -29,8 +29,8 @@ class LogisticsAPI(BaseAPI):
|
|
|
29
29
|
) -> VTEXPaginatedItemsResponse[Any, Any]:
|
|
30
30
|
return self._request(
|
|
31
31
|
method="GET",
|
|
32
|
-
environment=self.ENVIRONMENT,
|
|
33
32
|
endpoint="/api/logistics/pvt/shipping-policies",
|
|
33
|
+
environment=self.ENVIRONMENT,
|
|
34
34
|
params={
|
|
35
35
|
"page": max(page, LIST_SHIPPING_POLICIES_START_PAGE),
|
|
36
36
|
"perPage": max(
|
|
@@ -49,8 +49,8 @@ class LogisticsAPI(BaseAPI):
|
|
|
49
49
|
) -> VTEXDataResponse[Any]:
|
|
50
50
|
return self._request(
|
|
51
51
|
method="GET",
|
|
52
|
-
environment=self.ENVIRONMENT,
|
|
53
52
|
endpoint=f"/api/logistics/pvt/shipping-policies/{shipping_policy_id}",
|
|
53
|
+
environment=self.ENVIRONMENT,
|
|
54
54
|
config=self.client.config.with_overrides(**kwargs),
|
|
55
55
|
response_class=VTEXDataResponse[Any],
|
|
56
56
|
)
|
|
@@ -63,8 +63,8 @@ class LogisticsAPI(BaseAPI):
|
|
|
63
63
|
) -> VTEXPaginatedItemsResponse[Any, Any]:
|
|
64
64
|
return self._request(
|
|
65
65
|
method="GET",
|
|
66
|
-
environment=self.ENVIRONMENT,
|
|
67
66
|
endpoint="/api/logistics/pvt/configuration/carriers",
|
|
67
|
+
environment=self.ENVIRONMENT,
|
|
68
68
|
params={
|
|
69
69
|
"page": max(page, LIST_CARRIERS_START_PAGE),
|
|
70
70
|
"perPage": max(
|
|
@@ -83,8 +83,8 @@ class LogisticsAPI(BaseAPI):
|
|
|
83
83
|
) -> VTEXDataResponse[Any]:
|
|
84
84
|
return self._request(
|
|
85
85
|
method="GET",
|
|
86
|
-
environment=self.ENVIRONMENT,
|
|
87
86
|
endpoint=f"/api/logistics/pvt/configuration/carriers/{carrier_id}",
|
|
87
|
+
environment=self.ENVIRONMENT,
|
|
88
88
|
config=self.client.config.with_overrides(**kwargs),
|
|
89
89
|
response_class=VTEXDataResponse[Any],
|
|
90
90
|
)
|
|
@@ -97,8 +97,8 @@ class LogisticsAPI(BaseAPI):
|
|
|
97
97
|
) -> VTEXPaginatedItemsResponse[Any, Any]:
|
|
98
98
|
return self._request(
|
|
99
99
|
method="GET",
|
|
100
|
-
environment=self.ENVIRONMENT,
|
|
101
100
|
endpoint="/api/logistics/pvt/configuration/docks",
|
|
101
|
+
environment=self.ENVIRONMENT,
|
|
102
102
|
params={
|
|
103
103
|
"page": max(page, LIST_DOCKS_START_PAGE),
|
|
104
104
|
"perPage": max(
|
|
@@ -113,8 +113,8 @@ class LogisticsAPI(BaseAPI):
|
|
|
113
113
|
def get_dock(self, dock_id: str, **kwargs: Any) -> VTEXDataResponse[Any]:
|
|
114
114
|
return self._request(
|
|
115
115
|
method="GET",
|
|
116
|
-
environment=self.ENVIRONMENT,
|
|
117
116
|
endpoint=f"/api/logistics/pvt/configuration/docks/{dock_id}",
|
|
117
|
+
environment=self.ENVIRONMENT,
|
|
118
118
|
config=self.client.config.with_overrides(**kwargs),
|
|
119
119
|
response_class=VTEXDataResponse[Any],
|
|
120
120
|
)
|
|
@@ -127,11 +127,11 @@ class LogisticsAPI(BaseAPI):
|
|
|
127
127
|
) -> VTEXItemsResponse[Any, Any]:
|
|
128
128
|
return self._request(
|
|
129
129
|
method="GET",
|
|
130
|
-
environment=self.ENVIRONMENT,
|
|
131
130
|
endpoint=(
|
|
132
131
|
f"/api/logistics/pvt/configuration/freights/{carrier_id}/{zip_code}"
|
|
133
132
|
f"/values"
|
|
134
133
|
),
|
|
134
|
+
environment=self.ENVIRONMENT,
|
|
135
135
|
config=self.client.config.with_overrides(**kwargs),
|
|
136
136
|
response_class=VTEXItemsResponse[Any, Any],
|
|
137
137
|
)
|
|
@@ -143,8 +143,8 @@ class LogisticsAPI(BaseAPI):
|
|
|
143
143
|
) -> VTEXDataResponse[Any]:
|
|
144
144
|
return self._request(
|
|
145
145
|
method="GET",
|
|
146
|
-
environment=self.ENVIRONMENT,
|
|
147
146
|
endpoint=f"/api/logistics/pvt/inventory/skus/{sku_id}",
|
|
147
|
+
environment=self.ENVIRONMENT,
|
|
148
148
|
config=self.client.config.with_overrides(**kwargs),
|
|
149
149
|
response_class=VTEXDataResponse[Any],
|
|
150
150
|
)
|
|
@@ -51,8 +51,8 @@ class MasterDataAPI(BaseAPI):
|
|
|
51
51
|
|
|
52
52
|
return self._request(
|
|
53
53
|
method="GET",
|
|
54
|
-
environment=self.ENVIRONMENT,
|
|
55
54
|
endpoint=f"/api/dataentities/{entity_name}/search",
|
|
55
|
+
environment=self.ENVIRONMENT,
|
|
56
56
|
params=omitting_undefined(params),
|
|
57
57
|
headers={
|
|
58
58
|
"REST-Range": f"resources={(page - 1) * page_size}-{page * page_size}",
|
|
@@ -18,8 +18,8 @@ class PromotionsAndTaxesAPI(BaseAPI):
|
|
|
18
18
|
) -> VTEXItemsResponse[Any, Any]:
|
|
19
19
|
return self._request(
|
|
20
20
|
method="GET",
|
|
21
|
-
environment=self.ENVIRONMENT,
|
|
22
21
|
endpoint="api/rnb/pvt/archive/benefits/calculatorconfiguration",
|
|
22
|
+
environment=self.ENVIRONMENT,
|
|
23
23
|
config=self.client.config.with_overrides(**kwargs),
|
|
24
24
|
response_class=VTEXItemsResponse[Any, Any],
|
|
25
25
|
)
|
|
@@ -27,8 +27,8 @@ class PromotionsAndTaxesAPI(BaseAPI):
|
|
|
27
27
|
def get_promotions(self, **kwargs: Any) -> VTEXDataResponse[Any]:
|
|
28
28
|
return self._request(
|
|
29
29
|
method="GET",
|
|
30
|
-
environment=self.ENVIRONMENT,
|
|
31
30
|
endpoint="api/rnb/pvt/benefits/calculatorconfiguration",
|
|
31
|
+
environment=self.ENVIRONMENT,
|
|
32
32
|
config=self.client.config.with_overrides(**kwargs),
|
|
33
33
|
response_class=VTEXDataResponse[Any],
|
|
34
34
|
)
|
|
@@ -36,8 +36,8 @@ class PromotionsAndTaxesAPI(BaseAPI):
|
|
|
36
36
|
def get_taxes(self, **kwargs: Any) -> VTEXDataResponse[Any]:
|
|
37
37
|
return self._request(
|
|
38
38
|
method="GET",
|
|
39
|
-
environment=self.ENVIRONMENT,
|
|
40
39
|
endpoint="api/rnb/pvt/taxes/calculatorconfiguration",
|
|
40
|
+
environment=self.ENVIRONMENT,
|
|
41
41
|
config=self.client.config.with_overrides(**kwargs),
|
|
42
42
|
response_class=VTEXDataResponse[Any],
|
|
43
43
|
)
|
|
@@ -49,8 +49,8 @@ class PromotionsAndTaxesAPI(BaseAPI):
|
|
|
49
49
|
) -> VTEXDataResponse[Any]:
|
|
50
50
|
return self._request(
|
|
51
51
|
method="GET",
|
|
52
|
-
environment=self.ENVIRONMENT,
|
|
53
52
|
endpoint=f"/api/rnb/pvt/calculatorconfiguration/{promotion_or_tax_id}",
|
|
53
|
+
environment=self.ENVIRONMENT,
|
|
54
54
|
config=self.client.config.with_overrides(**kwargs),
|
|
55
55
|
response_class=VTEXDataResponse[Any],
|
|
56
56
|
)
|
|
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
|