Expected Behaviour
payload_validation_jmespath should accept the same JMESPath functions as event_key_jmespath. The idempotency docs say powertools_json, powertools_base64 and powertools_base64_gzip "are also available to use in this utility".
With the snippet below the handler should run and return {"statusCode": 200, "body": "charged"}. A later call with the same order_id and a changed amount should raise IdempotencyValidationError.
Current Behaviour
Every call fails before the handler runs. What I get:
aws_lambda_powertools.utilities.idempotency.exceptions.IdempotencyPersistenceLayerError: Failed to save in progress record to idempotency store - (Unknown function: powertools_json())
This hits API Gateway handlers, where the payload is a JSON string in body. The docs use powertools_json(body) for the idempotency key, and payload validation is how you catch a changed amount. Use both and no request gets through.
Only the key search passes jmespath_options:
|
data = self.event_key_compiled_jmespath.search( |
|
data, |
|
options=jmespath.Options(**(self.jmespath_options or {})), |
|
) |
The payload search doesn't pass any options, so neither the Powertools functions nor custom functions from jmespath_options exist there:
|
data = self.validation_key_jmespath.search(data) |
Code snippet
import json
from aws_lambda_powertools.utilities.idempotency import (
DynamoDBPersistenceLayer,
IdempotencyConfig,
idempotent,
)
persistence_layer = DynamoDBPersistenceLayer(table_name="IdempotencyTable")
config = IdempotencyConfig(
event_key_jmespath="powertools_json(body).order_id",
payload_validation_jmespath="powertools_json(body).amount",
)
@idempotent(config=config, persistence_store=persistence_layer)
def lambda_handler(event, context):
return {"statusCode": 200, "body": "charged"}
lambda_handler({"body": json.dumps({"order_id": "o-1", "amount": 100})}, None)
Possible Solution
Pass the same options in _get_hashed_payload:
data = self.validation_key_jmespath.search(
data,
options=jmespath.Options(**(self.jmespath_options or {})),
)
I've got the fix with functional tests and will open a PR.
Steps to Reproduce
Run the snippet on develop (f872ab8) with an AWS region set. It fails while hashing the payload, before any DynamoDB call, so you don't need a table or credentials. v3.35.0 has the same line.
Powertools for AWS Lambda (Python) version
3.35.0
AWS Lambda function runtime
3.13
Packaging format used
PyPi
Expected Behaviour
payload_validation_jmespathshould accept the same JMESPath functions asevent_key_jmespath. The idempotency docs saypowertools_json,powertools_base64andpowertools_base64_gzip"are also available to use in this utility".With the snippet below the handler should run and return
{"statusCode": 200, "body": "charged"}. A later call with the sameorder_idand a changedamountshould raiseIdempotencyValidationError.Current Behaviour
Every call fails before the handler runs. What I get:
This hits API Gateway handlers, where the payload is a JSON string in
body. The docs usepowertools_json(body)for the idempotency key, and payload validation is how you catch a changed amount. Use both and no request gets through.Only the key search passes
jmespath_options:powertools-lambda-python/aws_lambda_powertools/utilities/idempotency/persistence/base.py
Lines 114 to 117 in f872ab8
The payload search doesn't pass any options, so neither the Powertools functions nor custom functions from
jmespath_optionsexist there:powertools-lambda-python/aws_lambda_powertools/utilities/idempotency/persistence/base.py
Line 160 in f872ab8
Code snippet
Possible Solution
Pass the same options in
_get_hashed_payload:I've got the fix with functional tests and will open a PR.
Steps to Reproduce
Run the snippet on
develop(f872ab8) with an AWS region set. It fails while hashing the payload, before any DynamoDB call, so you don't need a table or credentials. v3.35.0 has the same line.Powertools for AWS Lambda (Python) version
3.35.0
AWS Lambda function runtime
3.13
Packaging format used
PyPi