Skip to content

Commit 0e76edb

Browse files
committed
Added sample nested test events, parent class for unwrapping, and custom logic for unwrapping some events
1 parent 58ffa89 commit 0e76edb

File tree

8 files changed

+377
-64
lines changed

8 files changed

+377
-64
lines changed

aws_lambda_powertools/utilities/data_classes/common.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -94,28 +94,35 @@ def raw_event(self) -> Dict[str, Any]:
9494
return self._data
9595

9696
class EventWrapper(DictWrapper):
97+
9798
NestedEvent = TypeVar("NestedEvent", bound=DictWrapper)
98-
@property
99+
100+
def __init__(self, data: Dict[str, Any], json_deserializer: Optional[Callable] = None):
101+
"""
102+
Parameters
103+
----------
104+
data : Dict[str, Any]
105+
Lambda Event Source Event payload
106+
json_deserializer : Callable, optional
107+
function to deserialize `str`, `bytes`, `bytearray`
108+
containing a JSON document to a Python `obj`,
109+
by default json.loads
110+
"""
111+
super().__init__(data, json_deserializer)
112+
99113
def nested_event_contents(self):
100114
for record in self["Records"]:
101-
yield record["body"]
115+
body = record['body']
116+
yield body
117+
102118

103-
# @property
104119
def decode_nested_events(self, nested_event_class: Type[NestedEvent], nested_event_content_deserializer = None):
105120
if nested_event_content_deserializer is None:
106121
nested_event_content_deserializer = self._json_deserializer
107122

108-
for content in self.nested_event_contents:
123+
for content in self.nested_event_contents():
109124
yield nested_event_class(nested_event_content_deserializer(content))
110125

111-
# @property
112-
def decode_nested_event(self, nested_event_class, nested_event_content_deserializer = None):
113-
if nested_event_content_deserializer is None:
114-
nested_event_content_deserializer = self._json_deserializer
115-
116-
for content in self.nested_event_contents:
117-
return nested_event_class(nested_event_content_deserializer(content))
118-
119126
class BaseProxyEvent(DictWrapper):
120127
@property
121128
def headers(self) -> Dict[str, str]:

aws_lambda_powertools/utilities/data_classes/event_bridge_event.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,9 @@ def detail(self) -> Dict[str, Any]:
6767
def replay_name(self) -> Optional[str]:
6868
"""Identifies whether the event is being replayed and what is the name of the replay."""
6969
return self["replay-name"]
70+
71+
def nested_event_contents(self):
72+
for record in self["detail"]:
73+
print('record', record, type(record))
74+
# print('body:', body, type(body))
75+
yield record

aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
from typing_extensions import Literal
88

9-
from aws_lambda_powertools.utilities.data_classes.common import DictWrapper
9+
from aws_lambda_powertools.utilities.data_classes.common import DictWrapper, EventWrapper
1010

1111

1212
@dataclass(repr=False, order=False, frozen=True)
@@ -274,7 +274,7 @@ def build_data_transformation_response(
274274
)
275275

276276

277-
class KinesisFirehoseEvent(DictWrapper):
277+
class KinesisFirehoseEvent(EventWrapper):
278278
"""Kinesis Data Firehose event
279279
280280
Documentation:
@@ -306,3 +306,10 @@ def region(self) -> str:
306306
def records(self) -> Iterator[KinesisFirehoseRecord]:
307307
for record in self["records"]:
308308
yield KinesisFirehoseRecord(data=record, json_deserializer=self._json_deserializer)
309+
310+
def nested_event_contents(self):
311+
for record in self["records"]:
312+
# print('record', record, type(record))
313+
# body = record[]
314+
# print('body:', body, type(body))
315+
yield record
Lines changed: 69 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,71 @@
1+
from typing import Iterator
12
import json
3+
from aws_lambda_powertools.utilities.data_classes import S3Event, SQSEvent, SNSEvent, SESEvent, EventBridgeEvent
4+
import test_events
25

3-
from aws_lambda_powertools.utilities.data_classes import S3Event, SQSEvent
4-
# from aws_lambda_powertools.utilities.data_classes.sns_event import SNSMessage
5-
from aws_lambda_powertools.utilities.data_classes import event_source
6-
7-
8-
# @event_source(data_class=SQSEvent)
9-
def lambda_handler(event: SQSEvent, context):
10-
event = SQSEvent(event)
11-
nesteds3event = event.decode_nested_events(S3Event)
12-
for record in event.records: #then how would a for loop work..
13-
nested_event = record.decode_nested_event(S3Event) #for loop must be for same events inside one event
14-
print(nested_event, nested_event)
15-
16-
# event = SQSEvent()
17-
# sns_events = event.decode_nested_events(Iterator[SNSEvent])
18-
# for sns_event in sns_events:
19-
# s3_events = sns_event.decode_nested_events(S3Event)
20-
# for s3_event in s3_events:
21-
# print(s3_event.bucket.name)
22-
23-
24-
25-
26-
event = SQSEvent({
27-
"Records": [
28-
{
29-
"messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78",
30-
"receiptHandle": "MessageReceiptHandle",
31-
"body": {
32-
"Message": "{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2023-01-01T00:00:00.000Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:123456789012:example-user\"},\"requestParameters\":{\"sourceIPAddress\":\"127.0.0.1\"},\"responseElements\":{\"x-amz-request-id\":\"example-request-id\",\"x-amz-id-2\":\"example-id\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"testConfigRule\",\"bucket\":{\"name\":\"example-bucket\",\"ownerIdentity\":{\"principalId\":\"EXAMPLE\"},\"arn\":\"arn:aws:s3:::example-bucket\"},\"object\":{\"key\":\"example-object.txt\",\"size\":1024,\"eTag\":\"example-tag\",\"versionId\":\"1\",\"sequencer\":\"example-sequencer\"}}}]}"
33-
},
34-
"attributes": {
35-
"ApproximateReceiveCount": "1",
36-
"SentTimestamp": "1523232000000",
37-
"SenderId": "123456789012",
38-
"ApproximateFirstReceiveTimestamp": "1523232000001"
39-
},
40-
"messageAttributes": {},
41-
"md5OfBody": "7b270e59b47ff90a553787216d55d91d",
42-
"eventSource": "aws:sqs",
43-
"eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:MyQueue",
44-
"awsRegion": "us-east-1"
45-
}
46-
]
47-
})
48-
49-
lambda_handler(event, {})
6+
7+
def lambda_handler_sqs_s3(event: SQSEvent = test_events.sqs_s3_event): # sqs(s3)
8+
sqs_event = SQSEvent(event)
9+
s3_event = sqs_event.decode_nested_events(S3Event)
10+
for rec in s3_event:
11+
print('rec:', rec.bucket_name)
12+
# for sqs_record in sqs_event.records:
13+
# # print('body in main:', sqs_record.body)
14+
# # s3_event = sqs_event.decode_nested_events(Iterator[S3Event]) # is this correct format?
15+
# s3_event = sqs_event.decode_nested_events(S3Event)
16+
# for rec in s3_event:
17+
# print('rec:', rec.bucket_name)
18+
# print(next(s3_event).bucket_name) # use this if not inside a for loop
19+
20+
21+
def lambda_handler_sqs_sns(event: SQSEvent = test_events.sqs_sns_event): # sqs(sns)
22+
sqs_event = SQSEvent(event)
23+
sns_event = sqs_event.decode_nested_events(SNSEvent)
24+
for rec in sns_event:
25+
print('rec:', type(rec), rec.sns_message)
26+
27+
28+
def lambda_handler_sns_s3(event: SNSEvent = test_events.sns_s3_event): # sns(s3)
29+
sns_event = SNSEvent(event)
30+
s3_event = sns_event.decode_nested_events(S3Event)
31+
for rec in s3_event:
32+
print(type(rec))
33+
print('rec:', rec.bucket_name)
34+
35+
36+
def lambda_handler_sqs_s3_multi(event: SQSEvent = test_events.sqs_s3_multi_event): # sqs(s3, s3)
37+
sqs_event = SQSEvent(event)
38+
s3_event = sqs_event.decode_nested_events(S3Event)
39+
for rec in s3_event:
40+
print('rec:', rec.bucket_name)
41+
42+
43+
def lambda_handler_sqs_sns_s3(event: SQSEvent = test_events.sqs_sns_s3_event): # sqs(sns(s3))
44+
sqs_event = SQSEvent(event)
45+
sns_event = sqs_event.decode_nested_events(SNSEvent)
46+
for rec in sns_event:
47+
print('rec:', type(rec), rec.sns_message)
48+
# s3_event = sns_event.decode_nested_events(S3Event)
49+
50+
51+
def lambda_handler_sns_ses(event: SNSEvent = test_events.sns_ses_event): # sns(ses)
52+
sns_event = SNSEvent(event)
53+
ses_event = sns_event.decode_nested_events(SESEvent)
54+
for rec in ses_event:
55+
print(type(rec))
56+
print('rec:', rec.get("mail").get('source')) #but can't do rec.mail bc no "Records" key..
57+
58+
def lambda_handler_eb_s3(event: EventBridgeEvent = test_events.eb_s3_event): # eventbridge(s3)
59+
eb_event = EventBridgeEvent(event)
60+
s3_event = eb_event.decode_nested_events(S3Event)
61+
for rec in s3_event:
62+
print(type(rec))
63+
print('rec:', rec)
64+
65+
lambda_handler_sqs_s3(test_events.sqs_s3_event)
66+
# lambda_handler_sqs_sns(test_events.sqs_sns_event) #not working bc sns doesn't have Records key
67+
lambda_handler_sns_s3(test_events.sns_s3_event)
68+
lambda_handler_sqs_s3_multi(test_events.sqs_s3_multi_event)
69+
# lambda_handler_sqs_sns_s3(test_events.sqs_sns_s3_event) #not working bc sns doesn't have Records key
70+
lambda_handler_sns_ses(test_events.sns_ses_event)
71+
# lambda_handler_eb_s3(test_events.eb_s3_event) #EB returning a str, not dict

aws_lambda_powertools/utilities/data_classes/ses_event.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Iterator, List, Optional
22

3-
from aws_lambda_powertools.utilities.data_classes.common import DictWrapper
3+
from aws_lambda_powertools.utilities.data_classes.common import DictWrapper, EventWrapper
44

55

66
class SESMailHeader(DictWrapper):
@@ -233,7 +233,7 @@ def ses(self) -> SESMessage:
233233
return SESMessage(self._data)
234234

235235

236-
class SESEvent(DictWrapper):
236+
class SESEvent(EventWrapper):
237237
"""Amazon SES to receive message event trigger
238238
239239
NOTE: There is a 30-second timeout on RequestResponse invocations.
@@ -260,3 +260,10 @@ def mail(self) -> SESMail:
260260
@property
261261
def receipt(self) -> SESReceipt:
262262
return self.record.ses.receipt
263+
264+
def nested_event_contents(self):
265+
for record in self["Records"]:
266+
# print('record', record, type(record))
267+
body = record['ses']
268+
# print('body:', body, type(body))
269+
yield body

aws_lambda_powertools/utilities/data_classes/sns_event.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,10 @@ def record(self) -> SNSEventRecord:
121121
def sns_message(self) -> str:
122122
"""Return the message for the first sns event record"""
123123
return self.record.sns.message
124+
125+
def nested_event_contents(self):
126+
for record in self["Records"]:
127+
# print('record', record, type(record))
128+
body = record['Sns']['Message']
129+
# print('body:', body, type(body))
130+
yield body

aws_lambda_powertools/utilities/data_classes/sqs_event.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,5 @@ class SQSEvent(EventWrapper):
246246

247247
@property
248248
def records(self) -> Iterator[SQSRecord]:
249-
print("in here!!")
250249
for record in self["Records"]:
251250
yield SQSRecord(data=record, json_deserializer=self._json_deserializer)

0 commit comments

Comments
 (0)