vtexpy 0.0.0b16__tar.gz → 0.0.0b18__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.

Files changed (33) hide show
  1. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/PKG-INFO +31 -26
  2. vtexpy-0.0.0b18/README.md +64 -0
  3. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/pyproject.toml +14 -9
  4. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/__init__.py +2 -0
  5. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_api/base.py +62 -39
  6. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_api/catalog.py +26 -14
  7. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_api/checkout.py +5 -6
  8. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_api/custom.py +23 -14
  9. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_api/license_manager.py +1 -1
  10. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_api/logistics.py +14 -15
  11. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_api/master_data.py +5 -5
  12. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_api/orders.py +9 -9
  13. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_api/payments_gateway.py +16 -17
  14. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_api/promotions_and_taxes.py +8 -9
  15. vtexpy-0.0.0b18/vtex/_api/types/catalog.py +21 -0
  16. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_api/types/generic.py +4 -4
  17. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_api/types/license_manager.py +13 -7
  18. vtexpy-0.0.0b18/vtex/_config.py +338 -0
  19. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_constants.py +18 -6
  20. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_dto.py +22 -17
  21. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_logging.py +28 -6
  22. vtexpy-0.0.0b18/vtex/_types.py +37 -0
  23. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_utils.py +16 -20
  24. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_vtex.py +4 -30
  25. vtexpy-0.0.0b16/README.md +0 -60
  26. vtexpy-0.0.0b16/vtex/_config.py +0 -478
  27. vtexpy-0.0.0b16/vtex/_types.py +0 -22
  28. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/LICENSE +0 -0
  29. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_api/__init__.py +0 -0
  30. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_api/types/__init__.py +0 -0
  31. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_exceptions.py +0 -0
  32. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/_sentinels.py +0 -0
  33. {vtexpy-0.0.0b16 → vtexpy-0.0.0b18}/vtex/py.typed +0 -0
@@ -1,19 +1,19 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vtexpy
3
- Version: 0.0.0b16
4
- Summary: Unofficial Python SDK for VTEX API
3
+ Version: 0.0.0b18
4
+ Summary: Unofficial VTEX API's Python SDK
5
5
  Home-page: https://github.com/lvieirajr/vtex-python
6
- License: MIT
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.14
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 :: OSI Approved :: MIT 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,29 +36,28 @@ Description-Content-Type: text/markdown
35
36
  # VTEXPY
36
37
  [![PyPI Version](https://img.shields.io/pypi/v/vtexpy.svg)](https://pypi.python.org/pypi/vtexpy)
37
38
 
38
- ## Unofficial Python SDK for VTEX API
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
 
42
43
  Even though it is still tagged as beta, vtexpy has been in use by a _SaaS_ company in a
43
44
  production environment for over a year, making millions of requests a day to the VTEX
44
- API.
45
+ API. The only reason why it is tagged as beta is that it is still under heavy
46
+ development and breaking changes are expected on the external API.
45
47
 
46
48
  ### Features
47
49
 
48
- - Easy to use Python interface for calling endpoints on the VTEX API.
50
+ - Easy to use Python interface for calling VTEX API endpoints
51
+ - Response format standardization
49
52
  - Custom exception handling
50
- - Automatic retries
53
+ - Automatic request retrying
51
54
  - Request logging
52
55
 
53
56
  ### Getting Started
54
57
 
55
58
  #### Requirements
56
59
 
57
- - Python >= 3.9, < 3.14
58
- - httpx >= 0.26, < 1.0
59
- - python-dateutil >= 2.9, < 3.0
60
- - tenacity >= 8.3, < 10.0
60
+ - Python >= 3.9, < 3.13
61
61
 
62
62
  #### Installation
63
63
 
@@ -67,29 +67,34 @@ pip install vtexpy
67
67
 
68
68
  #### Usage
69
69
 
70
- If the API you want to call is not yet implemented, feel free to create an issue on the
70
+ If the API you want to call is not yet implemented, feel free to create an issue on the
71
71
  VTEXPY Github repository and request it to be added.
72
72
 
73
73
  ```python
74
- from vtex import VTEX
74
+ from vtex import VTEX, VTEXConfig
75
75
 
76
- # 1 - Instantiate the VTEX client for the account you want to access:
77
- vtex_client = VTEX(
78
- account_name="<ACCOUNT_NAME>",
79
- app_key="<APP_KEY>",
76
+ # Instantiate your VTEX API configuration:
77
+ vtex_config = VTEXConfig(
78
+ account_name="<ACCOUNT_NAME>",
79
+ app_key="<APP_KEY>",
80
80
  app_token="<APP_TOKEN>",
81
+ # Other arguments such as: retrying, logging, etc...
81
82
  )
82
83
 
83
- # 2 - Call one of the available APIs, e.g.:
84
- vtex_client.license_manager.get_account()
85
- vtex_client.catalog.list_sku_ids(page=1, page_size=1000)
86
- vtex_client.orders.list_orders(page=1, page_size=100)
84
+ # Instantiate the VTEX client with your configuration:
85
+ vtex_client = VTEX(config=vtex_config)
87
86
 
88
- # 3 - If the API you want to call is not yet implemented you can use the `custom` API.
89
- vtex_client.custom.request(
87
+ # Call one of the available APIs, e.g.:
88
+ account_response = vtex_client.license_manager.get_account()
89
+ list_sku_ids_response = vtex_client.catalog.list_sku_ids(page=1, page_size=1000)
90
+ list_orders_response = vtex_client.orders.list_orders(page=1, page_size=100)
91
+
92
+ # If the API you want to call is not yet implemented you can use the `custom` API.
93
+ response = vtex_client.custom.request(
90
94
  method="GET",
91
95
  environment="vtexcommercestable",
92
96
  endpoint="/api/catalog_system/pvt/commercialcondition/list",
97
+ # Other arguments such as: query params, headers, json data, response class, etc...
93
98
  )
94
99
  ```
95
100
 
@@ -0,0 +1,64 @@
1
+ # VTEXPY
2
+ [![PyPI Version](https://img.shields.io/pypi/v/vtexpy.svg)](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. The only reason why it is tagged as beta is that it is still under heavy
11
+ development and breaking changes are expected on the external API.
12
+
13
+ ### Features
14
+
15
+ - Easy to use Python interface for calling VTEX API endpoints
16
+ - Response format standardization
17
+ - Custom exception handling
18
+ - Automatic request retrying
19
+ - Request logging
20
+
21
+ ### Getting Started
22
+
23
+ #### Requirements
24
+
25
+ - Python >= 3.9, < 3.13
26
+
27
+ #### Installation
28
+
29
+ ```bash
30
+ pip install vtexpy
31
+ ```
32
+
33
+ #### Usage
34
+
35
+ If the API you want to call is not yet implemented, feel free to create an issue on the
36
+ VTEXPY Github repository and request it to be added.
37
+
38
+ ```python
39
+ from vtex import VTEX, VTEXConfig
40
+
41
+ # Instantiate your VTEX API configuration:
42
+ vtex_config = VTEXConfig(
43
+ account_name="<ACCOUNT_NAME>",
44
+ app_key="<APP_KEY>",
45
+ app_token="<APP_TOKEN>",
46
+ # Other arguments such as: retrying, logging, etc...
47
+ )
48
+
49
+ # Instantiate the VTEX client with your configuration:
50
+ vtex_client = VTEX(config=vtex_config)
51
+
52
+ # Call one of the available APIs, e.g.:
53
+ account_response = vtex_client.license_manager.get_account()
54
+ list_sku_ids_response = vtex_client.catalog.list_sku_ids(page=1, page_size=1000)
55
+ list_orders_response = vtex_client.orders.list_orders(page=1, page_size=100)
56
+
57
+ # If the API you want to call is not yet implemented you can use the `custom` API.
58
+ response = vtex_client.custom.request(
59
+ method="GET",
60
+ environment="vtexcommercestable",
61
+ endpoint="/api/catalog_system/pvt/commercialcondition/list",
62
+ # Other arguments such as: query params, headers, json data, response class, etc...
63
+ )
64
+ ```
@@ -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 for VTEX API"
7
+ description = "Unofficial VTEX API's Python SDK"
8
+ version = "0.0.0b18"
4
9
  readme = "README.md"
5
- license = "MIT"
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.14"
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 = "*"}
@@ -79,9 +81,12 @@ mock_use_standalone_module = true
79
81
  [tool.mypy]
80
82
  exclude = [".*tests/*"]
81
83
  ignore_missing_imports = true
84
+ install_types = true
82
85
  namespace_packages = true
83
86
  no_implicit_reexport = false
87
+ non_interactive = true
84
88
  plugins = []
89
+ pretty = true
85
90
  strict = true
86
91
 
87
92
 
@@ -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 Config # type: ignore[attr-defined]
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[Config, None] = None,
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.get_account_name()}.{environment}.com.br",
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.get_app_key()
75
- headers[APP_TOKEN_HEADER] = request_config.get_app_token()
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.get_retry_attempts() + 1,
81
+ max_attempt_number=request_config.retry_attempts + 1,
82
82
  ),
83
83
  wait=wait_exponential(
84
- min=request_config.get_retry_backoff_min(),
85
- max=request_config.get_retry_backoff_max(),
86
- exp_base=request_config.get_retry_backoff_exponential(),
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=HTTPError),
88
+ retry=retry_if_exception_type(exception_types=HTTPStatusError),
89
89
  before_sleep=(
90
- log_before_retry(logger=self.logger, log_level=WARNING)
91
- if request_config.get_retry_logs()
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.get_timeout()) as client:
98
- response = client.request(
99
- method.upper(),
100
- url,
101
- headers=headers,
102
- cookies=cookies,
103
- params=params,
104
- json=json,
105
- data=data,
106
- content=content,
107
- files=files,
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
- if response.status_code in request_config.get_retry_statuses():
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: Config) -> None:
145
- if response.is_error and config.get_raise_for_status():
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
- error = VTEXResponseError(
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 .._types import DictType
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[DictType, DictType]:
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=exclude_undefined_values({
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[DictType, DictType],
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[DictType]:
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[DictType],
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[DictType, DictType]:
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[DictType, DictType],
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[DictType]:
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[DictType],
123
+ response_class=VTEXDataResponse[Any],
112
124
  )
113
125
 
114
126
  def get_category(
115
127
  self,
116
- category_id: str,
128
+ category_id: int,
117
129
  **kwargs: Any,
118
- ) -> VTEXDataResponse[DictType]:
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[DictType],
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 .._types import DictType
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[DictType]:
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=exclude_undefined_values({
32
+ params=omitting_undefined({
34
33
  "RnbBehavior": rnb_behavior,
35
34
  "sc": sales_channel,
36
35
  "individualShippingEstimates": individual_shipping_estimates,
37
36
  }),
38
- json=exclude_undefined_values({
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[DictType],
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 get_account_creation_date(self) -> datetime:
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 get_account_site_names(self) -> datetime:
64
- return to_datetime(
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) -> str:
69
- return "1"
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
- def get_market_place_sellers(self, include_inactive: bool = False) -> List[str]:
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["seller_id"]
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"] or include_inactive)
85
+ and (include_main or seller["seller_id"] != "1")
86
+ and (include_inactive or seller["is_active"])
78
87
  ]
79
88
 
80
- def get_franchise_sellers(self, include_inactive: bool = False) -> List[str]:
89
+ def list_franchise_sellers(self, include_inactive: bool = False) -> List[Seller]:
81
90
  return [
82
- seller["seller_id"]
91
+ seller
83
92
  for seller in self.client.catalog.list_sellers().items
84
- if seller["seller_type"] == 2 and (seller["is_active"] or include_inactive)
93
+ if seller["seller_type"] == 2 and (include_inactive or seller["is_active"])
85
94
  ]
@@ -38,7 +38,7 @@ class LicenseManagerAPI(BaseAPI):
38
38
  for app_key in self.get_account().data["app_keys"]
39
39
  }
40
40
 
41
- user_id = app_keys[config.get_app_key()]["id"]
41
+ user_id = app_keys[config.app_key.get_secret_value()]["id"]
42
42
 
43
43
  return self._request(
44
44
  method="GET",