Skip to content

Commit dfc928f

Browse files
author
Michael Brewer
authored
docs(idempotent): Fix typos and code formatting (#305)
Changes: * Used the same formatting and indentation for all of the code examples * Fix various typos and spelling * Highlight the correct lines on some of the examples
1 parent 5367f61 commit dfc928f

File tree

1 file changed

+102
-89
lines changed

1 file changed

+102
-89
lines changed

docs/utilities/idempotency.md

Lines changed: 102 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ storage layer, so you'll need to create a table first.
3434
> Example using AWS Serverless Application Model (SAM)
3535
3636
=== "template.yml"
37+
3738
```yaml
3839
Resources:
3940
HelloWorldFunction:
@@ -76,32 +77,32 @@ You can quickly start by initializing the `DynamoDBPersistenceLayer` class outsi
7677
with the `idempotent` decorator on your lambda handler. The only required parameter is `table_name`, but you likely
7778
want to specify `event_key_jmespath` as well.
7879

79-
`event_key_jmespath`: A JMESpath expression which will be used to extract the payload from the event your Lambda hander
80+
`event_key_jmespath`: A JMESpath expression which will be used to extract the payload from the event your Lambda handler
8081
is called with. This payload will be used as the key to decide if future invocations are duplicates. If you don't pass
8182
this parameter, the entire event will be used as the key.
8283

8384
=== "app.py"
8485

8586
```python hl_lines="2 6-9 11"
86-
import json
87-
from aws_lambda_powertools.utilities.idempotency import DynamoDBPersistenceLayer, idempotent
88-
89-
# Treat everything under the "body" key in
90-
# the event json object as our payload
91-
persistence_layer = DynamoDBPersistenceLayer(
92-
event_key_jmespath="body",
93-
table_name="IdempotencyTable"
94-
)
87+
import json
88+
from aws_lambda_powertools.utilities.idempotency import DynamoDBPersistenceLayer, idempotent
89+
90+
# Treat everything under the "body" key in
91+
# the event json object as our payload
92+
persistence_layer = DynamoDBPersistenceLayer(
93+
table_name="IdempotencyTable",
94+
event_key_jmespath="body",
95+
)
9596

96-
@idempotent(persistence_store=persistence_layer)
97-
def handler(event, context):
98-
body = json.loads(event['body'])
99-
payment = create_subscription_payment(
100-
user=body['user'],
101-
product=body['product_id']
102-
)
103-
...
104-
return {"message": "success", "statusCode": 200, "payment_id": payment.id}
97+
@idempotent(persistence_store=persistence_layer)
98+
def handler(event, context):
99+
body = json.loads(event['body'])
100+
payment = create_subscription_payment(
101+
user=body['user'],
102+
product=body['product_id']
103+
)
104+
...
105+
return {"message": "success", "statusCode": 200, "payment_id": payment.id}
105106
```
106107
=== "Example event"
107108

@@ -171,17 +172,19 @@ In most cases, it is not desirable to store the idempotency records forever. Rat
171172
same payload won't be executed within a period of time. By default, the period is set to 1 hour (3600 seconds). You can
172173
change this window with the `expires_after_seconds` parameter:
173174

174-
```python hl_lines="4"
175-
DynamoDBPersistenceLayer(
176-
event_key_jmespath="body",
177-
table_name="IdempotencyTable",
178-
expires_after_seconds=5*60 # 5 minutes
175+
=== "app.py"
176+
177+
```python hl_lines="4"
178+
DynamoDBPersistenceLayer(
179+
table_name="IdempotencyTable",
180+
event_key_jmespath="body",
181+
expires_after_seconds=5*60, # 5 minutes
179182
)
183+
```
180184

181-
```
182185
This will mark any records older than 5 minutes as expired, and the lambda handler will be executed as normal if it is
183186
invoked with a matching payload. If you have set the TTL field in DynamoDB like in the SAM example above, the record
184-
will be automatically deleted from the table after a period of itme.
187+
will be automatically deleted from the table after a period of time.
185188

186189

187190
### Handling concurrent executions
@@ -195,17 +198,19 @@ concurrent execution. If you receive this error, you can safely retry the operat
195198
To reduce the number of lookups to the persistence storage layer, you can enable in memory caching with the
196199
`use_local_cache` parameter, which is disabled by default. This cache is local to each Lambda execution environment.
197200
This means it will be effective in cases where your function's concurrency is low in comparison to the number of
198-
"retry" invocations with the same payload. When enabled, the default is to cache a maxmum of 256 records in each Lambda
201+
"retry" invocations with the same payload. When enabled, the default is to cache a maximum of 256 records in each Lambda
199202
execution environment. You can change this with the `local_cache_max_items` parameter.
200203

201-
```python hl_lines="4 5"
202-
DynamoDBPersistenceLayer(
203-
event_key_jmespath="body",
204-
table_name="IdempotencyTable",
205-
use_local_cache=True,
206-
local_cache_max_items=1000
204+
=== "app.py"
205+
206+
```python hl_lines="4 5"
207+
DynamoDBPersistenceLayer(
208+
table_name="IdempotencyTable",
209+
event_key_jmespath="body",
210+
use_local_cache=True,
211+
local_cache_max_items=1000
207212
)
208-
```
213+
```
209214

210215

211216
## Advanced
@@ -218,35 +223,37 @@ with the `payload_validation_jmespath` to specify which part of the event body s
218223
idempotent invocations.
219224

220225
=== "app.py"
226+
221227
```python hl_lines="6"
222228
from aws_lambda_powertools.utilities.idempotency import DynamoDBPersistenceLayer, idempotent
223229

224-
persistence_layer = DynamoDBPersistenceLayer(
225-
event_key_jmespath="[userDetail, productId]",
226-
table_name="IdempotencyTable",)
227-
payload_validation_jmespath="amount"
228-
)
230+
persistence_layer = DynamoDBPersistenceLayer(
231+
table_name="IdempotencyTable",
232+
event_key_jmespath="[userDetail, productId]",
233+
payload_validation_jmespath="amount"
234+
)
229235

230-
@idempotent(persistence_store=persistence_layer)
231-
def handler(event, context):
232-
# Creating a subscription payment is a side
233-
# effect of calling this function!
234-
payment = create_subscription_payment(
235-
user=event['userDetail']['username'],
236-
product=event['product_id'],
237-
amount=event['amount']
238-
)
239-
...
240-
return {"message": "success", "statusCode": 200,
241-
"payment_id": payment.id, "amount": payment.amount}
236+
@idempotent(persistence_store=persistence_layer)
237+
def handler(event, context):
238+
# Creating a subscription payment is a side
239+
# effect of calling this function!
240+
payment = create_subscription_payment(
241+
user=event['userDetail']['username'],
242+
product=event['product_id'],
243+
amount=event['amount']
244+
)
245+
...
246+
return {"message": "success", "statusCode": 200,
247+
"payment_id": payment.id, "amount": payment.amount}
242248
```
243-
=== "Event"
249+
=== "Example Event"
250+
244251
```json
245252
{
246253
"userDetail": {
247254
"username": "User1",
248255
"user_email": "[email protected]"
249-
},
256+
},
250257
"productId": 1500,
251258
"charge_type": "subscription",
252259
"amount": 500
@@ -264,13 +271,15 @@ amount field, we prevent this potentially confusing behaviour and instead raise
264271
If you want to enforce that an idempotency key is required, you can set `raise_on_no_idempotency_key` to `True`,
265272
and we will raise `IdempotencyKeyError` if none was found.
266273

267-
```python hl_lines="4"
268-
DynamoDBPersistenceLayer(
269-
event_key_jmespath="body",
270-
table_name="IdempotencyTable",
271-
raise_on_no_idempotency_key=True
274+
=== "app.py"
275+
276+
```python hl_lines="4"
277+
DynamoDBPersistenceLayer(
278+
table_name="IdempotencyTable",
279+
event_key_jmespath="body",
280+
raise_on_no_idempotency_key=True,
272281
)
273-
```
282+
```
274283

275284
### Changing dynamoDB attribute names
276285
If you want to use an existing DynamoDB table, or wish to change the name of the attributes used to store items in the
@@ -288,53 +297,56 @@ validation_key_attr | "validation" | Hashed representation of the parts of the
288297
This example demonstrates changing the attribute names to custom values:
289298

290299
=== "app.py"
291-
```python hl_lines="5-10"
300+
301+
```python hl_lines="4-8"
292302
persistence_layer = DynamoDBPersistenceLayer(
293-
event_key_jmespath="[userDetail, productId]",
294303
table_name="IdempotencyTable",
304+
event_key_jmespath="[userDetail, productId]",
295305
key_attr="idempotency_key",
296306
expiry_attr="expires_at",
297307
status_attr="current_status",
298308
data_attr="result_data",
299309
validation_key_attr="validation_key"
300-
)
310+
)
301311
```
302312

303313
### Customizing boto configuration
304314
You can provide custom boto configuration or event bring your own boto3 session if required by using the `boto_config`
305315
or `boto3_session` parameters when constructing the persistence store.
306316

307317
=== "Custom session"
318+
308319
```python hl_lines="1 4 8"
309-
import boto3
310-
from aws_lambda_powertools.utilities.idempotency import DynamoDBPersistenceLayer, idempotent
311-
312-
boto3_session = boto3.session.Session()
313-
persistence_layer = DynamoDBPersistenceLayer(
314-
event_key_jmespath="body",
315-
table_name="IdempotencyTable",
316-
boto3_session=boto3_session
317-
)
320+
import boto3
321+
from aws_lambda_powertools.utilities.idempotency import DynamoDBPersistenceLayer, idempotent
322+
323+
boto3_session = boto3.session.Session()
324+
persistence_layer = DynamoDBPersistenceLayer(
325+
table_name="IdempotencyTable",
326+
event_key_jmespath="body",
327+
boto3_session=boto3_session
328+
)
318329

319-
@idempotent(persistence_store=persistence_layer)
320-
def handler(event, context):
321-
...
330+
@idempotent(persistence_store=persistence_layer)
331+
def handler(event, context):
332+
...
322333
```
323334
=== "Custom config"
335+
324336
```python hl_lines="1 4 8"
325-
from botocore.config import Config
326-
from aws_lambda_powertools.utilities.idempotency import DynamoDBPersistenceLayer, idempotent
327-
328-
boto_config = Config()
329-
persistence_layer = DynamoDBPersistenceLayer(
330-
event_key_jmespath="body",
331-
table_name="IdempotencyTable",
332-
boto_config=boto_config
333-
)
334-
335-
@idempotent(persistence_store=persistence_layer)
336-
def handler(event, context):
337-
...
337+
from botocore.config import Config
338+
from aws_lambda_powertools.utilities.idempotency import DynamoDBPersistenceLayer, idempotent
339+
340+
boto_config = Config()
341+
persistence_layer = DynamoDBPersistenceLayer(
342+
table_name="IdempotencyTable",
343+
event_key_jmespath="body",
344+
boto_config=boto_config
345+
)
346+
347+
@idempotent(persistence_store=persistence_layer)
348+
def handler(event, context):
349+
...
338350
```
339351

340352
### Bring your own persistent store
@@ -357,14 +369,15 @@ The idempotency utility can be used with the `validator` decorator. Ensure that
357369
`event_key_jmespath`.
358370

359371
=== "app.py"
372+
360373
```python hl_lines="9 10"
361374
from aws_lambda_powertools.utilities.validation import validator, envelopes
362375
from aws_lambda_powertools.utilities.idempotency.idempotency import idempotent
363376

364377
persistence_layer = DynamoDBPersistenceLayer(
365-
event_key_jmespath="[message, username]",
366378
table_name="IdempotencyTable",
367-
)
379+
event_key_jmespath="[message, username]",
380+
)
368381

369382
@validator(envelope=envelopes.API_GATEWAY_HTTP)
370383
@idempotent(persistence_store=persistence_layer)

0 commit comments

Comments
 (0)