Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 5f50be5

Browse files
committedApr 3, 2024
Improving doc
1 parent f0596a4 commit 5f50be5

File tree

3 files changed

+50
-10
lines changed

3 files changed

+50
-10
lines changed
 

‎docs/utilities/idempotency.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -950,20 +950,32 @@ You can set up a `response_hook` in the `IdempotentConfig` class to access the r
950950

951951
=== "Using an Idempotent Response Hook"
952952

953-
```python hl_lines="15 17 20 31"
953+
```python hl_lines="18 20 23 32"
954954
--8<-- "examples/idempotency/src/working_with_response_hook.py"
955955
```
956956

957957
=== "Sample event"
958958

959959
```json
960-
--8<-- "examples/idempotency/src/getting_started_with_idempotency_payload.json"
960+
--8<-- "examples/idempotency/src/working_with_response_hook_payload.json"
961961
```
962962

963963
???+ info "Info: Using custom de-serialization?"
964964

965965
The response_hook is called after the custom de-serialization so the payload you process will be the de-serialized version.
966966

967+
#### Being a good citizen
968+
969+
Using Response hooks can add subtle improvements to manipulating returned data from idempotent operations, but also add significant complexity if you're not careful.
970+
971+
Keep the following in mind when authoring hooks for Idempotency utility:
972+
973+
1. **Response hook works exclusively when operations are idempotent.** Carefully consider the logic within the `Response hook` and prevent any attempt to access the key from relying exclusively on idempotent operations.
974+
975+
2. **Catch your own exceptions.** Catch and handle known exceptions to your logic.
976+
977+
3. **Watch out when you are decorating the Lambda Handler and using the Response hook.** If you don't catch and handle exceptions in your `Response hook`, your function might not run properly.
978+
967979
## Compatibility with other utilities
968980

969981
### Batch
Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
1-
from datetime import datetime
1+
import datetime
2+
import uuid
23
from typing import Dict
34

5+
from aws_lambda_powertools import Logger
46
from aws_lambda_powertools.utilities.idempotency import (
57
DynamoDBPersistenceLayer,
68
IdempotencyConfig,
7-
idempotent,
9+
idempotent_function,
810
)
911
from aws_lambda_powertools.utilities.idempotency.persistence.base import (
1012
DataRecord,
1113
)
1214
from aws_lambda_powertools.utilities.typing import LambdaContext
1315

16+
logger = Logger()
17+
1418

1519
def my_response_hook(response: Dict, idempotent_data: DataRecord) -> Dict:
1620
# Return inserted Header data into the Idempotent Response
@@ -19,18 +23,34 @@ def my_response_hook(response: Dict, idempotent_data: DataRecord) -> Dict:
1923
# expiry_timestamp could be None so include if set
2024
expiry_timestamp = idempotent_data.expiry_timestamp
2125
if expiry_timestamp:
22-
expiry_time = datetime.fromtimestamp(int(expiry_timestamp))
26+
expiry_time = datetime.datetime.fromtimestamp(int(expiry_timestamp))
2327
response["x-idempotent-expiration"] = expiry_time.isoformat()
2428

2529
# Must return the response here
2630
return response
2731

2832

29-
persistence_layer = DynamoDBPersistenceLayer(table_name="IdempotencyTable")
30-
33+
dynamodb = DynamoDBPersistenceLayer(table_name="IdempotencyTable")
3134
config = IdempotencyConfig(response_hook=my_response_hook)
3235

3336

34-
@idempotent(persistence_store=persistence_layer, config=config)
35-
def lambda_handler(event: dict, context: LambdaContext) -> dict:
36-
return event
37+
@idempotent_function(data_keyword_argument="order", config=config, persistence_store=dynamodb)
38+
def process_order(order: dict) -> dict:
39+
# create the order_id
40+
order_id = str(uuid.uuid4())
41+
42+
# create your logic to save the order
43+
# append the order_id created
44+
order["order_id"] = order_id
45+
46+
# return the order
47+
return {"order": order}
48+
49+
50+
def lambda_handler(event: dict, context: LambdaContext):
51+
config.register_lambda_context(context) # see Lambda timeouts section
52+
try:
53+
logger.info(f"Processing order id {event.get('order_id')}")
54+
return process_order(order=event.get("order"))
55+
except Exception as err:
56+
return {"status_code": 400, "error": f"Erro processing {str(err)}"}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"order" : {
3+
"user_id": "xyz",
4+
"product_id": "123456789",
5+
"quantity": 2,
6+
"value": 30
7+
}
8+
}

0 commit comments

Comments
 (0)
Please sign in to comment.