vtexpy 0.0.0b16__py3-none-any.whl → 0.0.0b17__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.

vtex/_config.py CHANGED
@@ -1,478 +1,338 @@
1
- # type: ignore
1
+ from logging import CRITICAL, DEBUG, ERROR, INFO, WARNING
2
2
  from os import getenv
3
- from typing import List, Union
3
+ from typing import Any, List, Literal, Union
4
+
5
+ from pydantic import BaseModel, Field, SecretStr, field_validator
4
6
 
5
7
  from ._constants import (
6
8
  ACCOUNT_NAME_ENV_VAR,
7
9
  APP_KEY_ENV_VAR,
8
10
  APP_TOKEN_ENV_VAR,
11
+ DEFAULT_LOG_1XX,
12
+ DEFAULT_LOG_2XX,
13
+ DEFAULT_LOG_3XX,
14
+ DEFAULT_LOG_4XX,
15
+ DEFAULT_LOG_5XX,
16
+ DEFAULT_LOG_RETRIES,
9
17
  DEFAULT_RAISE_FOR_STATUS,
10
18
  DEFAULT_RETRY_ATTEMPTS,
11
- DEFAULT_RETRY_BACKOFF_EXPONENTIAL,
12
19
  DEFAULT_RETRY_BACKOFF_MAX,
13
20
  DEFAULT_RETRY_BACKOFF_MIN,
14
- DEFAULT_RETRY_LOGS,
15
21
  DEFAULT_RETRY_STATUSES,
16
22
  DEFAULT_TIMEOUT,
23
+ LOG_1XX_ENV_VAR,
24
+ LOG_2XX_ENV_VAR,
25
+ LOG_3XX_ENV_VAR,
26
+ LOG_4XX_ENV_VAR,
27
+ LOG_5XX_ENV_VAR,
28
+ LOG_RETRIES_ENV_VAR,
17
29
  RAISE_FOR_STATUS_ENV_VAR,
18
30
  RETRY_ATTEMPTS_ENV_VAR,
19
- RETRY_BACKOFF_EXPONENTIAL_ENV_VAR,
20
31
  RETRY_BACKOFF_MAX_ENV_VAR,
21
32
  RETRY_BACKOFF_MIN_ENV_VAR,
22
- RETRY_LOGS_ENV_VAR,
23
33
  RETRY_STATUSES_ENV_VAR,
24
34
  TIMEOUT_ENV_VAR,
25
35
  )
26
36
  from ._sentinels import UNDEFINED, UndefinedSentinel
27
- from ._utils import is_nullish_str, str_to_bool
37
+ from ._types import LogLevelType
38
+ from ._utils import omitting_undefined, str_to_bool
28
39
 
40
+ FalseOrLogLevel = Union[Literal[False], LogLevelType]
41
+ FalseOrLogLevelOrUndefined = Union[FalseOrLogLevel, UndefinedSentinel]
29
42
 
30
- class Config:
31
- def __init__(
32
- self,
33
- account_name: Union[str, UndefinedSentinel] = UNDEFINED,
34
- app_key: Union[str, UndefinedSentinel] = UNDEFINED,
35
- app_token: Union[str, UndefinedSentinel] = UNDEFINED,
36
- timeout: Union[float, int, None, UndefinedSentinel] = UNDEFINED,
37
- retry_attempts: Union[int, UndefinedSentinel] = UNDEFINED,
38
- retry_backoff_min: Union[float, int, UndefinedSentinel] = UNDEFINED,
39
- retry_backoff_max: Union[float, int, UndefinedSentinel] = UNDEFINED,
40
- retry_backoff_exponential: Union[
41
- bool, float, int, UndefinedSentinel
42
- ] = UNDEFINED,
43
- retry_statuses: Union[List[int], UndefinedSentinel] = UNDEFINED,
44
- retry_logs: Union[bool, UndefinedSentinel] = UNDEFINED,
45
- raise_for_status: Union[bool, UndefinedSentinel] = UNDEFINED,
46
- ) -> None:
47
- self._account_name = self._parse_account_name(account_name)
48
- self._app_key = self._parse_app_key(app_key)
49
- self._app_token = self._parse_app_token(app_token)
50
- self._timeout = self._parse_timeout(timeout)
51
- self._retry_attempts = self._parse_retry_attempts(retry_attempts)
52
- self._retry_backoff_min = self._parse_retry_backoff_min(retry_backoff_min)
53
- self._retry_backoff_max = self._parse_retry_backoff_max(retry_backoff_max)
54
- self._retry_backoff_exponential = self._parse_retry_backoff_exponential(
55
- retry_backoff_exponential,
56
- )
57
- self._retry_statuses = self._parse_retry_statuses(retry_statuses)
58
- self._retry_logs = self._parse_retry_logs(retry_logs)
59
- self._raise_for_status = self._parse_raise_for_status(raise_for_status)
60
43
 
61
- if self.get_retry_backoff_min() > self.get_retry_backoff_max():
62
- raise ValueError("Minimum backoff has to be lower than maximum backoff")
44
+ class VTEXConfig(BaseModel):
45
+ account_name: str = Field(UNDEFINED, validate_default=True)
46
+ app_key: SecretStr = Field(UNDEFINED, validate_default=True)
47
+ app_token: SecretStr = Field(UNDEFINED, validate_default=True)
48
+
49
+ timeout: Union[float, None] = Field(UNDEFINED, validate_default=True)
50
+
51
+ retry_attempts: int = Field(UNDEFINED, validate_default=True)
52
+ retry_backoff_min: float = Field(UNDEFINED, validate_default=True)
53
+ retry_backoff_max: float = Field(UNDEFINED, validate_default=True)
54
+ retry_statuses: List[int] = Field(UNDEFINED, validate_default=True)
55
+
56
+ raise_for_status: bool = Field(UNDEFINED, validate_default=True)
57
+
58
+ log_retries: FalseOrLogLevel = Field(UNDEFINED, validate_default=True)
59
+ log_1xx: FalseOrLogLevel = Field(UNDEFINED, validate_default=True)
60
+ log_2xx: FalseOrLogLevel = Field(UNDEFINED, validate_default=True)
61
+ log_3xx: FalseOrLogLevel = Field(UNDEFINED, validate_default=True)
62
+ log_4xx: FalseOrLogLevel = Field(UNDEFINED, validate_default=True)
63
+ log_5xx: FalseOrLogLevel = Field(UNDEFINED, validate_default=True)
63
64
 
64
65
  def with_overrides(
65
66
  self,
66
67
  account_name: Union[str, UndefinedSentinel] = UNDEFINED,
67
- app_key: Union[str, UndefinedSentinel] = UNDEFINED,
68
- app_token: Union[str, UndefinedSentinel] = UNDEFINED,
68
+ app_key: Union[SecretStr, str, UndefinedSentinel] = UNDEFINED,
69
+ app_token: Union[SecretStr, str, UndefinedSentinel] = UNDEFINED,
69
70
  timeout: Union[float, int, None, UndefinedSentinel] = UNDEFINED,
70
71
  retry_attempts: Union[int, UndefinedSentinel] = UNDEFINED,
71
72
  retry_backoff_min: Union[float, int, UndefinedSentinel] = UNDEFINED,
72
73
  retry_backoff_max: Union[float, int, UndefinedSentinel] = UNDEFINED,
73
- retry_backoff_exponential: Union[
74
- bool,
75
- int,
76
- float,
77
- UndefinedSentinel,
78
- ] = UNDEFINED,
79
74
  retry_statuses: Union[List[int], UndefinedSentinel] = UNDEFINED,
80
- retry_logs: Union[bool, UndefinedSentinel] = UNDEFINED,
81
75
  raise_for_status: Union[bool, UndefinedSentinel] = UNDEFINED,
82
- ) -> "Config":
83
- return Config(
84
- account_name=(
85
- self._account_name if account_name is UNDEFINED else account_name
86
- ),
87
- app_key=self._app_key if app_key is UNDEFINED else app_key,
88
- app_token=self._app_token if app_token is UNDEFINED else app_token,
89
- timeout=self._timeout if timeout is UNDEFINED else timeout,
90
- retry_attempts=(
91
- self._retry_attempts if retry_attempts is UNDEFINED else retry_attempts
92
- ),
93
- retry_backoff_min=(
94
- self._retry_backoff_min
95
- if retry_backoff_min is UNDEFINED
96
- else retry_backoff_min
97
- ),
98
- retry_backoff_max=(
99
- self._retry_backoff_max
100
- if retry_backoff_max is UNDEFINED
101
- else retry_backoff_max
102
- ),
103
- retry_backoff_exponential=(
104
- self._retry_backoff_exponential
105
- if retry_backoff_exponential is UNDEFINED
106
- else retry_backoff_exponential
107
- ),
108
- retry_statuses=(
109
- self._retry_statuses if retry_statuses is UNDEFINED else retry_statuses
110
- ),
111
- retry_logs=(self._retry_logs if retry_logs is UNDEFINED else retry_logs),
112
- raise_for_status=(
113
- self._raise_for_status
114
- if raise_for_status is UNDEFINED
115
- else raise_for_status
116
- ),
76
+ log_retries: FalseOrLogLevelOrUndefined = UNDEFINED,
77
+ log_1xx: FalseOrLogLevelOrUndefined = UNDEFINED,
78
+ log_2xx: FalseOrLogLevelOrUndefined = UNDEFINED,
79
+ log_3xx: FalseOrLogLevelOrUndefined = UNDEFINED,
80
+ log_4xx: FalseOrLogLevelOrUndefined = UNDEFINED,
81
+ log_5xx: FalseOrLogLevelOrUndefined = UNDEFINED,
82
+ ) -> "VTEXConfig":
83
+ return VTEXConfig(
84
+ **{
85
+ **self.model_dump(),
86
+ **omitting_undefined({
87
+ "account_name": account_name,
88
+ "app_key": app_key,
89
+ "app_token": app_token,
90
+ "timeout": timeout,
91
+ "retry_attempts": retry_attempts,
92
+ "retry_backoff_min": retry_backoff_min,
93
+ "retry_backoff_max": retry_backoff_max,
94
+ "retry_statuses": retry_statuses,
95
+ "raise_for_status": raise_for_status,
96
+ "log_retries": log_retries,
97
+ "log_1xx": log_1xx,
98
+ "log_2xx": log_2xx,
99
+ "log_3xx": log_3xx,
100
+ "log_4xx": log_4xx,
101
+ "log_5xx": log_5xx,
102
+ }),
103
+ },
117
104
  )
118
105
 
119
- def get_account_name(self) -> str:
120
- if self._account_name is UNDEFINED:
121
- raise ValueError("Missing VTEX Account Name")
122
-
123
- return self._account_name
124
-
125
- def get_app_key(self) -> str:
126
- if self._app_key is UNDEFINED:
127
- raise ValueError("Missing VTEX APP Key")
128
-
129
- return self._app_key
130
-
131
- def get_app_token(self) -> str:
132
- if self._app_token is UNDEFINED:
133
- raise ValueError("Missing VTEX APP Token")
134
-
135
- return self._app_token
136
-
137
- def get_timeout(self) -> Union[float, None]:
138
- if self._timeout is UNDEFINED:
139
- return DEFAULT_TIMEOUT
140
-
141
- return self._timeout
142
-
143
- def get_retry_attempts(self) -> int:
144
- if self._retry_attempts is UNDEFINED:
145
- return DEFAULT_RETRY_ATTEMPTS
146
-
147
- return self._retry_attempts
148
-
149
- def get_retry_backoff_min(self) -> float:
150
- if self._retry_backoff_min is UNDEFINED:
151
- return DEFAULT_RETRY_BACKOFF_MIN
152
-
153
- return self._retry_backoff_min
154
-
155
- def get_retry_backoff_max(self) -> float:
156
- if self._retry_backoff_max is UNDEFINED:
157
- return DEFAULT_RETRY_BACKOFF_MAX
158
-
159
- return self._retry_backoff_max
160
-
161
- def get_retry_backoff_exponential(self) -> float:
162
- if self._retry_backoff_exponential is UNDEFINED:
163
- return DEFAULT_RETRY_BACKOFF_EXPONENTIAL
164
-
165
- return self._retry_backoff_exponential
166
-
167
- def get_retry_statuses(self) -> List[int]:
168
- if self._retry_statuses is UNDEFINED:
169
- return DEFAULT_RETRY_STATUSES
170
-
171
- return self._retry_statuses
172
-
173
- def get_retry_logs(self) -> bool:
174
- if self._retry_logs is UNDEFINED:
175
- return DEFAULT_RETRY_LOGS
176
-
177
- return self._retry_logs
178
-
179
- def get_raise_for_status(self) -> bool:
180
- if self._raise_for_status is UNDEFINED:
181
- return DEFAULT_RAISE_FOR_STATUS
182
-
183
- return self._raise_for_status
184
-
185
- def _parse_account_name(
186
- self,
187
- account_name: Union[str, UndefinedSentinel] = UNDEFINED,
188
- ) -> Union[str, UndefinedSentinel]:
189
- if isinstance(account_name, str) and account_name:
190
- return account_name
191
-
192
- if account_name is UNDEFINED:
193
- env_account_name = getenv(ACCOUNT_NAME_ENV_VAR, UNDEFINED)
194
-
195
- if env_account_name is UNDEFINED or env_account_name:
196
- return env_account_name
197
-
198
- raise ValueError(
199
- f"Invalid value for {ACCOUNT_NAME_ENV_VAR}: {env_account_name}",
200
- )
201
-
202
- raise ValueError(f"Invalid value for account_name: {account_name}")
203
-
204
- def _parse_app_key(
205
- self,
206
- app_key: Union[str, UndefinedSentinel] = UNDEFINED,
207
- ) -> Union[str, UndefinedSentinel]:
208
- if isinstance(app_key, str) and app_key:
209
- return app_key
210
-
211
- if app_key is UNDEFINED:
212
- env_app_key = getenv(APP_KEY_ENV_VAR, UNDEFINED)
213
-
214
- if env_app_key is UNDEFINED or env_app_key:
215
- return env_app_key
216
-
217
- raise ValueError(f"Invalid value for {APP_KEY_ENV_VAR}: {env_app_key}")
218
-
219
- raise ValueError(f"Invalid value for app_key: {app_key}")
220
-
221
- def _parse_app_token(
222
- self,
223
- app_token: Union[str, UndefinedSentinel] = UNDEFINED,
224
- ) -> Union[str, UndefinedSentinel]:
225
- if isinstance(app_token, str) and app_token:
226
- return app_token
227
-
228
- if app_token is UNDEFINED:
229
- env_app_token = getenv(APP_TOKEN_ENV_VAR, UNDEFINED)
230
-
231
- if env_app_token is UNDEFINED or env_app_token:
232
- return env_app_token
233
-
234
- raise ValueError(f"Invalid value for {APP_TOKEN_ENV_VAR}: {env_app_token}")
106
+ @field_validator("account_name", mode="before")
107
+ @classmethod
108
+ def validate_account_name(cls, value: Any) -> str:
109
+ return cls._validate_required_string(value, ACCOUNT_NAME_ENV_VAR)
235
110
 
236
- raise ValueError(f"Invalid value for app_token: {app_token}")
111
+ @field_validator("app_key", mode="before")
112
+ @classmethod
113
+ def validate_app_key(cls, value: Any) -> str:
114
+ return cls._validate_required_string(value, APP_KEY_ENV_VAR)
237
115
 
238
- def _parse_timeout(
239
- self,
240
- timeout: Union[float, int, None, UndefinedSentinel] = UNDEFINED,
241
- ) -> Union[float, None, UndefinedSentinel]:
242
- if isinstance(timeout, (float, int)) and timeout > 0:
243
- return float(timeout)
244
-
245
- if timeout is None:
246
- return timeout
247
-
248
- if timeout is UNDEFINED:
249
- env_timeout = getenv(TIMEOUT_ENV_VAR, UNDEFINED)
116
+ @field_validator("app_token", mode="before")
117
+ @classmethod
118
+ def validate_app_token(cls, value: Any) -> str:
119
+ return cls._validate_required_string(value, APP_TOKEN_ENV_VAR)
250
120
 
251
- if env_timeout is UNDEFINED:
252
- return env_timeout
253
-
254
- if is_nullish_str(env_timeout):
255
- return None
121
+ @field_validator("timeout", mode="before")
122
+ @classmethod
123
+ def validate_timeout(cls, value: Any) -> Union[float, None]:
124
+ if isinstance(value, UndefinedSentinel):
125
+ value = getenv(TIMEOUT_ENV_VAR, DEFAULT_TIMEOUT)
256
126
 
127
+ if isinstance(value, (str, float, int)):
257
128
  try:
258
- converted_value = float(env_timeout)
259
-
260
- if converted_value > 0:
261
- return converted_value
129
+ value = float(value)
262
130
  except ValueError:
263
131
  pass
264
132
 
265
- raise ValueError(f"Invalid value for {TIMEOUT_ENV_VAR}: {env_timeout}")
266
-
267
- raise ValueError(f"Invalid value for timeout: {timeout}")
133
+ if isinstance(value, str) and value.lower() in {"", "none", "null"}:
134
+ value = None
268
135
 
269
- def _parse_retry_attempts(
270
- self,
271
- retry_attempts: Union[int, UndefinedSentinel] = UNDEFINED,
272
- ) -> Union[int, UndefinedSentinel]:
273
- if isinstance(retry_attempts, int) and retry_attempts >= 0:
274
- return retry_attempts
136
+ if value is None or (isinstance(value, (float, int)) and value > 0):
137
+ return value
275
138
 
276
- if retry_attempts is UNDEFINED:
277
- env_retry_attempts = getenv(RETRY_ATTEMPTS_ENV_VAR, UNDEFINED)
139
+ raise cls._prepare_value_error(value, TIMEOUT_ENV_VAR)
278
140
 
279
- if env_retry_attempts is UNDEFINED:
280
- return env_retry_attempts
141
+ @field_validator("retry_attempts", mode="before")
142
+ @classmethod
143
+ def validate_retry_attempts(cls, value: Any) -> int:
144
+ if isinstance(value, UndefinedSentinel):
145
+ value = getenv(RETRY_ATTEMPTS_ENV_VAR, DEFAULT_RETRY_ATTEMPTS)
281
146
 
147
+ if isinstance(value, (str, int)):
282
148
  try:
283
- converted_value = int(env_retry_attempts)
284
-
285
- if converted_value >= 0:
286
- return converted_value
149
+ value = int(value)
287
150
  except ValueError:
288
151
  pass
289
152
 
290
- raise ValueError(
291
- f"Invalid value for {RETRY_ATTEMPTS_ENV_VAR}: {env_retry_attempts}",
292
- )
293
-
294
- raise ValueError(f"Invalid value for retry_attempts: {retry_attempts}")
295
-
296
- def _parse_retry_backoff_min(
297
- self,
298
- retry_backoff_min: Union[float, int, UndefinedSentinel] = UNDEFINED,
299
- ) -> Union[float, UndefinedSentinel]:
300
- if isinstance(retry_backoff_min, (float, int)) and retry_backoff_min > 0:
301
- return float(retry_backoff_min)
153
+ if isinstance(value, int) and value >= 0:
154
+ return value
302
155
 
303
- if retry_backoff_min is UNDEFINED:
304
- env_retry_backoff_min = getenv(RETRY_BACKOFF_MIN_ENV_VAR, UNDEFINED)
156
+ raise cls._prepare_value_error(value, RETRY_ATTEMPTS_ENV_VAR)
305
157
 
306
- if env_retry_backoff_min is UNDEFINED:
307
- return env_retry_backoff_min
308
-
309
- try:
310
- converted_value = float(env_retry_backoff_min)
311
-
312
- if converted_value > 0:
313
- return converted_value
314
- except ValueError:
315
- pass
316
-
317
- raise ValueError(
318
- f"Invalid value for {RETRY_BACKOFF_MIN_ENV_VAR}: "
319
- f"{env_retry_backoff_min}",
320
- )
158
+ @field_validator("retry_backoff_min", mode="before")
159
+ @classmethod
160
+ def validate_retry_backoff_min(cls, value: Any) -> Union[float, int]:
161
+ return cls._validate_number(
162
+ value,
163
+ RETRY_BACKOFF_MIN_ENV_VAR,
164
+ DEFAULT_RETRY_BACKOFF_MIN,
165
+ allow_zero=False,
166
+ )
321
167
 
322
- raise ValueError(f"Invalid value for retry_backoff_min: {retry_backoff_min}")
168
+ @field_validator("retry_backoff_max", mode="before")
169
+ @classmethod
170
+ def validate_retry_backoff_max(cls, value: Any) -> Union[float, int]:
171
+ return cls._validate_number(
172
+ value,
173
+ RETRY_BACKOFF_MAX_ENV_VAR,
174
+ DEFAULT_RETRY_BACKOFF_MAX,
175
+ allow_zero=False,
176
+ )
323
177
 
324
- def _parse_retry_backoff_max(
325
- self,
326
- retry_backoff_max: Union[float, UndefinedSentinel] = UNDEFINED,
327
- ) -> Union[float, UndefinedSentinel]:
328
- if isinstance(retry_backoff_max, (float, int)) and retry_backoff_max > 0:
329
- return float(retry_backoff_max)
178
+ @field_validator("retry_statuses", mode="before")
179
+ @classmethod
180
+ def validate_retry_statuses(cls, value: Any) -> List[int]:
181
+ if isinstance(value, UndefinedSentinel):
182
+ value = getenv(RETRY_STATUSES_ENV_VAR, DEFAULT_RETRY_STATUSES)
183
+
184
+ if isinstance(value, str):
185
+ if value == "":
186
+ value = []
187
+ elif value == "*":
188
+ value = list(range(100, 600))
189
+ else:
190
+ statuses = value.split(",")
191
+
192
+ try:
193
+ value = [int(status.strip()) for status in statuses]
194
+ except ValueError:
195
+ pass
196
+
197
+ if isinstance(value, (list, set, tuple)) and all(
198
+ isinstance(status, int) and 100 <= status <= 599 for status in value
199
+ ):
200
+ return list(value)
330
201
 
331
- if retry_backoff_max is UNDEFINED:
332
- env_retry_backoff_max = getenv(RETRY_BACKOFF_MAX_ENV_VAR, UNDEFINED)
202
+ raise cls._prepare_value_error(value, RETRY_STATUSES_ENV_VAR)
333
203
 
334
- if env_retry_backoff_max is UNDEFINED:
335
- return env_retry_backoff_max
204
+ @field_validator("raise_for_status", mode="before")
205
+ @classmethod
206
+ def validate_raise_for_status(cls, value: Any) -> bool:
207
+ if isinstance(value, UndefinedSentinel):
208
+ value = getenv(RAISE_FOR_STATUS_ENV_VAR, DEFAULT_RAISE_FOR_STATUS)
336
209
 
210
+ if isinstance(value, str):
337
211
  try:
338
- converted_value = float(env_retry_backoff_max)
339
-
340
- if converted_value > 0:
341
- return converted_value
212
+ value = str_to_bool(value)
342
213
  except ValueError:
343
214
  pass
344
215
 
345
- raise ValueError(
346
- f"Invalid value for {RETRY_BACKOFF_MAX_ENV_VAR}: "
347
- f"{env_retry_backoff_max}",
348
- )
216
+ if isinstance(value, bool):
217
+ return value
349
218
 
350
- raise ValueError(f"Invalid value for retry_backoff_max: {retry_backoff_max}")
219
+ raise cls._prepare_value_error(value, RAISE_FOR_STATUS_ENV_VAR)
351
220
 
352
- def _parse_retry_backoff_exponential(
353
- self,
354
- retry_backoff_exponential: Union[
355
- bool, float, int, UndefinedSentinel
356
- ] = UNDEFINED,
357
- ) -> Union[float, UndefinedSentinel]:
358
- if (
359
- not isinstance(retry_backoff_exponential, bool)
360
- and isinstance(retry_backoff_exponential, (float, int))
361
- and retry_backoff_exponential >= 1
362
- ):
363
- return float(retry_backoff_exponential)
364
- elif isinstance(retry_backoff_exponential, bool):
365
- return (
366
- DEFAULT_RETRY_BACKOFF_EXPONENTIAL if retry_backoff_exponential else 1.0
367
- )
221
+ @field_validator("log_retries", mode="before")
222
+ @classmethod
223
+ def validate_log_retries(cls, value: Any) -> FalseOrLogLevel:
224
+ return cls._validate_false_or_loglevel(
225
+ value,
226
+ LOG_RETRIES_ENV_VAR,
227
+ DEFAULT_LOG_RETRIES,
228
+ )
368
229
 
369
- if retry_backoff_exponential is UNDEFINED:
370
- env_retry_backoff_exponential = getenv(
371
- RETRY_BACKOFF_EXPONENTIAL_ENV_VAR,
372
- UNDEFINED,
373
- )
230
+ @field_validator("log_1xx", mode="before")
231
+ @classmethod
232
+ def validate_log_1xx(cls, value: Any) -> FalseOrLogLevel:
233
+ return cls._validate_false_or_loglevel(
234
+ value,
235
+ LOG_1XX_ENV_VAR,
236
+ DEFAULT_LOG_1XX,
237
+ )
374
238
 
375
- if env_retry_backoff_exponential is UNDEFINED:
376
- return env_retry_backoff_exponential
239
+ @field_validator("log_2xx", mode="before")
240
+ @classmethod
241
+ def validate_log_2xx(cls, value: Any) -> FalseOrLogLevel:
242
+ return cls._validate_false_or_loglevel(
243
+ value,
244
+ LOG_2XX_ENV_VAR,
245
+ DEFAULT_LOG_2XX,
246
+ )
377
247
 
378
- try:
379
- converted_value = float(env_retry_backoff_exponential)
248
+ @field_validator("log_3xx", mode="before")
249
+ @classmethod
250
+ def validate_log_3xx(cls, value: Any) -> FalseOrLogLevel:
251
+ return cls._validate_false_or_loglevel(
252
+ value,
253
+ LOG_3XX_ENV_VAR,
254
+ DEFAULT_LOG_3XX,
255
+ )
380
256
 
381
- if converted_value >= 1:
382
- return converted_value
383
- except ValueError:
384
- pass
257
+ @field_validator("log_4xx", mode="before")
258
+ @classmethod
259
+ def validate_log_4xx(cls, value: Any) -> FalseOrLogLevel:
260
+ return cls._validate_false_or_loglevel(
261
+ value,
262
+ LOG_4XX_ENV_VAR,
263
+ DEFAULT_LOG_4XX,
264
+ )
385
265
 
386
- try:
387
- converted_value = str_to_bool(env_retry_backoff_exponential)
388
- return DEFAULT_RETRY_BACKOFF_EXPONENTIAL if converted_value else 1.0
389
- except ValueError:
390
- pass
266
+ @field_validator("log_5xx", mode="before")
267
+ @classmethod
268
+ def validate_log_5xx(cls, value: Any) -> FalseOrLogLevel:
269
+ return cls._validate_false_or_loglevel(
270
+ value,
271
+ LOG_5XX_ENV_VAR,
272
+ DEFAULT_LOG_5XX,
273
+ )
391
274
 
392
- raise ValueError(
393
- f"Invalid value for {RETRY_BACKOFF_EXPONENTIAL_ENV_VAR}: "
394
- f"{env_retry_backoff_exponential}",
395
- ) from None
275
+ @classmethod
276
+ def _validate_required_string(cls, value: Any, env_var: str) -> str:
277
+ if isinstance(value, UndefinedSentinel):
278
+ value = getenv(env_var, UNDEFINED)
396
279
 
397
- raise ValueError(
398
- f"Invalid value for retry_backoff_exponential: {retry_backoff_exponential}",
399
- )
280
+ if isinstance(value, SecretStr):
281
+ value = value.get_secret_value()
400
282
 
401
- def _parse_retry_statuses(
402
- self,
403
- retry_statuses: Union[List[int], UndefinedSentinel] = UNDEFINED,
404
- ) -> Union[List[int], UndefinedSentinel]:
405
- if isinstance(retry_statuses, (list, set, tuple)) and all(
406
- isinstance(status, int) and 100 <= status <= 599
407
- for status in retry_statuses
408
- ):
409
- return retry_statuses
283
+ if isinstance(value, str) and value.strip():
284
+ return value.strip()
410
285
 
411
- if retry_statuses is UNDEFINED:
412
- env_retry_statuses = getenv(RETRY_STATUSES_ENV_VAR, UNDEFINED)
286
+ raise cls._prepare_value_error(value, env_var)
413
287
 
414
- if env_retry_statuses is UNDEFINED:
415
- return env_retry_statuses
288
+ @classmethod
289
+ def _validate_number(
290
+ cls,
291
+ value: Any,
292
+ env_var: str,
293
+ default: Union[float, int],
294
+ allow_zero: bool = False,
295
+ ) -> float:
296
+ if isinstance(value, UndefinedSentinel):
297
+ value = getenv(env_var, default)
416
298
 
299
+ if isinstance(value, (str, float, int)):
417
300
  try:
418
- converted_values = [
419
- int(status.strip())
420
- for status in env_retry_statuses.split(",")
421
- if status.strip()
422
- ]
423
-
424
- if all(100 <= value <= 599 for value in converted_values):
425
- return converted_values
301
+ value = float(value)
426
302
  except ValueError:
427
303
  pass
428
304
 
429
- raise ValueError(
430
- f"Invalid value for {RETRY_STATUSES_ENV_VAR}: {env_retry_statuses}",
431
- ) from None
305
+ if isinstance(value, (float, int)) and value >= 0 and (allow_zero or value > 0):
306
+ return value
432
307
 
433
- raise ValueError(f"Invalid value for retry_statuses: {retry_statuses}")
308
+ raise cls._prepare_value_error(value, env_var)
434
309
 
435
- def _parse_retry_logs(
436
- self,
437
- retry_logs: Union[bool, UndefinedSentinel] = UNDEFINED,
438
- ) -> Union[bool, UndefinedSentinel]:
439
- if isinstance(retry_logs, bool):
440
- return retry_logs
441
-
442
- if retry_logs is UNDEFINED:
443
- env_retry_logs = getenv(RETRY_LOGS_ENV_VAR, UNDEFINED)
444
-
445
- if env_retry_logs is UNDEFINED:
446
- return env_retry_logs
310
+ @classmethod
311
+ def _validate_false_or_loglevel(
312
+ cls,
313
+ value: Any,
314
+ env_var: str,
315
+ default: FalseOrLogLevel,
316
+ ) -> FalseOrLogLevel:
317
+ if isinstance(value, UndefinedSentinel):
318
+ value = getenv(env_var, default)
447
319
 
320
+ if isinstance(value, str):
448
321
  try:
449
- return str_to_bool(env_retry_logs)
322
+ value = str_to_bool(value)
450
323
  except ValueError:
451
- raise ValueError(
452
- f"Invalid value for {RETRY_LOGS_ENV_VAR}: {env_retry_logs}"
453
- ) from None
324
+ try:
325
+ value = int(value)
326
+ except ValueError:
327
+ pass
454
328
 
455
- raise ValueError(f"Invalid value for retry_logs: {retry_logs}")
329
+ if value is False or value in {DEBUG, INFO, WARNING, ERROR, CRITICAL}:
330
+ return value
456
331
 
457
- def _parse_raise_for_status(
458
- self,
459
- raise_for_status: Union[bool, UndefinedSentinel] = UNDEFINED,
460
- ) -> Union[bool, UndefinedSentinel]:
461
- if isinstance(raise_for_status, bool):
462
- return raise_for_status
463
-
464
- if raise_for_status is UNDEFINED:
465
- env_raise_for_status = getenv(RAISE_FOR_STATUS_ENV_VAR, UNDEFINED)
466
-
467
- if env_raise_for_status is UNDEFINED:
468
- return env_raise_for_status
469
-
470
- try:
471
- return str_to_bool(env_raise_for_status)
472
- except ValueError:
473
- raise ValueError(
474
- f"Invalid value for {RAISE_FOR_STATUS_ENV_VAR}: "
475
- f"{env_raise_for_status}"
476
- ) from None
332
+ raise cls._prepare_value_error(value, env_var)
477
333
 
478
- raise ValueError(f"Invalid value for raise_for_status: {raise_for_status}")
334
+ @staticmethod
335
+ def _prepare_value_error(value: Any, env_var: str) -> ValueError:
336
+ error = "Missing" if isinstance(value, UndefinedSentinel) else "Invalid"
337
+ field_name = env_var.lower().replace("vtex_", "")
338
+ return ValueError(f"{error} {field_name}")