aws-lambda-powertools 3.12.1a7__py3-none-any.whl → 3.12.1a9__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.
- aws_lambda_powertools/shared/version.py +1 -1
- aws_lambda_powertools/utilities/idempotency/persistence/cache.py +11 -0
- aws_lambda_powertools/utilities/idempotency/persistence/redis.py +67 -60
- {aws_lambda_powertools-3.12.1a7.dist-info → aws_lambda_powertools-3.12.1a9.dist-info}/METADATA +3 -1
- {aws_lambda_powertools-3.12.1a7.dist-info → aws_lambda_powertools-3.12.1a9.dist-info}/RECORD +7 -6
- {aws_lambda_powertools-3.12.1a7.dist-info → aws_lambda_powertools-3.12.1a9.dist-info}/LICENSE +0 -0
- {aws_lambda_powertools-3.12.1a7.dist-info → aws_lambda_powertools-3.12.1a9.dist-info}/WHEEL +0 -0
@@ -8,6 +8,7 @@ from datetime import timedelta
|
|
8
8
|
from typing import Any, Literal, Protocol
|
9
9
|
|
10
10
|
import redis
|
11
|
+
from typing_extensions import TypeAlias, deprecated
|
11
12
|
|
12
13
|
from aws_lambda_powertools.utilities.idempotency import BasePersistenceLayer
|
13
14
|
from aws_lambda_powertools.utilities.idempotency.exceptions import (
|
@@ -25,11 +26,12 @@ from aws_lambda_powertools.utilities.idempotency.persistence.base import (
|
|
25
26
|
logger = logging.getLogger(__name__)
|
26
27
|
|
27
28
|
|
29
|
+
@deprecated("RedisPersistenceLayer will be removed in v4.0.0. Please use CacheProtocol instead.")
|
28
30
|
class RedisClientProtocol(Protocol):
|
29
31
|
"""
|
30
|
-
Protocol class defining the interface for a
|
32
|
+
Protocol class defining the interface for a Cache client.
|
31
33
|
|
32
|
-
This protocol outlines the expected behavior of a
|
34
|
+
This protocol outlines the expected behavior of a Cache client, allowing for
|
33
35
|
standardization among different implementations and allowing customers to extend it
|
34
36
|
in their own implementation.
|
35
37
|
|
@@ -78,6 +80,7 @@ class RedisClientProtocol(Protocol):
|
|
78
80
|
raise NotImplementedError
|
79
81
|
|
80
82
|
|
83
|
+
@deprecated("RedisConnection will be removed in v4.0.0. Please use CacheConnection instead.")
|
81
84
|
class RedisConnection:
|
82
85
|
def __init__(
|
83
86
|
self,
|
@@ -85,32 +88,32 @@ class RedisConnection:
|
|
85
88
|
host: str = "",
|
86
89
|
port: int = 6379,
|
87
90
|
username: str = "",
|
88
|
-
password: str = "", # nosec - password for
|
91
|
+
password: str = "", # nosec - password for Cache connection
|
89
92
|
db_index: int = 0,
|
90
93
|
mode: Literal["standalone", "cluster"] = "standalone",
|
91
94
|
ssl: bool = True,
|
92
95
|
) -> None:
|
93
96
|
"""
|
94
|
-
Initialize
|
97
|
+
Initialize Cache connection which will be used in Cache persistence_store to support Idempotency
|
95
98
|
|
96
99
|
Parameters
|
97
100
|
----------
|
98
101
|
host: str, optional
|
99
|
-
|
102
|
+
Cache host
|
100
103
|
port: int, optional: default 6379
|
101
|
-
|
104
|
+
Cache port
|
102
105
|
username: str, optional
|
103
|
-
|
106
|
+
Cache username
|
104
107
|
password: str, optional
|
105
|
-
|
108
|
+
Cache password
|
106
109
|
url: str, optional
|
107
|
-
|
110
|
+
Cache connection string, using url will override the host/port in the previous parameters
|
108
111
|
db_index: int, optional: default 0
|
109
|
-
|
112
|
+
Cache db index
|
110
113
|
mode: str, Literal["standalone","cluster"]
|
111
|
-
set
|
114
|
+
set Cache client mode, choose from standalone/cluster. The default is standalone
|
112
115
|
ssl: bool, optional: default True
|
113
|
-
set whether to use ssl for
|
116
|
+
set whether to use ssl for Cache connection
|
114
117
|
|
115
118
|
Example
|
116
119
|
--------
|
@@ -122,13 +125,13 @@ class RedisConnection:
|
|
122
125
|
from aws_lambda_powertools.utilities.idempotency import (
|
123
126
|
idempotent,
|
124
127
|
)
|
125
|
-
from aws_lambda_powertools.utilities.idempotency.persistence.
|
126
|
-
|
128
|
+
from aws_lambda_powertools.utilities.idempotency.persistence.cache import (
|
129
|
+
CachePersistenceLayer,
|
127
130
|
)
|
128
131
|
|
129
132
|
from aws_lambda_powertools.utilities.typing import LambdaContext
|
130
133
|
|
131
|
-
persistence_layer =
|
134
|
+
persistence_layer = CachePersistenceLayer(host="localhost", port=6379)
|
132
135
|
|
133
136
|
|
134
137
|
@dataclass
|
@@ -181,15 +184,15 @@ class RedisConnection:
|
|
181
184
|
|
182
185
|
try:
|
183
186
|
if self.url:
|
184
|
-
logger.debug(f"Using URL format to connect to
|
187
|
+
logger.debug(f"Using URL format to connect to Cache: {self.host}")
|
185
188
|
return client.from_url(url=self.url)
|
186
189
|
else:
|
187
|
-
#
|
190
|
+
# Cache in cluster mode doesn't support db parameter
|
188
191
|
extra_param_connection: dict[str, Any] = {}
|
189
192
|
if self.mode != "cluster":
|
190
193
|
extra_param_connection = {"db": self.db_index}
|
191
194
|
|
192
|
-
logger.debug(f"Using arguments to connect to
|
195
|
+
logger.debug(f"Using arguments to connect to Cache: {self.host}")
|
193
196
|
return client(
|
194
197
|
host=self.host,
|
195
198
|
port=self.port,
|
@@ -200,10 +203,11 @@ class RedisConnection:
|
|
200
203
|
**extra_param_connection,
|
201
204
|
)
|
202
205
|
except redis.exceptions.ConnectionError as exc:
|
203
|
-
logger.debug(f"Cannot connect
|
204
|
-
raise IdempotencyPersistenceConnectionError("Could not to connect to
|
206
|
+
logger.debug(f"Cannot connect to Cache endpoint: {self.host}")
|
207
|
+
raise IdempotencyPersistenceConnectionError("Could not to connect to Cache endpoint", exc) from exc
|
205
208
|
|
206
209
|
|
210
|
+
@deprecated("RedisCachePersistenceLayer will be removed in v4.0.0. Please use CachePersistenceLayer instead.")
|
207
211
|
class RedisCachePersistenceLayer(BasePersistenceLayer):
|
208
212
|
def __init__(
|
209
213
|
self,
|
@@ -211,7 +215,7 @@ class RedisCachePersistenceLayer(BasePersistenceLayer):
|
|
211
215
|
host: str = "",
|
212
216
|
port: int = 6379,
|
213
217
|
username: str = "",
|
214
|
-
password: str = "", # nosec - password for
|
218
|
+
password: str = "", # nosec - password for Cache connection
|
215
219
|
db_index: int = 0,
|
216
220
|
mode: Literal["standalone", "cluster"] = "standalone",
|
217
221
|
ssl: bool = True,
|
@@ -223,39 +227,39 @@ class RedisCachePersistenceLayer(BasePersistenceLayer):
|
|
223
227
|
validation_key_attr: str = "validation",
|
224
228
|
):
|
225
229
|
"""
|
226
|
-
Initialize the
|
230
|
+
Initialize the Cache Persistence Layer
|
227
231
|
|
228
232
|
Parameters
|
229
233
|
----------
|
230
234
|
host: str, optional
|
231
|
-
|
235
|
+
Cache host
|
232
236
|
port: int, optional: default 6379
|
233
|
-
|
237
|
+
Cache port
|
234
238
|
username: str, optional
|
235
|
-
|
239
|
+
Cache username
|
236
240
|
password: str, optional
|
237
|
-
|
241
|
+
Cache password
|
238
242
|
url: str, optional
|
239
|
-
|
243
|
+
Cache connection string, using url will override the host/port in the previous parameters
|
240
244
|
db_index: int, optional: default 0
|
241
|
-
|
245
|
+
Cache db index
|
242
246
|
mode: str, Literal["standalone","cluster"]
|
243
|
-
set
|
247
|
+
set Cache client mode, choose from standalone/cluster
|
244
248
|
ssl: bool, optional: default True
|
245
|
-
set whether to use ssl for
|
246
|
-
client:
|
247
|
-
Bring your own
|
249
|
+
set whether to use ssl for Cache connection
|
250
|
+
client: CacheClientProtocol, optional
|
251
|
+
Bring your own Cache client that follows CacheClientProtocol.
|
248
252
|
If provided, all other connection configuration options will be ignored
|
249
253
|
expiry_attr: str, optional
|
250
|
-
|
254
|
+
Cache json attribute name for expiry timestamp, by default "expiration"
|
251
255
|
in_progress_expiry_attr: str, optional
|
252
|
-
|
256
|
+
Cache json attribute name for in-progress expiry timestamp, by default "in_progress_expiration"
|
253
257
|
status_attr: str, optional
|
254
|
-
|
258
|
+
Cache json attribute name for status, by default "status"
|
255
259
|
data_attr: str, optional
|
256
|
-
|
260
|
+
Cache json attribute name for response data, by default "data"
|
257
261
|
validation_key_attr: str, optional
|
258
|
-
|
262
|
+
Cache json attribute name for hashed representation of the parts of the event used for validation
|
259
263
|
|
260
264
|
Examples
|
261
265
|
--------
|
@@ -266,8 +270,8 @@ class RedisCachePersistenceLayer(BasePersistenceLayer):
|
|
266
270
|
idempotent,
|
267
271
|
)
|
268
272
|
|
269
|
-
from aws_lambda_powertools.utilities.idempotency.persistence.
|
270
|
-
|
273
|
+
from aws_lambda_powertools.utilities.idempotency.persistence.cache import (
|
274
|
+
CachePersistenceLayer,
|
271
275
|
)
|
272
276
|
|
273
277
|
client = redis.Redis(
|
@@ -275,7 +279,7 @@ class RedisCachePersistenceLayer(BasePersistenceLayer):
|
|
275
279
|
port="6379",
|
276
280
|
decode_responses=True,
|
277
281
|
)
|
278
|
-
persistence_layer =
|
282
|
+
persistence_layer = CachePersistenceLayer(client=client)
|
279
283
|
|
280
284
|
@idempotent(persistence_store=persistence_layer)
|
281
285
|
def lambda_handler(event: dict, context: LambdaContext):
|
@@ -288,7 +292,7 @@ class RedisCachePersistenceLayer(BasePersistenceLayer):
|
|
288
292
|
```
|
289
293
|
"""
|
290
294
|
|
291
|
-
# Initialize
|
295
|
+
# Initialize Cache client with cache config if no client is passed in
|
292
296
|
if client is None:
|
293
297
|
self.client = RedisConnection(
|
294
298
|
host=host,
|
@@ -330,11 +334,11 @@ class RedisCachePersistenceLayer(BasePersistenceLayer):
|
|
330
334
|
in_progress_expiry_timestamp=in_progress_expiry_timestamp,
|
331
335
|
response_data=str(item.get(self.data_attr)),
|
332
336
|
payload_hash=str(item.get(self.validation_key_attr)),
|
333
|
-
expiry_timestamp=item.get("expiration"
|
337
|
+
expiry_timestamp=item.get("expiration"),
|
334
338
|
)
|
335
339
|
|
336
340
|
def _get_record(self, idempotency_key) -> DataRecord:
|
337
|
-
# See: https://
|
341
|
+
# See: https://valkey.io/valkey-glide/python/core/#glide.async_commands.CoreCommands.set
|
338
342
|
response = self.client.get(idempotency_key)
|
339
343
|
|
340
344
|
# key not found
|
@@ -384,25 +388,25 @@ class RedisCachePersistenceLayer(BasePersistenceLayer):
|
|
384
388
|
# The idempotency key does not exist:
|
385
389
|
# - first time that this invocation key is used
|
386
390
|
# - previous invocation with the same key was deleted due to TTL
|
387
|
-
# - SET see https://
|
391
|
+
# - SET see https://valkey.io/valkey-glide/python/core/#glide.async_commands.CoreCommands.set
|
388
392
|
|
389
|
-
logger.debug(f"Putting record on
|
393
|
+
logger.debug(f"Putting record on Cache for idempotency key: {data_record.idempotency_key}")
|
390
394
|
encoded_item = self._json_serializer(item["mapping"])
|
391
395
|
ttl = self._get_expiry_second(expiry_timestamp=data_record.expiry_timestamp)
|
392
396
|
|
393
|
-
|
397
|
+
cache_response = self.client.set(name=data_record.idempotency_key, value=encoded_item, ex=ttl, nx=True)
|
394
398
|
|
395
|
-
# If
|
399
|
+
# If cache_response is True, the Cache SET operation was successful and the idempotency key was not
|
396
400
|
# previously set. This indicates that we can safely proceed to the handler execution phase.
|
397
401
|
# Most invocations should successfully proceed past this point.
|
398
|
-
if
|
402
|
+
if cache_response:
|
399
403
|
return
|
400
404
|
|
401
|
-
# If
|
405
|
+
# If cache_response is None, it indicates an existing record in Cache for the given idempotency key.
|
402
406
|
# This could be due to:
|
403
407
|
# - An active idempotency record from a previous invocation that has not yet expired.
|
404
408
|
# - An orphan record where a previous invocation has timed out.
|
405
|
-
# - An expired idempotency record that has not been deleted by
|
409
|
+
# - An expired idempotency record that has not been deleted by Cache.
|
406
410
|
# In any case, we proceed to retrieve the record for further inspection.
|
407
411
|
|
408
412
|
idempotency_record = self._get_record(data_record.idempotency_key)
|
@@ -427,7 +431,7 @@ class RedisCachePersistenceLayer(BasePersistenceLayer):
|
|
427
431
|
|
428
432
|
# Reaching this point indicates that the idempotency record found is an orphan record. An orphan record is
|
429
433
|
# one that is neither completed nor in-progress within its expected time frame. It may result from a
|
430
|
-
# previous invocation that has timed out or an expired record that has yet to be cleaned up by
|
434
|
+
# previous invocation that has timed out or an expired record that has yet to be cleaned up by Cache.
|
431
435
|
# We raise an error to handle this exceptional scenario appropriately.
|
432
436
|
raise IdempotencyPersistenceConsistencyError
|
433
437
|
|
@@ -435,24 +439,22 @@ class RedisCachePersistenceLayer(BasePersistenceLayer):
|
|
435
439
|
# Handle an orphan record by attempting to acquire a lock, which by default lasts for 10 seconds.
|
436
440
|
# The purpose of acquiring the lock is to prevent race conditions with other processes that might
|
437
441
|
# also be trying to handle the same orphan record. Once the lock is acquired, we set a new value
|
438
|
-
# for the idempotency record in
|
442
|
+
# for the idempotency record in Cache with the appropriate time-to-live (TTL).
|
439
443
|
with self._acquire_lock(name=item["name"]):
|
440
444
|
self.client.set(name=item["name"], value=encoded_item, ex=ttl)
|
441
445
|
|
442
446
|
# Not removing the lock here serves as a safeguard against race conditions,
|
443
447
|
# preventing another operation from mistakenly treating this record as an orphan while the
|
444
448
|
# current operation is still in progress.
|
445
|
-
except (redis.exceptions.RedisError, redis.exceptions.RedisClusterException) as e:
|
446
|
-
raise e
|
447
449
|
except Exception as e:
|
448
|
-
logger.debug(f"
|
449
|
-
raise
|
450
|
+
logger.debug(f"An error occurred: {e}")
|
451
|
+
raise
|
450
452
|
|
451
453
|
@contextmanager
|
452
454
|
def _acquire_lock(self, name: str):
|
453
455
|
"""
|
454
456
|
Attempt to acquire a lock for a specified resource name, with a default timeout.
|
455
|
-
This context manager attempts to set a lock using
|
457
|
+
This context manager attempts to set a lock using Cache to prevent concurrent
|
456
458
|
access to a resource identified by 'name'. It uses the 'nx' flag to ensure that
|
457
459
|
the lock is only set if it does not already exist, thereby enforcing mutual exclusion.
|
458
460
|
"""
|
@@ -496,9 +498,9 @@ class RedisCachePersistenceLayer(BasePersistenceLayer):
|
|
496
498
|
|
497
499
|
def _delete_record(self, data_record: DataRecord) -> None:
|
498
500
|
"""
|
499
|
-
Deletes the idempotency record associated with a given DataRecord from
|
501
|
+
Deletes the idempotency record associated with a given DataRecord from Cache.
|
500
502
|
This function is designed to be called after a Lambda handler invocation has completed processing.
|
501
|
-
It ensures that the idempotency key associated with the DataRecord is removed from
|
503
|
+
It ensures that the idempotency key associated with the DataRecord is removed from Cache to
|
502
504
|
prevent future conflicts and to maintain the idempotency integrity.
|
503
505
|
|
504
506
|
Note: it is essential that the idempotency key is not empty, as that would indicate the Lambda
|
@@ -506,5 +508,10 @@ class RedisCachePersistenceLayer(BasePersistenceLayer):
|
|
506
508
|
"""
|
507
509
|
logger.debug(f"Deleting record for idempotency key: {data_record.idempotency_key}")
|
508
510
|
|
509
|
-
# See: https://
|
511
|
+
# See: https://valkey.io/valkey-glide/python/core/#glide.async_commands.CoreCommands.delete
|
510
512
|
self.client.delete(data_record.idempotency_key)
|
513
|
+
|
514
|
+
|
515
|
+
CachePersistenceLayer: TypeAlias = RedisCachePersistenceLayer
|
516
|
+
CacheClientProtocol: TypeAlias = RedisClientProtocol
|
517
|
+
CacheConnection: TypeAlias = RedisConnection
|
{aws_lambda_powertools-3.12.1a7.dist-info → aws_lambda_powertools-3.12.1a9.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: aws_lambda_powertools
|
3
|
-
Version: 3.12.
|
3
|
+
Version: 3.12.1a9
|
4
4
|
Summary: Powertools for AWS Lambda (Python) is a developer toolkit to implement Serverless best practices and increase developer velocity.
|
5
5
|
License: MIT
|
6
6
|
Keywords: aws_lambda_powertools,aws,tracing,logging,lambda,powertools,feature_flags,idempotency,middleware
|
@@ -25,6 +25,7 @@ Provides-Extra: parser
|
|
25
25
|
Provides-Extra: redis
|
26
26
|
Provides-Extra: tracer
|
27
27
|
Provides-Extra: validation
|
28
|
+
Provides-Extra: valkey
|
28
29
|
Requires-Dist: aws-encryption-sdk (>=3.1.1,<5.0.0) ; extra == "all" or extra == "datamasking"
|
29
30
|
Requires-Dist: aws-xray-sdk (>=2.8.0,<3.0.0) ; extra == "tracer" or extra == "all"
|
30
31
|
Requires-Dist: boto3 (>=1.34.32,<2.0.0) ; extra == "aws-sdk"
|
@@ -36,6 +37,7 @@ Requires-Dist: pydantic (>=2.4.0,<3.0.0) ; extra == "parser" or extra == "all"
|
|
36
37
|
Requires-Dist: pydantic-settings (>=2.6.1,<3.0.0) ; extra == "all"
|
37
38
|
Requires-Dist: redis (>=4.4,<7.0) ; extra == "redis"
|
38
39
|
Requires-Dist: typing-extensions (>=4.11.0,<5.0.0)
|
40
|
+
Requires-Dist: valkey-glide (>=1.3.5,<2.0) ; extra == "valkey"
|
39
41
|
Project-URL: Documentation, https://docs.powertools.aws.dev/lambda/python/
|
40
42
|
Project-URL: Issue tracker, https://github.com/aws-powertools/powertools-lambda-python/issues
|
41
43
|
Project-URL: Repository, https://github.com/aws-powertools/powertools-lambda-python
|
{aws_lambda_powertools-3.12.1a7.dist-info → aws_lambda_powertools-3.12.1a9.dist-info}/RECORD
RENAMED
@@ -97,7 +97,7 @@ aws_lambda_powertools/shared/json_encoder.py,sha256=JQeWNu-4M7_xI_hqYExrxsb3OcEH
|
|
97
97
|
aws_lambda_powertools/shared/lazy_import.py,sha256=TbXQm2bcwXdZrYdBaJJXIswyLlumM85RJ_A_0w-h-GU,2019
|
98
98
|
aws_lambda_powertools/shared/types.py,sha256=EZ_tbX3F98LA4Zcra1hTEjzRacpZAtggK957Zcv1oKg,135
|
99
99
|
aws_lambda_powertools/shared/user_agent.py,sha256=DrCMFQuT4a4iIrpcWpAIjY37EFqR9-QxlxDGD-Nn9Gg,7081
|
100
|
-
aws_lambda_powertools/shared/version.py,sha256
|
100
|
+
aws_lambda_powertools/shared/version.py,sha256=-vsxq2DhrkC6gFTyPBzHdPbaHnfg2-EwEu03tvXjNbQ,85
|
101
101
|
aws_lambda_powertools/tracing/__init__.py,sha256=f4bMThOPBPWTPVcYqcAIErAJPerMsf3H_Z4gCXCsK9I,141
|
102
102
|
aws_lambda_powertools/tracing/base.py,sha256=WSO986XGBOe9K0F2SnG6ustJokIrtO0m0mcL8N7mfno,4544
|
103
103
|
aws_lambda_powertools/tracing/extensions.py,sha256=APOfXOq-hRBKaK5WyfIyrd_6M1_9SWJZ3zxLA9jDZzU,492
|
@@ -175,9 +175,10 @@ aws_lambda_powertools/utilities/idempotency/hook.py,sha256=XHj6q0dP65C8Cj-TPJ9a8
|
|
175
175
|
aws_lambda_powertools/utilities/idempotency/idempotency.py,sha256=_t_OmCzL8vBcmrif_9PrAnoCkfBMnG3p2T3sVGHhUqw,7429
|
176
176
|
aws_lambda_powertools/utilities/idempotency/persistence/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
177
177
|
aws_lambda_powertools/utilities/idempotency/persistence/base.py,sha256=slYzih7C-tpAUugXdM2DMemNVA_HnxsbtpsvZKiH3gY,16022
|
178
|
+
aws_lambda_powertools/utilities/idempotency/persistence/cache.py,sha256=GgGmp-5HtbZoVKUxp70-8rw-lq1d3Fwq9HmGXiINQDk,245
|
178
179
|
aws_lambda_powertools/utilities/idempotency/persistence/datarecord.py,sha256=brtO34whh_ioHkB6GfIjcIUyvzBI7BrEiwQVwFjEVXc,3644
|
179
180
|
aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py,sha256=H0dm8U1dwNPzAHtmARBoPIq-ajI1ih62bgQFX1RyVxo,13908
|
180
|
-
aws_lambda_powertools/utilities/idempotency/persistence/redis.py,sha256=
|
181
|
+
aws_lambda_powertools/utilities/idempotency/persistence/redis.py,sha256=dJZ2afGILfhy-ov2Nwim51s4q7zKyz2C6ZjuaLBwUT4,22126
|
181
182
|
aws_lambda_powertools/utilities/idempotency/serialization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
182
183
|
aws_lambda_powertools/utilities/idempotency/serialization/base.py,sha256=E6ZO7uGOJnhepSkS4NkUbPhw9BNU1581HRmdgEaXe8k,1445
|
183
184
|
aws_lambda_powertools/utilities/idempotency/serialization/custom_dict.py,sha256=QhPDPoa-MHAqo8APjSaQEENPeRiOnTovHWhQgCBkfIg,1018
|
@@ -268,7 +269,7 @@ aws_lambda_powertools/utilities/validation/envelopes.py,sha256=YD5HOFx6IClQgii0n
|
|
268
269
|
aws_lambda_powertools/utilities/validation/exceptions.py,sha256=PKy_19zQMBJGCMMFl-sMkcm-cc0v3zZBn_bhGE4wKNo,2084
|
269
270
|
aws_lambda_powertools/utilities/validation/validator.py,sha256=khCqFhACSdn0nKyYRRPiC5Exht956hTfSfhlV3IRmpg,10099
|
270
271
|
aws_lambda_powertools/warnings/__init__.py,sha256=vqDVeZz8wGtD8WGYNSkQE7AHwqtIrPGRxuoJR_BBnSs,1193
|
271
|
-
aws_lambda_powertools-3.12.
|
272
|
-
aws_lambda_powertools-3.12.
|
273
|
-
aws_lambda_powertools-3.12.
|
274
|
-
aws_lambda_powertools-3.12.
|
272
|
+
aws_lambda_powertools-3.12.1a9.dist-info/LICENSE,sha256=vMHS2eBgmwPUIMPb7LQ4p7ib_FPVQXarVjAasflrTwo,951
|
273
|
+
aws_lambda_powertools-3.12.1a9.dist-info/METADATA,sha256=Hoz_WlCMO7qqUjQ9nK3nDvfM0gE41MiEQmUaEpBWL1I,11273
|
274
|
+
aws_lambda_powertools-3.12.1a9.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
275
|
+
aws_lambda_powertools-3.12.1a9.dist-info/RECORD,,
|
{aws_lambda_powertools-3.12.1a7.dist-info → aws_lambda_powertools-3.12.1a9.dist-info}/LICENSE
RENAMED
File without changes
|
File without changes
|