RFC: Generic way to handle nested events on Event Source Data Classes #6063
Replies: 5 comments
-
|
Hello @rafaelgsr! This is fantastic because it solves a need that we have to create events every time we want to unwrap nested events. That way, we make it linear and very easy. Let's analyze this RFC until next week, ok? |
Beta Was this translation helpful? Give feedback.
-
|
Update: we're still prioritizing Pydantic v2 POC as it impacts a larger set of customers. We'll get back to review this RFC as soon as we're able. |
Beta Was this translation helpful? Give feedback.
-
|
Hello @rafaelgsr, thank you for writing this RFC, this will be extremely useful to have! I would love to work with you to get the RFC and UX finalized. Some questions/comments:
Should we consider adding the methods for some of the most popular outlier events for how they would return the right content? This would probably help users out as they would quickly know how to get the right info.
I think having a method to return only Record[0] is a great idea! We could definitely do that in addition to having a method for the Iterable version. Was the potential challenge to do this or not? Or did I misread something in that section? |
Beta Was this translation helpful? Give feedback.
-
|
Discussed offline with @rafaelgsr and got my questions clarified:
The original comment was more saying we should implement some way for the
Yes, we should implement both a method to get |
Beta Was this translation helpful? Give feedback.
-
|
Hello @rafaelgsr and @seshubaws! I think we can create a PoC and discuss this implementation, what do you think? I'm sure we'll have a lot of things to discuss about the best API design, user experience, plural vs singular and others when this code is created. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Is this related to an existing feature request or issue?
#2348
Which Powertools for AWS Lambda (Python) utility does this relate to?
Event Source Data Classes
Summary
This RFC proposes the implementation of a generic way to decode/unwrap nested events in Event Source Data Classes. When handling events, it may happen that the
eventpassed into thelambda_handlerwraps another event that was originated on a different resource. For example, anSQSEventthat wraps an event originated on Amazon S3.The goal is to simplify how developers access and handle nested events, even when they are multi-level.
Use case
At this point, when the developer decorates the
lambda_handlerwith@event_source, they declare thedata_classfor the event that invoked the Lambda function. If this event wraps another event - or a chain of events originated somewhere else, the developer has to manually instantiate new objects using the appropriate Event Source Data Classes.This was partially addressed by #2348, but it covers only
SQSEventswrappingS3EventsandSNSEvents. In practice, there can be dozens of different combinations of events, with more to come as AWS adds new features and use cases to the services. Moreover, nested events as such may be multi-level: S3 -> SNS -> SQS.Implementing on Powertools each possible combination is not feasible, therefore I'm proposing a generic implementation that would also facilitate how developers are using this utility. With this approach, the developer would be able to traverse the chain of events until the root event, and still have access to relevant attributes from the parent i.e., the event wrapper.
Proposal
The proposal is to have a class called
EventWrapperextendingDictWrapper. This new class has the generic implementation to decode/unwrap nested events. Each relevant Event Source Data Class, such asSNSEvent, extendsEventWrapperinstead ofDictWrapper. With that,SNSEvent(and the other relevant data classes) inherits a method calleddecode_nested_events(ordecode_nested_eventin singular - I'll elaborate on the singular vs. plural further down on the Potential Challenges section).The method
decode_nested_eventsacceptsnested_event_class(the wrapped data class), and optionally thenested_event_content_deserializer(the implementation of the nested content deserializer, that can be in the format of JSON, Base64, GZIP, etc.). If nonested_event_content_deserializeris passed, the default isself._json_deserializer. For the latter, I intend to add implementations for the most common deserializers inEventWrapper. An example of that is compressed JSON CloudWatch Logs data coming inKinesisStreamEvents.Here is a mock implementation (with no types yet):
I'm also planning to add a reference to the parent event into the nested event, so that the chain of events can be traversed back and forth. Another shortcut that I'm planning to add is a direct access to the root event. For the chain S3 -> SNS -> SQS, there would be a method
decode_root_eventto return anS3Eventdirectly from theSQSEvent.Here is a mock implementation of
nested_event_contents:The implementation of
nested_event_contentsassumes thatselfhas an attribute calledRecords, and eachRecordhas the attributebodywith the actual content of the nested event. At this point, I assume this is the most common use case, but I know there are exceptions, hence this mock implementation may change. Nevertheless, the outliers have the possibility to override just this method to return the right content. An example of that isSNSEventthat would override that to returnself.sns_messageinstead.Note: Based on the analysis I've done so far, we can implement the proposal on this RFC without breaking changes.
Out of scope
Nothing so far.
Potential challenges
Plural vs. singular
One implementation challenge that affects the UX is the JSON format of these events. For instance, the JSON object representing an SQS event has the attribute
Records. Within eachRecord, there is a nested event. As a consequence, using the same example,SQSEventcontains a collection of nested events instead of just one. Note that in the sample code above, I return anIteratorinstead of just one event because of that.In practice, there are multiple use cases that we empirically know that the event contains just one single
Record. With that in mind,EventWrappercould provide a method calleddecode_nested_event(in singular) to allow decoding the nested evant in theRecord[0]. This aims to allow an experience as such:event.decode_nested_event(SNSEvent).decode_nested_event(S3Event)to get direct access to theS3Eventwrapped within anSNSEventwith is wrapped within anSQSEvent.For the
Iterableversion (plural), the UX would be similar to (consider thateventis an instance ofSQSEvent):Dependencies and Integrations
No response
Alternative solutions
No response
Acknowledgment
Beta Was this translation helpful? Give feedback.
All reactions