23
23
IdempotencyKeyError ,
24
24
IdempotencyValidationError ,
25
25
)
26
+ from aws_lambda_powertools .utilities .typing import LambdaContext
26
27
27
28
logger = logging .getLogger (__name__ )
28
29
@@ -152,34 +153,35 @@ def configure(self, config: IdempotencyConfig) -> None:
152
153
self ._cache = LRUDict (max_items = config .local_cache_max_items )
153
154
self .hash_function = getattr (hashlib , config .hash_function )
154
155
155
- def _get_hashed_idempotency_key (self , lambda_event : Dict [str , Any ]) -> str :
156
+ def _get_hashed_idempotency_key (self , event : Dict [str , Any ], context : LambdaContext ) -> str :
156
157
"""
157
158
Extract data from lambda event using event key jmespath, and return a hashed representation
158
159
159
160
Parameters
160
161
----------
161
- lambda_event : Dict[str, Any]
162
+ event : Dict[str, Any]
162
163
Lambda event
164
+ context: LambdaContext
165
+ Lambda context
163
166
164
167
Returns
165
168
-------
166
169
str
167
170
Hashed representation of the data extracted by the jmespath expression
168
171
169
172
"""
170
- data = lambda_event
173
+ data = event
171
174
172
175
if self .event_key_jmespath :
173
- data = self .event_key_compiled_jmespath .search (
174
- lambda_event , options = jmespath .Options (** self .jmespath_options )
175
- )
176
+ data = self .event_key_compiled_jmespath .search (event , options = jmespath .Options (** self .jmespath_options ))
176
177
177
178
if self .is_missing_idempotency_key (data ):
178
179
if self .raise_on_no_idempotency_key :
179
180
raise IdempotencyKeyError ("No data found to create a hashed idempotency_key" )
180
181
warnings .warn (f"No value found for idempotency_key. jmespath: { self .event_key_jmespath } " )
181
182
182
- return self ._generate_hash (data )
183
+ generated_hash = self ._generate_hash (data )
184
+ return f"{ context .function_name } #{ generated_hash } "
183
185
184
186
@staticmethod
185
187
def is_missing_idempotency_key (data ) -> bool :
@@ -298,21 +300,23 @@ def _delete_from_cache(self, idempotency_key: str):
298
300
if idempotency_key in self ._cache :
299
301
del self ._cache [idempotency_key ]
300
302
301
- def save_success (self , event : Dict [str , Any ], result : dict ) -> None :
303
+ def save_success (self , event : Dict [str , Any ], context : LambdaContext , result : dict ) -> None :
302
304
"""
303
305
Save record of function's execution completing successfully
304
306
305
307
Parameters
306
308
----------
307
309
event: Dict[str, Any]
308
310
Lambda event
311
+ context: LambdaContext
312
+ Lambda context
309
313
result: dict
310
314
The response from lambda handler
311
315
"""
312
316
response_data = json .dumps (result , cls = Encoder )
313
317
314
318
data_record = DataRecord (
315
- idempotency_key = self ._get_hashed_idempotency_key (event ),
319
+ idempotency_key = self ._get_hashed_idempotency_key (event , context ),
316
320
status = STATUS_CONSTANTS ["COMPLETED" ],
317
321
expiry_timestamp = self ._get_expiry_timestamp (),
318
322
response_data = response_data ,
@@ -326,17 +330,19 @@ def save_success(self, event: Dict[str, Any], result: dict) -> None:
326
330
327
331
self ._save_to_cache (data_record )
328
332
329
- def save_inprogress (self , event : Dict [str , Any ]) -> None :
333
+ def save_inprogress (self , event : Dict [str , Any ], context : LambdaContext ) -> None :
330
334
"""
331
335
Save record of function's execution being in progress
332
336
333
337
Parameters
334
338
----------
335
339
event: Dict[str, Any]
336
340
Lambda event
341
+ context: LambdaContext
342
+ Lambda context
337
343
"""
338
344
data_record = DataRecord (
339
- idempotency_key = self ._get_hashed_idempotency_key (event ),
345
+ idempotency_key = self ._get_hashed_idempotency_key (event , context ),
340
346
status = STATUS_CONSTANTS ["INPROGRESS" ],
341
347
expiry_timestamp = self ._get_expiry_timestamp (),
342
348
payload_hash = self ._get_hashed_payload (event ),
@@ -349,18 +355,20 @@ def save_inprogress(self, event: Dict[str, Any]) -> None:
349
355
350
356
self ._put_record (data_record )
351
357
352
- def delete_record (self , event : Dict [str , Any ], exception : Exception ):
358
+ def delete_record (self , event : Dict [str , Any ], context : LambdaContext , exception : Exception ):
353
359
"""
354
360
Delete record from the persistence store
355
361
356
362
Parameters
357
363
----------
358
364
event: Dict[str, Any]
359
365
Lambda event
366
+ context: LambdaContext
367
+ Lambda context
360
368
exception
361
369
The exception raised by the lambda handler
362
370
"""
363
- data_record = DataRecord (idempotency_key = self ._get_hashed_idempotency_key (event ))
371
+ data_record = DataRecord (idempotency_key = self ._get_hashed_idempotency_key (event , context ))
364
372
365
373
logger .debug (
366
374
f"Lambda raised an exception ({ type (exception ).__name__ } ). Clearing in progress record in persistence "
@@ -370,14 +378,17 @@ def delete_record(self, event: Dict[str, Any], exception: Exception):
370
378
371
379
self ._delete_from_cache (data_record .idempotency_key )
372
380
373
- def get_record (self , event : Dict [str , Any ]) -> DataRecord :
381
+ def get_record (self , event : Dict [str , Any ], context : LambdaContext ) -> DataRecord :
374
382
"""
375
383
Calculate idempotency key for lambda_event, then retrieve item from persistence store using idempotency key
376
384
and return it as a DataRecord instance.and return it as a DataRecord instance.
377
385
378
386
Parameters
379
387
----------
380
388
event: Dict[str, Any]
389
+ Lambda event
390
+ context: LambdaContext
391
+ Lambda context
381
392
382
393
Returns
383
394
-------
@@ -392,7 +403,7 @@ def get_record(self, event: Dict[str, Any]) -> DataRecord:
392
403
Event payload doesn't match the stored record for the given idempotency key
393
404
"""
394
405
395
- idempotency_key = self ._get_hashed_idempotency_key (event )
406
+ idempotency_key = self ._get_hashed_idempotency_key (event , context )
396
407
397
408
cached_record = self ._retrieve_from_cache (idempotency_key = idempotency_key )
398
409
if cached_record :
0 commit comments