Skip to content

feat(event-sources): cache parsed json in data class #909

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Dec 21, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ def decoded_data(self) -> str:
@property
def json_data(self) -> Any:
"""Parses the data as json"""
return json.loads(self.decoded_data)
if self._json_data is None:
self._json_data = json.loads(self.decoded_data)
return self._json_data

@property
def connection_id(self) -> str:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ def user_parameters(self) -> str:
@property
def decoded_user_parameters(self) -> Dict[str, Any]:
"""Json Decoded user parameters"""
return json.loads(self.user_parameters)
if self._json_data is None:
self._json_data = json.loads(self.user_parameters)
return self._json_data


class CodePipelineActionConfiguration(DictWrapper):
Expand Down
5 changes: 4 additions & 1 deletion aws_lambda_powertools/utilities/data_classes/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class DictWrapper:

def __init__(self, data: Dict[str, Any]):
self._data = data
self._json_data: Optional[Any] = None

def __getitem__(self, key: str) -> Any:
return self._data[key]
Expand Down Expand Up @@ -65,7 +66,9 @@ def body(self) -> Optional[str]:
@property
def json_body(self) -> Any:
"""Parses the submitted body as json"""
return json.loads(self.decoded_body)
if self._json_data is None:
self._json_data = json.loads(self.decoded_body)
return self._json_data

@property
def decoded_body(self) -> str:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ def decoded_data(self) -> str:
@property
def json_data(self) -> Any:
"""Parses the data as json"""
return json.loads(self.decoded_data)
if self._json_data is None:
self._json_data = json.loads(self.decoded_data)
return self._json_data


class RabbitMQEvent(DictWrapper):
Expand Down
2 changes: 2 additions & 0 deletions tests/functional/data_classes/test_amazon_mq.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def test_active_mq_event():
messages = list(event.messages)
message = messages[1]
assert message.json_data["timeout"] == 0
assert message.json_data["data"] == "CZrmf0Gw8Ov4bqLQxD4E"


def test_rabbit_mq_event():
Expand All @@ -47,6 +48,7 @@ def test_rabbit_mq_event():
assert message.data is not None
assert message.decoded_data is not None
assert message.json_data["timeout"] == 0
assert message.json_data["data"] == "CZrmf0Gw8Ov4bqLQxD4E"

assert isinstance(message, RabbitMessage)
properties = message.basic_properties
Expand Down
14 changes: 10 additions & 4 deletions tests/functional/test_data_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ def test_cognito_pre_token_generation_trigger_event():
claims_override_details.set_group_configuration_groups_to_override(expected_groups)
assert claims_override_details.group_configuration.groups_to_override == expected_groups
assert event["response"]["claimsOverrideDetails"]["groupOverrideDetails"]["groupsToOverride"] == expected_groups
claims_override_details = event.response.claims_override_details
assert claims_override_details["groupOverrideDetails"]["groupsToOverride"] == expected_groups

claims_override_details.set_group_configuration_iam_roles_to_override(["role"])
assert claims_override_details.group_configuration.iam_roles_to_override == ["role"]
Expand Down Expand Up @@ -1054,6 +1056,7 @@ def test_base_proxy_event_json_body():
data = {"message": "Foo"}
event = BaseProxyEvent({"body": json.dumps(data)})
assert event.json_body == data
assert event.json_body["message"] == "Foo"


def test_base_proxy_event_decode_body_key_error():
Expand Down Expand Up @@ -1084,7 +1087,7 @@ def test_base_proxy_event_json_body_with_base64_encoded_data():
event = BaseProxyEvent({"body": encoded_data, "isBase64Encoded": True})

# WHEN calling json_body
# THEN then base64 decode and json load
# THEN base64 decode and json load
assert event.json_body == data


Expand Down Expand Up @@ -1120,7 +1123,8 @@ def test_kinesis_stream_event_json_data():
json_value = {"test": "value"}
data = base64.b64encode(bytes(json.dumps(json_value), "utf-8")).decode("utf-8")
event = KinesisStreamEvent({"Records": [{"kinesis": {"data": data}}]})
assert next(event.records).kinesis.data_as_json() == json_value
record = next(event.records)
assert record.kinesis.data_as_json() == json_value


def test_alb_event():
Expand Down Expand Up @@ -1392,9 +1396,11 @@ def test_code_pipeline_event_decoded_data():
event = CodePipelineJobEvent(load_event("codePipelineEventData.json"))

assert event.data.continuation_token is None
decoded_params = event.data.action_configuration.configuration.decoded_user_parameters
configuration = event.data.action_configuration.configuration
decoded_params = configuration.decoded_user_parameters
assert decoded_params == event.decoded_user_parameters
assert "VALUE" == decoded_params["KEY"]
assert decoded_params["KEY"] == "VALUE"
assert configuration.decoded_user_parameters["KEY"] == "VALUE"

assert "my-pipeline-SourceArtifact" == event.data.input_artifacts[0].name

Expand Down