Skip to content

Commit 7df82ff

Browse files
author
Michael Brewer
committed
feat(idempotent): Add support for jmespath_options
Like for the validator, idempotent utility should allow for extracting an idempotent key using custom functions
1 parent d7b4afe commit 7df82ff

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

Diff for: aws_lambda_powertools/utilities/idempotency/persistence/base.py

+12-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
IdempotencyItemAlreadyExistsError,
2020
IdempotencyValidationError,
2121
)
22+
from aws_lambda_powertools.utilities.validation.jmespath_functions import PowertoolsFunctions
2223

2324
logger = logging.getLogger(__name__)
2425

@@ -112,6 +113,7 @@ def __init__(
112113
use_local_cache: bool = False,
113114
local_cache_max_items: int = 256,
114115
hash_function: str = "md5",
116+
jmespath_options: Dict = None,
115117
) -> None:
116118
"""
117119
Initialize the base persistence layer
@@ -130,6 +132,8 @@ def __init__(
130132
Max number of items to store in local cache, by default 1024
131133
hash_function: str, optional
132134
Function to use for calculating hashes, by default md5.
135+
jmespath_options : Dict
136+
Alternative JMESPath options to be included when filtering expr
133137
"""
134138
self.event_key_jmespath = event_key_jmespath
135139
if self.event_key_jmespath:
@@ -143,6 +147,9 @@ def __init__(
143147
self.validation_key_jmespath = jmespath.compile(payload_validation_jmespath)
144148
self.payload_validation_enabled = True
145149
self.hash_function = getattr(hashlib, hash_function)
150+
if not jmespath_options:
151+
jmespath_options = {"custom_functions": PowertoolsFunctions()}
152+
self.jmespath_options = jmespath_options
146153

147154
def _get_hashed_idempotency_key(self, lambda_event: Dict[str, Any]) -> str:
148155
"""
@@ -160,8 +167,12 @@ def _get_hashed_idempotency_key(self, lambda_event: Dict[str, Any]) -> str:
160167
161168
"""
162169
data = lambda_event
170+
163171
if self.event_key_jmespath:
164-
data = self.event_key_compiled_jmespath.search(lambda_event)
172+
data = self.event_key_compiled_jmespath.search(
173+
lambda_event, options=jmespath.Options(**self.jmespath_options)
174+
)
175+
165176
return self._generate_hash(data)
166177

167178
def _get_hashed_payload(self, lambda_event: Dict[str, Any]) -> str:

Diff for: tests/functional/idempotency/test_idempotency.py

+22
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import copy
2+
import json
23
import sys
34

5+
import jmespath
46
import pytest
57
from botocore import stub
68

@@ -638,3 +640,23 @@ def test_delete_from_cache_when_empty(persistence_store):
638640
except KeyError:
639641
# THEN we should not get a KeyError
640642
pytest.fail("KeyError should not happen")
643+
644+
645+
@pytest.mark.parametrize("persistence_store", [{"use_local_cache": True}], indirect=True)
646+
def test_jmespath_with_powertools_json(persistence_store):
647+
# GIVEN an event_key_jmespath with powertools_json custom function
648+
persistence_store.event_key_jmespath = "[requestContext.authorizer.claims.sub, powertools_json(body).id]"
649+
persistence_store.event_key_compiled_jmespath = jmespath.compile(persistence_store.event_key_jmespath)
650+
sub_attr_value = "cognito_user"
651+
key_attr_value = "some_key"
652+
expected_value = [sub_attr_value, key_attr_value]
653+
api_gateway_proxy_event = {
654+
"requestContext": {"authorizer": {"claims": {"sub": sub_attr_value}}},
655+
"body": json.dumps({"id": key_attr_value}),
656+
}
657+
658+
# WHEN calling _get_hashed_idempotency_key
659+
result = persistence_store._get_hashed_idempotency_key(api_gateway_proxy_event)
660+
661+
# THEN the hashed idempotency key should match the extracted values generated hash
662+
assert result == persistence_store._generate_hash(expected_value)

0 commit comments

Comments
 (0)