vtexpy 0.0.0b16__tar.gz → 0.0.0b17__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.0b16 → vtexpy-0.0.0b17}/PKG-INFO +29 -25
- vtexpy-0.0.0b17/README.md +63 -0
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/pyproject.toml +17 -9
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/__init__.py +2 -0
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_api/base.py +62 -39
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_api/catalog.py +26 -14
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_api/checkout.py +5 -6
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_api/custom.py +23 -14
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_api/license_manager.py +1 -1
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_api/logistics.py +14 -15
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_api/master_data.py +5 -5
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_api/orders.py +9 -9
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_api/payments_gateway.py +16 -17
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_api/promotions_and_taxes.py +8 -9
- vtexpy-0.0.0b17/vtex/_api/types/catalog.py +21 -0
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_api/types/generic.py +4 -4
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_api/types/license_manager.py +13 -7
- vtexpy-0.0.0b17/vtex/_config.py +338 -0
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_constants.py +18 -6
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_dto.py +22 -17
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_logging.py +28 -6
- vtexpy-0.0.0b17/vtex/_types.py +37 -0
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_utils.py +16 -20
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_vtex.py +4 -30
- vtexpy-0.0.0b16/README.md +0 -60
- vtexpy-0.0.0b16/vtex/_config.py +0 -478
- vtexpy-0.0.0b16/vtex/_types.py +0 -22
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/LICENSE +0 -0
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_api/__init__.py +0 -0
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_api/types/__init__.py +0 -0
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_exceptions.py +0 -0
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/_sentinels.py +0 -0
- {vtexpy-0.0.0b16 → vtexpy-0.0.0b17}/vtex/py.typed +0 -0
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: vtexpy
|
|
3
|
-
Version: 0.0.
|
|
4
|
-
Summary: Unofficial Python SDK
|
|
3
|
+
Version: 0.0.0b17
|
|
4
|
+
Summary: Unofficial VTEX API's Python SDK
|
|
5
5
|
Home-page: https://github.com/lvieirajr/vtex-python
|
|
6
|
-
License:
|
|
6
|
+
License: Apache
|
|
7
7
|
Keywords: vtex,sdk,client,api
|
|
8
8
|
Author: Luis Vieira
|
|
9
9
|
Author-email: lvieira@lvieira.com
|
|
10
10
|
Maintainer: Luis Vieira
|
|
11
11
|
Maintainer-email: lvieira@lvieira.com
|
|
12
|
-
Requires-Python: >=3.9,<3.
|
|
12
|
+
Requires-Python: >=3.9,<3.13
|
|
13
13
|
Classifier: Development Status :: 4 - Beta
|
|
14
14
|
Classifier: Intended Audience :: Developers
|
|
15
15
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
16
|
-
Classifier: License ::
|
|
16
|
+
Classifier: License :: Other/Proprietary License
|
|
17
17
|
Classifier: Operating System :: OS Independent
|
|
18
18
|
Classifier: Programming Language :: Python
|
|
19
19
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -21,13 +21,14 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.10
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.11
|
|
23
23
|
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
25
24
|
Classifier: Topic :: Software Development :: Libraries
|
|
26
25
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
26
|
Classifier: Typing :: Typed
|
|
28
27
|
Requires-Dist: httpx (>=0.26,<1.0)
|
|
28
|
+
Requires-Dist: pydantic (>=2.6,<3.0)
|
|
29
29
|
Requires-Dist: python-dateutil (>=2.9,<3.0)
|
|
30
30
|
Requires-Dist: tenacity (>=8.3,<10.0)
|
|
31
|
+
Requires-Dist: typing-extensions (>=4.7,<5.0) ; python_version < "3.12"
|
|
31
32
|
Project-URL: Documentation, https://github.com/lvieirajr/vtex-python
|
|
32
33
|
Project-URL: Repository, https://github.com/lvieirajr/vtex-python
|
|
33
34
|
Description-Content-Type: text/markdown
|
|
@@ -35,7 +36,7 @@ Description-Content-Type: text/markdown
|
|
|
35
36
|
# VTEXPY
|
|
36
37
|
[](https://pypi.python.org/pypi/vtexpy)
|
|
37
38
|
|
|
38
|
-
## Unofficial Python SDK
|
|
39
|
+
## Unofficial VTEX API's Python SDK
|
|
39
40
|
|
|
40
41
|
VTEXPY is an unofficial Python SDK designed to facilitate integration with the VTEX API.
|
|
41
42
|
|
|
@@ -45,19 +46,17 @@ API.
|
|
|
45
46
|
|
|
46
47
|
### Features
|
|
47
48
|
|
|
48
|
-
- Easy to use Python interface for calling
|
|
49
|
+
- Easy to use Python interface for calling VTEX API endpoints
|
|
50
|
+
- Response format standardization
|
|
49
51
|
- Custom exception handling
|
|
50
|
-
- Automatic
|
|
52
|
+
- Automatic request retrying
|
|
51
53
|
- Request logging
|
|
52
54
|
|
|
53
55
|
### Getting Started
|
|
54
56
|
|
|
55
57
|
#### Requirements
|
|
56
58
|
|
|
57
|
-
- Python >= 3.9, < 3.
|
|
58
|
-
- httpx >= 0.26, < 1.0
|
|
59
|
-
- python-dateutil >= 2.9, < 3.0
|
|
60
|
-
- tenacity >= 8.3, < 10.0
|
|
59
|
+
- Python >= 3.9, < 3.13
|
|
61
60
|
|
|
62
61
|
#### Installation
|
|
63
62
|
|
|
@@ -67,29 +66,34 @@ pip install vtexpy
|
|
|
67
66
|
|
|
68
67
|
#### Usage
|
|
69
68
|
|
|
70
|
-
If the API you want to call is not yet implemented, feel free to create an issue on the
|
|
69
|
+
If the API you want to call is not yet implemented, feel free to create an issue on the
|
|
71
70
|
VTEXPY Github repository and request it to be added.
|
|
72
71
|
|
|
73
72
|
```python
|
|
74
|
-
from vtex import VTEX
|
|
73
|
+
from vtex import VTEX, VTEXConfig
|
|
75
74
|
|
|
76
|
-
#
|
|
77
|
-
|
|
78
|
-
account_name="<ACCOUNT_NAME>",
|
|
79
|
-
app_key="<APP_KEY>",
|
|
75
|
+
# Instantiate your VTEX API configuration:
|
|
76
|
+
vtex_config = VTEXConfig(
|
|
77
|
+
account_name="<ACCOUNT_NAME>",
|
|
78
|
+
app_key="<APP_KEY>",
|
|
80
79
|
app_token="<APP_TOKEN>",
|
|
80
|
+
# Other arguments such as: retrying, logging, etc...
|
|
81
81
|
)
|
|
82
82
|
|
|
83
|
-
#
|
|
84
|
-
vtex_client
|
|
85
|
-
vtex_client.catalog.list_sku_ids(page=1, page_size=1000)
|
|
86
|
-
vtex_client.orders.list_orders(page=1, page_size=100)
|
|
83
|
+
# Instantiate the VTEX client with your configuration:
|
|
84
|
+
vtex_client = VTEX(config=vtex_config)
|
|
87
85
|
|
|
88
|
-
#
|
|
89
|
-
vtex_client.
|
|
86
|
+
# Call one of the available APIs, e.g.:
|
|
87
|
+
account_response = vtex_client.license_manager.get_account()
|
|
88
|
+
list_sku_ids_response = vtex_client.catalog.list_sku_ids(page=1, page_size=1000)
|
|
89
|
+
list_orders_response = vtex_client.orders.list_orders(page=1, page_size=100)
|
|
90
|
+
|
|
91
|
+
# If the API you want to call is not yet implemented you can use the `custom` API.
|
|
92
|
+
response = vtex_client.custom.request(
|
|
90
93
|
method="GET",
|
|
91
94
|
environment="vtexcommercestable",
|
|
92
95
|
endpoint="/api/catalog_system/pvt/commercialcondition/list",
|
|
96
|
+
# Other arguments such as: query params, headers, json data, response class, etc...
|
|
93
97
|
)
|
|
94
98
|
```
|
|
95
99
|
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# VTEXPY
|
|
2
|
+
[](https://pypi.python.org/pypi/vtexpy)
|
|
3
|
+
|
|
4
|
+
## Unofficial VTEX API's Python SDK
|
|
5
|
+
|
|
6
|
+
VTEXPY is an unofficial Python SDK designed to facilitate integration with the VTEX API.
|
|
7
|
+
|
|
8
|
+
Even though it is still tagged as beta, vtexpy has been in use by a _SaaS_ company in a
|
|
9
|
+
production environment for over a year, making millions of requests a day to the VTEX
|
|
10
|
+
API.
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
- Easy to use Python interface for calling VTEX API endpoints
|
|
15
|
+
- Response format standardization
|
|
16
|
+
- Custom exception handling
|
|
17
|
+
- Automatic request retrying
|
|
18
|
+
- Request logging
|
|
19
|
+
|
|
20
|
+
### Getting Started
|
|
21
|
+
|
|
22
|
+
#### Requirements
|
|
23
|
+
|
|
24
|
+
- Python >= 3.9, < 3.13
|
|
25
|
+
|
|
26
|
+
#### Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install vtexpy
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
#### Usage
|
|
33
|
+
|
|
34
|
+
If the API you want to call is not yet implemented, feel free to create an issue on the
|
|
35
|
+
VTEXPY Github repository and request it to be added.
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from vtex import VTEX, VTEXConfig
|
|
39
|
+
|
|
40
|
+
# Instantiate your VTEX API configuration:
|
|
41
|
+
vtex_config = VTEXConfig(
|
|
42
|
+
account_name="<ACCOUNT_NAME>",
|
|
43
|
+
app_key="<APP_KEY>",
|
|
44
|
+
app_token="<APP_TOKEN>",
|
|
45
|
+
# Other arguments such as: retrying, logging, etc...
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
# Instantiate the VTEX client with your configuration:
|
|
49
|
+
vtex_client = VTEX(config=vtex_config)
|
|
50
|
+
|
|
51
|
+
# Call one of the available APIs, e.g.:
|
|
52
|
+
account_response = vtex_client.license_manager.get_account()
|
|
53
|
+
list_sku_ids_response = vtex_client.catalog.list_sku_ids(page=1, page_size=1000)
|
|
54
|
+
list_orders_response = vtex_client.orders.list_orders(page=1, page_size=100)
|
|
55
|
+
|
|
56
|
+
# If the API you want to call is not yet implemented you can use the `custom` API.
|
|
57
|
+
response = vtex_client.custom.request(
|
|
58
|
+
method="GET",
|
|
59
|
+
environment="vtexcommercestable",
|
|
60
|
+
endpoint="/api/catalog_system/pvt/commercialcondition/list",
|
|
61
|
+
# Other arguments such as: query params, headers, json data, response class, etc...
|
|
62
|
+
)
|
|
63
|
+
```
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["poetry-core"]
|
|
3
|
+
build-backend = "poetry.core.masonry.api"
|
|
4
|
+
|
|
1
5
|
[tool.poetry]
|
|
2
6
|
name = "vtexpy"
|
|
3
|
-
description = "Unofficial Python SDK
|
|
7
|
+
description = "Unofficial VTEX API's Python SDK"
|
|
8
|
+
version = "0.0.0b17"
|
|
4
9
|
readme = "README.md"
|
|
5
|
-
license = "
|
|
10
|
+
license = "Apache"
|
|
6
11
|
authors = [
|
|
7
12
|
"Luis Vieira <lvieira@lvieira.com>",
|
|
8
13
|
]
|
|
@@ -23,7 +28,6 @@ classifiers = [
|
|
|
23
28
|
"Programming Language :: Python :: 3.10",
|
|
24
29
|
"Programming Language :: Python :: 3.11",
|
|
25
30
|
"Programming Language :: Python :: 3.12",
|
|
26
|
-
"Programming Language :: Python :: 3.13",
|
|
27
31
|
"Operating System :: OS Independent",
|
|
28
32
|
"Topic :: Software Development :: Libraries",
|
|
29
33
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
@@ -32,17 +36,14 @@ classifiers = [
|
|
|
32
36
|
packages = [
|
|
33
37
|
{include = "vtex"},
|
|
34
38
|
]
|
|
35
|
-
version = "0.0.0b16"
|
|
36
|
-
|
|
37
|
-
[build-system]
|
|
38
|
-
requires = ["poetry-core"]
|
|
39
|
-
build-backend = "poetry.core.masonry.api"
|
|
40
39
|
|
|
41
40
|
[tool.poetry.dependencies]
|
|
42
|
-
python = ">=3.9,<3.
|
|
41
|
+
python = ">=3.9,<3.13"
|
|
43
42
|
httpx = {version = ">=0.26,<1.0"}
|
|
43
|
+
pydantic = {version = ">=2.6,<3.0"}
|
|
44
44
|
python-dateutil = {version = ">=2.9,<3.0"}
|
|
45
45
|
tenacity = {version = ">=8.3,<10.0"}
|
|
46
|
+
typing-extensions = {version = ">=4.7,<5.0", markers = "python_version < \"3.12\""}
|
|
46
47
|
|
|
47
48
|
[tool.poetry.group.dev.dependencies]
|
|
48
49
|
ipdb = {version = "*"}
|
|
@@ -51,6 +52,7 @@ mock = {version = "*"}
|
|
|
51
52
|
mypy = {version = "*"}
|
|
52
53
|
pip = {version = "*"}
|
|
53
54
|
poetry = {version = "*"}
|
|
55
|
+
pre-commit = {version = "*"}
|
|
54
56
|
pytest = {version = "*"}
|
|
55
57
|
pytest-mock = {version = "*"}
|
|
56
58
|
ruff = {version = "*"}
|
|
@@ -59,6 +61,9 @@ types-decorator = {version = "*"}
|
|
|
59
61
|
types-python-dateutil = {version = "*"}
|
|
60
62
|
types-six = {version = "*"}
|
|
61
63
|
|
|
64
|
+
[tool.poetry.scripts]
|
|
65
|
+
install-hooks = "pre-commit install:main"
|
|
66
|
+
|
|
62
67
|
|
|
63
68
|
# ======
|
|
64
69
|
# PyTest
|
|
@@ -79,9 +84,12 @@ mock_use_standalone_module = true
|
|
|
79
84
|
[tool.mypy]
|
|
80
85
|
exclude = [".*tests/*"]
|
|
81
86
|
ignore_missing_imports = true
|
|
87
|
+
install_types = true
|
|
82
88
|
namespace_packages = true
|
|
83
89
|
no_implicit_reexport = false
|
|
90
|
+
non_interactive = true
|
|
84
91
|
plugins = []
|
|
92
|
+
pretty = true
|
|
85
93
|
strict = true
|
|
86
94
|
|
|
87
95
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from . import _constants as VTEXConstants # noqa: N812
|
|
2
|
+
from ._config import VTEXConfig
|
|
2
3
|
from ._dto import (
|
|
3
4
|
VTEXCartItem,
|
|
4
5
|
VTEXDataResponse,
|
|
@@ -12,6 +13,7 @@ from ._vtex import VTEX
|
|
|
12
13
|
__all__ = [
|
|
13
14
|
"VTEX",
|
|
14
15
|
"VTEXCartItem",
|
|
16
|
+
"VTEXConfig",
|
|
15
17
|
"VTEXConstants",
|
|
16
18
|
"VTEXError",
|
|
17
19
|
"VTEXDataResponse",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from http import HTTPStatus
|
|
2
2
|
from json import JSONDecodeError
|
|
3
|
-
from logging import WARNING
|
|
4
3
|
from typing import Any, Type, Union, cast
|
|
5
4
|
from urllib.parse import urljoin
|
|
6
5
|
|
|
@@ -26,11 +25,11 @@ from tenacity import (
|
|
|
26
25
|
wait_exponential,
|
|
27
26
|
)
|
|
28
27
|
|
|
29
|
-
from .._config import
|
|
28
|
+
from .._config import VTEXConfig
|
|
30
29
|
from .._constants import APP_KEY_HEADER, APP_TOKEN_HEADER
|
|
31
30
|
from .._dto import VTEXDataResponse, VTEXResponseType
|
|
32
31
|
from .._exceptions import VTEXRequestError, VTEXResponseError
|
|
33
|
-
from .._logging import get_logger, log_before_retry
|
|
32
|
+
from .._logging import disable_loggers, get_logger, log_before_retry
|
|
34
33
|
from .._types import HTTPMethodType
|
|
35
34
|
from .._utils import redact_headers, to_snake_case, to_snake_case_deep
|
|
36
35
|
from .._vtex import VTEX
|
|
@@ -60,58 +59,89 @@ class BaseAPI:
|
|
|
60
59
|
data: Union[RequestData, None] = None,
|
|
61
60
|
content: Union[RequestContent, None] = None,
|
|
62
61
|
files: Union[RequestFiles, None] = None,
|
|
63
|
-
config: Union[
|
|
62
|
+
config: Union[VTEXConfig, None] = None,
|
|
64
63
|
response_class: Union[Type[VTEXResponseType], None] = None,
|
|
64
|
+
**kwargs: Any,
|
|
65
65
|
) -> VTEXResponseType:
|
|
66
|
-
request_config = config or self.client.config
|
|
66
|
+
request_config = (config or self.client.config).with_overrides(**kwargs)
|
|
67
67
|
|
|
68
68
|
url = urljoin(
|
|
69
|
-
f"https://{request_config.
|
|
69
|
+
f"https://{request_config.account_name}.{environment}.com.br",
|
|
70
70
|
endpoint,
|
|
71
71
|
)
|
|
72
72
|
|
|
73
73
|
headers = Headers(headers=headers)
|
|
74
|
-
headers[APP_KEY_HEADER] = request_config.
|
|
75
|
-
headers[APP_TOKEN_HEADER] = request_config.
|
|
74
|
+
headers[APP_KEY_HEADER] = request_config.app_key.get_secret_value()
|
|
75
|
+
headers[APP_TOKEN_HEADER] = request_config.app_token.get_secret_value()
|
|
76
76
|
headers["Content-Type"] = "application/json; charset=utf-8"
|
|
77
77
|
headers["Accept"] = "application/json"
|
|
78
78
|
|
|
79
79
|
@retry(
|
|
80
80
|
stop=stop_after_attempt(
|
|
81
|
-
max_attempt_number=request_config.
|
|
81
|
+
max_attempt_number=request_config.retry_attempts + 1,
|
|
82
82
|
),
|
|
83
83
|
wait=wait_exponential(
|
|
84
|
-
min=request_config.
|
|
85
|
-
max=request_config.
|
|
86
|
-
exp_base=
|
|
84
|
+
min=request_config.retry_backoff_min,
|
|
85
|
+
max=request_config.retry_backoff_max,
|
|
86
|
+
exp_base=2.0,
|
|
87
87
|
),
|
|
88
|
-
retry=retry_if_exception_type(exception_types=
|
|
88
|
+
retry=retry_if_exception_type(exception_types=HTTPStatusError),
|
|
89
89
|
before_sleep=(
|
|
90
|
-
log_before_retry(
|
|
91
|
-
|
|
90
|
+
log_before_retry(
|
|
91
|
+
logger=self.logger,
|
|
92
|
+
log_level=request_config.log_retries,
|
|
93
|
+
environment=environment,
|
|
94
|
+
endpoint=endpoint,
|
|
95
|
+
account_name=request_config.account_name,
|
|
96
|
+
)
|
|
97
|
+
if request_config.log_retries is not False
|
|
92
98
|
else None
|
|
93
99
|
),
|
|
94
100
|
reraise=True,
|
|
95
101
|
)
|
|
96
102
|
def send_vtex_request() -> Response:
|
|
97
|
-
with Client(timeout=request_config.
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
103
|
+
with Client(timeout=request_config.timeout) as client:
|
|
104
|
+
with disable_loggers(["httpcore", "httpx"]):
|
|
105
|
+
response = client.request(
|
|
106
|
+
method.upper(),
|
|
107
|
+
url,
|
|
108
|
+
headers=headers,
|
|
109
|
+
cookies=cookies,
|
|
110
|
+
params=params,
|
|
111
|
+
json=json,
|
|
112
|
+
data=data,
|
|
113
|
+
content=content,
|
|
114
|
+
files=files,
|
|
115
|
+
)
|
|
109
116
|
|
|
110
117
|
response.request.headers = Headers(
|
|
111
118
|
redact_headers(dict(response.request.headers)),
|
|
112
119
|
)
|
|
113
120
|
response.headers = Headers(redact_headers(dict(response.headers)))
|
|
114
|
-
|
|
121
|
+
|
|
122
|
+
for should_log, log_level in [
|
|
123
|
+
(response.is_informational, request_config.log_1xx),
|
|
124
|
+
(response.is_success, request_config.log_2xx),
|
|
125
|
+
(response.is_redirect, request_config.log_3xx),
|
|
126
|
+
(response.is_client_error, request_config.log_4xx),
|
|
127
|
+
(response.is_server_error, request_config.log_5xx),
|
|
128
|
+
]:
|
|
129
|
+
if should_log and log_level:
|
|
130
|
+
self.logger.log(
|
|
131
|
+
log_level,
|
|
132
|
+
f"{response.request.method} {response.request.url} "
|
|
133
|
+
f"{response.status_code} {response.reason_phrase}",
|
|
134
|
+
extra={
|
|
135
|
+
"method": response.request.method,
|
|
136
|
+
"url": response.request.url,
|
|
137
|
+
"status": response.status_code,
|
|
138
|
+
"environment": environment,
|
|
139
|
+
"endpoint": endpoint,
|
|
140
|
+
"account_name": request_config.account_name,
|
|
141
|
+
},
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
if response.status_code in request_config.retry_statuses:
|
|
115
145
|
response.raise_for_status()
|
|
116
146
|
|
|
117
147
|
return response
|
|
@@ -141,14 +171,14 @@ class BaseAPI:
|
|
|
141
171
|
(response_class or VTEXDataResponse).factory(response),
|
|
142
172
|
)
|
|
143
173
|
|
|
144
|
-
def _raise_from_response(self, response: Response, config:
|
|
145
|
-
if response.is_error and config.
|
|
174
|
+
def _raise_from_response(self, response: Response, config: VTEXConfig) -> None:
|
|
175
|
+
if response.is_error and config.raise_for_status:
|
|
146
176
|
try:
|
|
147
177
|
data = to_snake_case_deep(response.json(strict=False))
|
|
148
178
|
except JSONDecodeError:
|
|
149
179
|
data = response.text or HTTPStatus(response.status_code).phrase
|
|
150
180
|
|
|
151
|
-
|
|
181
|
+
raise VTEXResponseError(
|
|
152
182
|
data,
|
|
153
183
|
method=str(response.request.method).upper(),
|
|
154
184
|
url=str(response.request.url),
|
|
@@ -156,11 +186,4 @@ class BaseAPI:
|
|
|
156
186
|
status=response.status_code,
|
|
157
187
|
data=data,
|
|
158
188
|
response_headers=response.headers,
|
|
159
|
-
)
|
|
160
|
-
|
|
161
|
-
if response.is_server_error:
|
|
162
|
-
self.logger.error(data, extra=error.to_dict())
|
|
163
|
-
else:
|
|
164
|
-
self.logger.warning(data, extra=error.to_dict())
|
|
165
|
-
|
|
166
|
-
raise error from None
|
|
189
|
+
) from None
|
|
@@ -10,9 +10,9 @@ from .._constants import (
|
|
|
10
10
|
)
|
|
11
11
|
from .._dto import VTEXDataResponse, VTEXItemsResponse, VTEXPaginatedItemsResponse
|
|
12
12
|
from .._sentinels import UNDEFINED, UndefinedSentinel
|
|
13
|
-
from ..
|
|
14
|
-
from .._utils import exclude_undefined_values
|
|
13
|
+
from .._utils import omitting_undefined
|
|
15
14
|
from .base import BaseAPI
|
|
15
|
+
from .types.catalog import SalesChannel, Seller
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
class CatalogAPI(BaseAPI):
|
|
@@ -29,18 +29,30 @@ class CatalogAPI(BaseAPI):
|
|
|
29
29
|
seller_type: Union[int, UndefinedSentinel] = UNDEFINED,
|
|
30
30
|
is_better_scope: Union[bool, UndefinedSentinel] = UNDEFINED,
|
|
31
31
|
**kwargs: Any,
|
|
32
|
-
) -> VTEXItemsResponse[
|
|
32
|
+
) -> VTEXItemsResponse[List[Seller], Seller]:
|
|
33
33
|
return self._request(
|
|
34
34
|
method="GET",
|
|
35
35
|
environment=self.ENVIRONMENT,
|
|
36
36
|
endpoint="/api/catalog_system/pvt/seller/list",
|
|
37
|
-
params=
|
|
37
|
+
params=omitting_undefined({
|
|
38
38
|
"sc": sales_channel,
|
|
39
39
|
"sellerType": seller_type,
|
|
40
40
|
"isBetterScope": is_better_scope,
|
|
41
41
|
}),
|
|
42
42
|
config=self.client.config.with_overrides(**kwargs),
|
|
43
|
-
response_class=VTEXItemsResponse[
|
|
43
|
+
response_class=VTEXItemsResponse[Any, Any],
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
def list_sales_channels(
|
|
47
|
+
self,
|
|
48
|
+
**kwargs: Any,
|
|
49
|
+
) -> VTEXItemsResponse[List[SalesChannel], SalesChannel]:
|
|
50
|
+
return self._request(
|
|
51
|
+
method="GET",
|
|
52
|
+
environment=self.ENVIRONMENT,
|
|
53
|
+
endpoint="/api/catalog_system/pvt/saleschannel/list",
|
|
54
|
+
config=self.client.config.with_overrides(**kwargs),
|
|
55
|
+
response_class=VTEXItemsResponse[Any, Any],
|
|
44
56
|
)
|
|
45
57
|
|
|
46
58
|
def list_sku_ids(
|
|
@@ -68,13 +80,13 @@ class CatalogAPI(BaseAPI):
|
|
|
68
80
|
self,
|
|
69
81
|
sku_id: int,
|
|
70
82
|
**kwargs: Any,
|
|
71
|
-
) -> VTEXDataResponse[
|
|
83
|
+
) -> VTEXDataResponse[Any]:
|
|
72
84
|
return self._request(
|
|
73
85
|
method="GET",
|
|
74
86
|
environment=self.ENVIRONMENT,
|
|
75
87
|
endpoint=f"/api/catalog_system/pvt/sku/stockkeepingunitbyid/{sku_id}",
|
|
76
88
|
config=self.client.config.with_overrides(**kwargs),
|
|
77
|
-
response_class=VTEXDataResponse[
|
|
89
|
+
response_class=VTEXDataResponse[Any],
|
|
78
90
|
)
|
|
79
91
|
|
|
80
92
|
def list_categories(
|
|
@@ -82,7 +94,7 @@ class CatalogAPI(BaseAPI):
|
|
|
82
94
|
page: int = LIST_SKU_IDS_START_PAGE,
|
|
83
95
|
page_size: int = LIST_SKU_IDS_MAX_PAGE_SIZE,
|
|
84
96
|
**kwargs: Any,
|
|
85
|
-
) -> VTEXPaginatedItemsResponse[
|
|
97
|
+
) -> VTEXPaginatedItemsResponse[Any, Any]:
|
|
86
98
|
return self._request(
|
|
87
99
|
method="GET",
|
|
88
100
|
environment=self.ENVIRONMENT,
|
|
@@ -95,31 +107,31 @@ class CatalogAPI(BaseAPI):
|
|
|
95
107
|
),
|
|
96
108
|
},
|
|
97
109
|
config=self.client.config.with_overrides(**kwargs),
|
|
98
|
-
response_class=VTEXPaginatedItemsResponse[
|
|
110
|
+
response_class=VTEXPaginatedItemsResponse[Any, Any],
|
|
99
111
|
)
|
|
100
112
|
|
|
101
113
|
def get_category_tree(
|
|
102
114
|
self,
|
|
103
115
|
levels: int = GET_CATEGORY_TREE_MAX_LEVELS,
|
|
104
116
|
**kwargs: Any,
|
|
105
|
-
) -> VTEXDataResponse[
|
|
117
|
+
) -> VTEXDataResponse[Any]:
|
|
106
118
|
return self._request(
|
|
107
119
|
method="GET",
|
|
108
120
|
environment=self.ENVIRONMENT,
|
|
109
121
|
endpoint=f"/api/catalog_system/pub/category/tree/{levels}",
|
|
110
122
|
config=self.client.config.with_overrides(**kwargs),
|
|
111
|
-
response_class=VTEXDataResponse[
|
|
123
|
+
response_class=VTEXDataResponse[Any],
|
|
112
124
|
)
|
|
113
125
|
|
|
114
126
|
def get_category(
|
|
115
127
|
self,
|
|
116
|
-
category_id:
|
|
128
|
+
category_id: int,
|
|
117
129
|
**kwargs: Any,
|
|
118
|
-
) -> VTEXDataResponse[
|
|
130
|
+
) -> VTEXDataResponse[Any]:
|
|
119
131
|
return self._request(
|
|
120
132
|
method="GET",
|
|
121
133
|
environment=self.ENVIRONMENT,
|
|
122
134
|
endpoint=f"/api/catalog/pvt/category/{category_id}",
|
|
123
135
|
config=self.client.config.with_overrides(**kwargs),
|
|
124
|
-
response_class=VTEXDataResponse[
|
|
136
|
+
response_class=VTEXDataResponse[Any],
|
|
125
137
|
)
|
|
@@ -2,8 +2,7 @@ from typing import Any, List, Union
|
|
|
2
2
|
|
|
3
3
|
from .._dto import VTEXCartItem, VTEXDataResponse
|
|
4
4
|
from .._sentinels import UNDEFINED, UndefinedSentinel
|
|
5
|
-
from ..
|
|
6
|
-
from .._utils import exclude_undefined_values
|
|
5
|
+
from .._utils import omitting_undefined
|
|
7
6
|
from .base import BaseAPI
|
|
8
7
|
|
|
9
8
|
|
|
@@ -25,22 +24,22 @@ class CheckoutAPI(BaseAPI):
|
|
|
25
24
|
sales_channel: Union[int, UndefinedSentinel] = UNDEFINED,
|
|
26
25
|
individual_shipping_estimates: Union[bool, UndefinedSentinel] = UNDEFINED,
|
|
27
26
|
**kwargs: Any,
|
|
28
|
-
) -> VTEXDataResponse[
|
|
27
|
+
) -> VTEXDataResponse[Any]:
|
|
29
28
|
return self._request(
|
|
30
29
|
method="POST",
|
|
31
30
|
environment=self.ENVIRONMENT,
|
|
32
31
|
endpoint="/api/checkout/pub/orderForms/simulation",
|
|
33
|
-
params=
|
|
32
|
+
params=omitting_undefined({
|
|
34
33
|
"RnbBehavior": rnb_behavior,
|
|
35
34
|
"sc": sales_channel,
|
|
36
35
|
"individualShippingEstimates": individual_shipping_estimates,
|
|
37
36
|
}),
|
|
38
|
-
json=
|
|
37
|
+
json=omitting_undefined({
|
|
39
38
|
"items": [item.to_vtex_cart_item() for item in cart],
|
|
40
39
|
"country": country,
|
|
41
40
|
"postalCode": postal_code,
|
|
42
41
|
"geoCoordinates": geo_coordinates,
|
|
43
42
|
}),
|
|
44
43
|
config=self.client.config.with_overrides(**kwargs),
|
|
45
|
-
response_class=VTEXDataResponse[
|
|
44
|
+
response_class=VTEXDataResponse[Any],
|
|
46
45
|
)
|
|
@@ -10,10 +10,13 @@ from httpx._types import (
|
|
|
10
10
|
RequestFiles,
|
|
11
11
|
)
|
|
12
12
|
|
|
13
|
+
from .. import VTEXError
|
|
13
14
|
from .._dto import VTEXResponseType
|
|
14
15
|
from .._types import HTTPMethodType
|
|
15
16
|
from .._utils import to_datetime
|
|
16
17
|
from .base import BaseAPI
|
|
18
|
+
from .types.catalog import Seller
|
|
19
|
+
from .types.license_manager import AccountSite
|
|
17
20
|
|
|
18
21
|
|
|
19
22
|
class CustomAPI(BaseAPI):
|
|
@@ -55,31 +58,37 @@ class CustomAPI(BaseAPI):
|
|
|
55
58
|
def get_account_name(self) -> str:
|
|
56
59
|
return self.client.license_manager.get_account().data["account_name"]
|
|
57
60
|
|
|
58
|
-
def
|
|
61
|
+
def get_creation_date(self) -> datetime:
|
|
59
62
|
return to_datetime(
|
|
60
63
|
self.client.license_manager.get_account().data["creation_date"],
|
|
61
64
|
)
|
|
62
65
|
|
|
63
|
-
def
|
|
64
|
-
return
|
|
65
|
-
self.client.license_manager.get_account().data["creation_date"],
|
|
66
|
-
)
|
|
66
|
+
def list_sites(self) -> List[AccountSite]:
|
|
67
|
+
return self.client.license_manager.get_account().data["sites"]
|
|
67
68
|
|
|
68
|
-
def get_main_seller(self) ->
|
|
69
|
-
|
|
69
|
+
def get_main_seller(self) -> Seller:
|
|
70
|
+
for seller in self.client.catalog.list_sellers().items:
|
|
71
|
+
if seller["seller_type"] == 1 and seller["seller_id"] == "1":
|
|
72
|
+
return seller
|
|
70
73
|
|
|
71
|
-
|
|
74
|
+
raise VTEXError("Could not find main seller")
|
|
75
|
+
|
|
76
|
+
def list_market_place_sellers(
|
|
77
|
+
self,
|
|
78
|
+
include_inactive: bool = False,
|
|
79
|
+
include_main: bool = False,
|
|
80
|
+
) -> List[Seller]:
|
|
72
81
|
return [
|
|
73
|
-
seller
|
|
82
|
+
seller
|
|
74
83
|
for seller in self.client.catalog.list_sellers().items
|
|
75
84
|
if seller["seller_type"] == 1
|
|
76
|
-
and seller["seller_id"] != "1"
|
|
77
|
-
and (seller["is_active"]
|
|
85
|
+
and (include_main or seller["seller_id"] != "1")
|
|
86
|
+
and (include_inactive or seller["is_active"])
|
|
78
87
|
]
|
|
79
88
|
|
|
80
|
-
def
|
|
89
|
+
def list_franchise_sellers(self, include_inactive: bool = False) -> List[Seller]:
|
|
81
90
|
return [
|
|
82
|
-
seller
|
|
91
|
+
seller
|
|
83
92
|
for seller in self.client.catalog.list_sellers().items
|
|
84
|
-
if seller["seller_type"] == 2 and (seller["is_active"]
|
|
93
|
+
if seller["seller_type"] == 2 and (include_inactive or seller["is_active"])
|
|
85
94
|
]
|