vtexpy 0.0.0b9__py3-none-any.whl → 0.0.0b11__py3-none-any.whl

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.

@@ -1,6 +1,7 @@
1
1
  from typing import Any
2
2
 
3
- from .._dto import VTEXListResponse, VTEXResponse
3
+ from .._dto import VTEXDataResponse, VTEXItemsResponse
4
+ from .._types import DictType
4
5
  from .base import BaseAPI
5
6
 
6
7
 
@@ -12,39 +13,43 @@ class PaymentsGatewayAPI(BaseAPI):
12
13
 
13
14
  ENVIRONMENT = "vtexpayments"
14
15
 
15
- def get_transaction(self, transaction_id: str, **kwargs: Any) -> VTEXResponse:
16
+ def get_transaction(
17
+ self,
18
+ transaction_id: str,
19
+ **kwargs: Any,
20
+ ) -> VTEXDataResponse[DictType]:
16
21
  return self._request(
17
22
  method="GET",
18
23
  environment=self.ENVIRONMENT,
19
24
  endpoint=f"/api/pvt/transactions/{transaction_id}",
20
- config=self._config.with_overrides(**kwargs),
21
- response_class=VTEXResponse,
25
+ config=self.client.config.with_overrides(**kwargs),
26
+ response_class=VTEXDataResponse[DictType],
22
27
  )
23
28
 
24
29
  def list_transaction_interactions(
25
30
  self,
26
31
  transaction_id: str,
27
32
  **kwargs: Any,
28
- ) -> VTEXListResponse:
33
+ ) -> VTEXItemsResponse[DictType, DictType]:
29
34
  return self._request(
30
35
  method="GET",
31
36
  environment=self.ENVIRONMENT,
32
37
  endpoint=f"/api/pvt/transactions/{transaction_id}/interactions",
33
- config=self._config.with_overrides(**kwargs),
34
- response_class=VTEXListResponse,
38
+ config=self.client.config.with_overrides(**kwargs),
39
+ response_class=VTEXItemsResponse[DictType, DictType],
35
40
  )
36
41
 
37
42
  def list_transaction_payments(
38
43
  self,
39
44
  transaction_id: str,
40
45
  **kwargs: Any,
41
- ) -> VTEXListResponse:
46
+ ) -> VTEXItemsResponse[DictType, DictType]:
42
47
  return self._request(
43
48
  method="GET",
44
49
  environment=self.ENVIRONMENT,
45
50
  endpoint=f"/api/pvt/transactions/{transaction_id}/payments",
46
- config=self._config.with_overrides(**kwargs),
47
- response_class=VTEXListResponse,
51
+ config=self.client.config.with_overrides(**kwargs),
52
+ response_class=VTEXItemsResponse[DictType, DictType],
48
53
  )
49
54
 
50
55
  def get_transaction_payment(
@@ -52,63 +57,63 @@ class PaymentsGatewayAPI(BaseAPI):
52
57
  transaction_id: str,
53
58
  payment_id: str,
54
59
  **kwargs: Any,
55
- ) -> VTEXResponse:
60
+ ) -> VTEXDataResponse[DictType]:
56
61
  return self._request(
57
62
  method="GET",
58
63
  environment=self.ENVIRONMENT,
59
64
  endpoint=f"/api/pvt/transactions/{transaction_id}/payments/{payment_id}",
60
- config=self._config.with_overrides(**kwargs),
61
- response_class=VTEXResponse,
65
+ config=self.client.config.with_overrides(**kwargs),
66
+ response_class=VTEXDataResponse[DictType],
62
67
  )
63
68
 
64
69
  def get_transaction_capabilities(
65
70
  self,
66
71
  transaction_id: str,
67
72
  **kwargs: Any,
68
- ) -> VTEXResponse:
73
+ ) -> VTEXDataResponse[DictType]:
69
74
  return self._request(
70
75
  method="GET",
71
76
  environment=self.ENVIRONMENT,
72
77
  endpoint=f"/api/pvt/transactions/{transaction_id}/capabilities",
73
- config=self._config.with_overrides(**kwargs),
74
- response_class=VTEXResponse,
78
+ config=self.client.config.with_overrides(**kwargs),
79
+ response_class=VTEXDataResponse[DictType],
75
80
  )
76
81
 
77
82
  def get_transaction_cancellations(
78
83
  self,
79
84
  transaction_id: str,
80
85
  **kwargs: Any,
81
- ) -> VTEXResponse:
86
+ ) -> VTEXDataResponse[DictType]:
82
87
  return self._request(
83
88
  method="GET",
84
89
  environment=self.ENVIRONMENT,
85
90
  endpoint=f"/api/pvt/transactions/{transaction_id}/cancellations",
86
- config=self._config.with_overrides(**kwargs),
87
- response_class=VTEXResponse,
91
+ config=self.client.config.with_overrides(**kwargs),
92
+ response_class=VTEXDataResponse[DictType],
88
93
  )
89
94
 
90
95
  def get_transaction_refunds(
91
96
  self,
92
97
  transaction_id: str,
93
98
  **kwargs: Any,
94
- ) -> VTEXResponse:
99
+ ) -> VTEXDataResponse[DictType]:
95
100
  return self._request(
96
101
  method="GET",
97
102
  environment=self.ENVIRONMENT,
98
103
  endpoint=f"/api/pvt/transactions/{transaction_id}/refunds",
99
- config=self._config.with_overrides(**kwargs),
100
- response_class=VTEXResponse,
104
+ config=self.client.config.with_overrides(**kwargs),
105
+ response_class=VTEXDataResponse[DictType],
101
106
  )
102
107
 
103
108
  def get_transaction_settlements(
104
109
  self,
105
110
  transaction_id: str,
106
111
  **kwargs: Any,
107
- ) -> VTEXResponse:
112
+ ) -> VTEXDataResponse[DictType]:
108
113
  return self._request(
109
114
  method="GET",
110
115
  environment=self.ENVIRONMENT,
111
116
  endpoint=f"/api/pvt/transactions/{transaction_id}/settlements",
112
- config=self._config.with_overrides(**kwargs),
113
- response_class=VTEXResponse,
117
+ config=self.client.config.with_overrides(**kwargs),
118
+ response_class=VTEXDataResponse[DictType],
114
119
  )
@@ -1,6 +1,7 @@
1
1
  from typing import Any
2
2
 
3
- from .._dto import VTEXResponse
3
+ from .._dto import VTEXDataResponse, VTEXItemsResponse
4
+ from .._types import DictType
4
5
  from .base import BaseAPI
5
6
 
6
7
 
@@ -12,33 +13,45 @@ class PromotionsAndTaxesAPI(BaseAPI):
12
13
 
13
14
  ENVIRONMENT = "vtexcommercestable"
14
15
 
15
- def list_promotions(self, **kwargs: Any) -> VTEXResponse:
16
+ def list_archived_promotions(
17
+ self,
18
+ **kwargs: Any,
19
+ ) -> VTEXItemsResponse[DictType, DictType]:
20
+ return self._request(
21
+ method="GET",
22
+ environment=self.ENVIRONMENT,
23
+ endpoint="api/rnb/pvt/archive/benefits/calculatorconfiguration",
24
+ config=self.client.config.with_overrides(**kwargs),
25
+ response_class=VTEXItemsResponse[DictType, DictType],
26
+ )
27
+
28
+ def get_promotions(self, **kwargs: Any) -> VTEXDataResponse[DictType]:
16
29
  return self._request(
17
30
  method="GET",
18
31
  environment=self.ENVIRONMENT,
19
32
  endpoint="api/rnb/pvt/benefits/calculatorconfiguration",
20
- config=self._config.with_overrides(**kwargs),
21
- response_class=VTEXResponse,
33
+ config=self.client.config.with_overrides(**kwargs),
34
+ response_class=VTEXDataResponse[DictType],
22
35
  )
23
36
 
24
- def list_taxes(self, **kwargs: Any) -> VTEXResponse:
37
+ def get_taxes(self, **kwargs: Any) -> VTEXDataResponse[DictType]:
25
38
  return self._request(
26
39
  method="GET",
27
40
  environment=self.ENVIRONMENT,
28
41
  endpoint="api/rnb/pvt/taxes/calculatorconfiguration",
29
- config=self._config.with_overrides(**kwargs),
30
- response_class=VTEXResponse,
42
+ config=self.client.config.with_overrides(**kwargs),
43
+ response_class=VTEXDataResponse[DictType],
31
44
  )
32
45
 
33
46
  def get_promotion_or_tax(
34
47
  self,
35
48
  promotion_or_tax_id: str,
36
49
  **kwargs: Any,
37
- ) -> VTEXResponse:
50
+ ) -> VTEXDataResponse[DictType]:
38
51
  return self._request(
39
52
  method="GET",
40
53
  environment=self.ENVIRONMENT,
41
54
  endpoint=f"/api/rnb/pvt/calculatorconfiguration/{promotion_or_tax_id}",
42
- config=self._config.with_overrides(**kwargs),
43
- response_class=VTEXResponse,
55
+ config=self.client.config.with_overrides(**kwargs),
56
+ response_class=VTEXDataResponse[DictType],
44
57
  )
File without changes
@@ -0,0 +1,17 @@
1
+ from typing import TypedDict, Union
2
+
3
+
4
+ class GetAccountData(TypedDict, total=False):
5
+ account_name: str
6
+ company_name: str
7
+ creation_date: str
8
+ have_parent_account: bool
9
+ id: str
10
+ inactivation_date: Union[str, None]
11
+ is_active: bool
12
+ is_operating: bool
13
+ name: str
14
+ operation_date: Union[str, None]
15
+ parent_account_id: Union[str, None]
16
+ parent_account_name: Union[str, None]
17
+ trading_name: str
vtex/_config.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # type: ignore
2
2
  from os import getenv
3
- from typing import Union
3
+ from typing import List, Union
4
4
 
5
5
  from ._constants import (
6
6
  ACCOUNT_NAME_ENV_VAR,
@@ -24,7 +24,6 @@ from ._constants import (
24
24
  TIMEOUT_ENV_VAR,
25
25
  )
26
26
  from ._sentinels import UNDEFINED, UndefinedSentinel
27
- from ._types import IterableType
28
27
  from ._utils import is_nullish_str, str_to_bool
29
28
 
30
29
 
@@ -41,7 +40,7 @@ class Config:
41
40
  retry_backoff_exponential: Union[
42
41
  bool, float, int, UndefinedSentinel
43
42
  ] = UNDEFINED,
44
- retry_statuses: Union[IterableType[int], UndefinedSentinel] = UNDEFINED,
43
+ retry_statuses: Union[List[int], UndefinedSentinel] = UNDEFINED,
45
44
  retry_logs: Union[bool, UndefinedSentinel] = UNDEFINED,
46
45
  raise_for_status: Union[bool, UndefinedSentinel] = UNDEFINED,
47
46
  ) -> None:
@@ -74,7 +73,7 @@ class Config:
74
73
  retry_backoff_exponential: Union[
75
74
  bool, int, float, UndefinedSentinel
76
75
  ] = UNDEFINED,
77
- retry_statuses: Union[IterableType[int], UndefinedSentinel] = UNDEFINED,
76
+ retry_statuses: Union[List[int], UndefinedSentinel] = UNDEFINED,
78
77
  retry_logs: Union[bool, UndefinedSentinel] = UNDEFINED,
79
78
  raise_for_status: Union[bool, UndefinedSentinel] = UNDEFINED,
80
79
  ) -> "Config":
@@ -162,7 +161,7 @@ class Config:
162
161
 
163
162
  return self._retry_backoff_exponential
164
163
 
165
- def get_retry_statuses(self) -> IterableType[int]:
164
+ def get_retry_statuses(self) -> List[int]:
166
165
  if self._retry_statuses is UNDEFINED:
167
166
  return DEFAULT_RETRY_STATUSES
168
167
 
@@ -398,8 +397,8 @@ class Config:
398
397
 
399
398
  def _parse_retry_statuses(
400
399
  self,
401
- retry_statuses: Union[IterableType[int], UndefinedSentinel] = UNDEFINED,
402
- ) -> Union[IterableType[int], UndefinedSentinel]:
400
+ retry_statuses: Union[List[int], UndefinedSentinel] = UNDEFINED,
401
+ ) -> Union[List[int], UndefinedSentinel]:
403
402
  if isinstance(retry_statuses, (list, set, tuple)) and all(
404
403
  isinstance(status, int) and 100 <= status <= 599
405
404
  for status in retry_statuses
vtex/_dto.py CHANGED
@@ -1,14 +1,15 @@
1
1
  from dataclasses import dataclass
2
2
  from json import JSONDecodeError
3
3
  from math import ceil
4
- from typing import Dict, TypeVar, Union
4
+ from typing import Any, Dict, Generic, List, TypeVar, Union
5
5
 
6
6
  from httpx import Request, Response
7
7
 
8
- from ._types import IterableType, JSONType
9
- from ._utils import to_snake_case_deep
8
+ from ._utils import remove_null_bytes, to_snake_case_deep
10
9
 
11
- VTEXResponseType = TypeVar("VTEXResponseType", bound="VTEXResponse", covariant=True)
10
+ VTEXResponseType = TypeVar("VTEXResponseType", bound="VTEXResponse")
11
+ DataType = TypeVar("DataType", bound=Any)
12
+ ItemType = TypeVar("ItemType", bound=Any)
12
13
 
13
14
 
14
15
  @dataclass
@@ -32,34 +33,51 @@ class VTEXRequest:
32
33
  class VTEXResponse:
33
34
  request: VTEXRequest
34
35
  response: Response
35
- data: JSONType
36
36
  status: int
37
37
  headers: Dict[str, str]
38
38
 
39
39
  @classmethod
40
40
  def factory(cls, response: Response) -> "VTEXResponse":
41
- try:
42
- data = to_snake_case_deep(response.json(strict=False))
43
- except JSONDecodeError:
44
- data = response.text
45
-
46
41
  return cls(
47
42
  request=VTEXRequest.factory(response.request),
48
43
  response=response,
49
- data=data,
50
44
  status=int(response.status_code),
51
45
  headers=dict(response.headers),
52
46
  )
53
47
 
54
48
 
55
49
  @dataclass
56
- class VTEXListResponse(VTEXResponse):
57
- items: IterableType[JSONType]
50
+ class VTEXDataResponse(VTEXResponse, Generic[DataType]):
51
+ data: DataType
58
52
 
59
53
  @classmethod
60
- def factory(cls, response: Response) -> "VTEXListResponse":
54
+ def get_original_response_data(cls, response: Response) -> Any:
55
+ try:
56
+ return to_snake_case_deep(response.json(strict=False))
57
+ except JSONDecodeError:
58
+ return remove_null_bytes(response.text)
59
+
60
+ @classmethod
61
+ def factory(cls, response: Response) -> "VTEXDataResponse[DataType]":
61
62
  vtex_response = VTEXResponse.factory(response)
62
- data = vtex_response.data
63
+
64
+ return cls(
65
+ request=vtex_response.request,
66
+ response=vtex_response.response,
67
+ status=vtex_response.status,
68
+ headers=vtex_response.headers,
69
+ data=cls.get_original_response_data(response),
70
+ )
71
+
72
+
73
+ @dataclass
74
+ class VTEXItemsResponse(VTEXDataResponse[DataType], Generic[DataType, ItemType]):
75
+ items: List[ItemType]
76
+
77
+ @classmethod
78
+ def factory(cls, response: Response) -> "VTEXItemsResponse[DataType, ItemType]":
79
+ vtex_data_response = VTEXDataResponse[DataType].factory(response)
80
+ data = vtex_data_response.data
63
81
 
64
82
  if isinstance(data, list):
65
83
  items = data
@@ -70,15 +88,15 @@ class VTEXListResponse(VTEXResponse):
70
88
  elif isinstance(data, dict) and isinstance(data.get("data"), list):
71
89
  items = data["data"]
72
90
  else:
73
- raise ValueError(f"Not a valid list response: {data}")
91
+ raise ValueError(f"Not a valid items response: {data}")
74
92
 
75
93
  return cls(
76
- request=vtex_response.request,
77
- response=vtex_response.response,
78
- data=vtex_response.data,
79
- status=vtex_response.status,
80
- headers=vtex_response.headers,
81
- items=items,
94
+ request=vtex_data_response.request,
95
+ response=vtex_data_response.response,
96
+ status=vtex_data_response.status,
97
+ headers=vtex_data_response.headers,
98
+ data=vtex_data_response.data,
99
+ items=list(items),
82
100
  )
83
101
 
84
102
 
@@ -92,10 +110,13 @@ class VTEXPagination:
92
110
  next_page: Union[int, None]
93
111
 
94
112
  @classmethod
95
- def factory(cls, vtex_list_response: VTEXListResponse) -> "VTEXPagination":
96
- data = vtex_list_response.data
97
- request_headers = vtex_list_response.request.headers
98
- response_headers = vtex_list_response.headers
113
+ def factory(
114
+ cls,
115
+ vtex_items_response: VTEXItemsResponse[DataType, ItemType],
116
+ ) -> "VTEXPagination":
117
+ data = vtex_items_response.data
118
+ request_headers = vtex_items_response.request.headers
119
+ response_headers = vtex_items_response.headers
99
120
 
100
121
  total, pages, page_size, page = -1, -1, -1, -1
101
122
  if isinstance(data, dict) and data.get("paging"):
@@ -132,53 +153,25 @@ class VTEXPagination:
132
153
  next_page=page + 1 if page < pages else None,
133
154
  )
134
155
 
135
- raise ValueError(f"Not a valid paginated list response: {vtex_list_response}")
156
+ raise ValueError(f"Not a valid paginated items response: {vtex_items_response}")
136
157
 
137
158
 
138
159
  @dataclass
139
- class VTEXPaginatedListResponse(VTEXListResponse):
160
+ class VTEXPaginatedItemsResponse(VTEXItemsResponse[DataType, ItemType]):
140
161
  pagination: VTEXPagination
141
162
 
142
163
  @classmethod
143
- def factory(cls, response: Response) -> "VTEXPaginatedListResponse":
144
- vtex_list_response = VTEXListResponse.factory(response)
145
-
146
- return cls(
147
- request=vtex_list_response.request,
148
- response=vtex_list_response.response,
149
- data=vtex_list_response.data,
150
- status=vtex_list_response.status,
151
- headers=vtex_list_response.headers,
152
- items=vtex_list_response.items,
153
- pagination=VTEXPagination.factory(vtex_list_response),
154
- )
155
-
156
-
157
- @dataclass
158
- class VTEXScroll:
159
- token: Union[str, None]
160
-
161
- @classmethod
162
- def factory(cls, vtex_list_response: VTEXListResponse) -> "VTEXScroll":
163
- return cls(token=None)
164
-
165
-
166
- @dataclass
167
- class VTEXScrollListResponse(VTEXListResponse):
168
- scroll: VTEXScroll
169
-
170
- @classmethod
171
- def factory(cls, response: Response) -> "VTEXScrollListResponse":
172
- vtex_list_response = VTEXListResponse.factory(response)
164
+ def factory(cls, response: Response) -> "VTEXItemsResponse[DataType, ItemType]":
165
+ vtex_items_response = VTEXItemsResponse[DataType, ItemType].factory(response)
173
166
 
174
167
  return cls(
175
- request=vtex_list_response.request,
176
- response=vtex_list_response.response,
177
- data=vtex_list_response.data,
178
- status=vtex_list_response.status,
179
- headers=vtex_list_response.headers,
180
- items=vtex_list_response.items,
181
- scroll=VTEXScroll.factory(vtex_list_response),
168
+ request=vtex_items_response.request,
169
+ response=vtex_items_response.response,
170
+ data=vtex_items_response.data,
171
+ status=vtex_items_response.status,
172
+ headers=vtex_items_response.headers,
173
+ items=vtex_items_response.items,
174
+ pagination=VTEXPagination.factory(vtex_items_response),
182
175
  )
183
176
 
184
177
 
vtex/_exceptions.py CHANGED
@@ -2,8 +2,6 @@ from typing import Any, Dict, Union
2
2
 
3
3
  from httpx import Headers
4
4
 
5
- from ._types import JSONType
6
-
7
5
 
8
6
  class VTEXError(Exception):
9
7
  def __init__(self, *args: Any, **kwags: Any) -> None:
@@ -46,7 +44,7 @@ class VTEXResponseError(VTEXError):
46
44
  url: Union[str, None] = None,
47
45
  request_headers: Union[Headers, Dict[str, str], None] = None,
48
46
  status: Union[int, None] = None,
49
- data: JSONType = None,
47
+ data: Any = None,
50
48
  response_headers: Union[Headers, Dict[str, str], None] = None,
51
49
  **kwargs: Any,
52
50
  ) -> None:
vtex/_types.py CHANGED
@@ -1,19 +1,4 @@
1
- from typing import (
2
- List,
3
- Literal,
4
- Mapping,
5
- Set,
6
- Tuple,
7
- TypeVar,
8
- Union,
9
- )
10
-
11
- IterableValueType = TypeVar("IterableValueType")
12
- IterableType = Union[
13
- Tuple[IterableValueType, ...],
14
- Set[IterableValueType],
15
- List[IterableValueType],
16
- ]
1
+ from typing import Any, Dict, Literal
17
2
 
18
3
  OrderingDirectionType = Literal["ASC", "DESC", "asc", "desc"]
19
4
 
@@ -34,5 +19,4 @@ HTTPMethodType = Literal[
34
19
  "put",
35
20
  ]
36
21
 
37
- PrimitiveTypes = Union[None, bool, int, float, str]
38
- JSONType = Union[PrimitiveTypes, IterableType["JSONType"], Mapping[str, "JSONType"]]
22
+ DictType = Dict[str, Any]
vtex/_utils.py CHANGED
@@ -3,12 +3,13 @@ from re import compile
3
3
  from typing import Any, Dict, Mapping, Union
4
4
  from uuid import UUID
5
5
 
6
+ from dateutil.parser import parse as parse_datetime
7
+ from dateutil.tz import tzoffset
6
8
  from distutils.util import strtobool
7
9
 
8
10
  from ._constants import APP_KEY_HEADER, APP_TOKEN_HEADER
9
11
  from ._logging import UTILS_LOGGER
10
12
  from ._sentinels import UNDEFINED
11
- from ._types import JSONType
12
13
 
13
14
  TO_SNAKE_CASE_STEP_1_PATTERN = compile(r"(.)([A-Z][a-z]+)")
14
15
  TO_SNAKE_CASE_STEP_2_PATTERN = compile(r"([a-z0-9])([A-Z])")
@@ -42,7 +43,7 @@ def to_snake_case(string: str) -> str:
42
43
  return string
43
44
 
44
45
 
45
- def to_snake_case_deep(obj: JSONType) -> JSONType:
46
+ def to_snake_case_deep(obj: Any) -> Any:
46
47
  if isinstance(obj, dict):
47
48
  snake_cased_obj = {}
48
49
 
@@ -82,8 +83,34 @@ def redact_headers(headers: Mapping[str, str]) -> Dict[str, str]:
82
83
  return redacted_headers
83
84
 
84
85
 
86
+ def to_tzinfo(tz: Union[tzinfo, int, None] = None) -> tzinfo:
87
+ if isinstance(tz, tzinfo):
88
+ return tz
89
+
90
+ if isinstance(tz, int):
91
+ return tzoffset(None, tz)
92
+
93
+ return timezone.utc
94
+
95
+
96
+ def to_datetime(
97
+ value: Union[datetime, str],
98
+ use_tz: bool = True,
99
+ tz: Union[tzinfo, int, None] = None,
100
+ ) -> datetime:
101
+ value_as_datetime = value if isinstance(value, datetime) else parse_datetime(value)
102
+
103
+ if not use_tz:
104
+ return value_as_datetime.replace(tzinfo=None)
105
+
106
+ if value_as_datetime.tzinfo and tz is None:
107
+ return value_as_datetime
108
+
109
+ return value_as_datetime.replace(tzinfo=to_tzinfo(tz))
110
+
111
+
85
112
  def now(use_tz: bool = True, tz: Union[tzinfo, None] = None) -> datetime:
86
- return datetime.now((tz or timezone.utc) if use_tz else None)
113
+ return datetime.now(to_tzinfo(tz) if use_tz else None)
87
114
 
88
115
 
89
116
  def three_years_ago(use_tz: bool = True, tz: Union[tzinfo, None] = None) -> datetime: