Description
Key information
- RFC PR: feat(trigger): data class and helper functions for lambda trigger events #159
- Area: Utilities
- Meet tenets: Yes
Summary
NOTE: This solution should not have any additional dependencies and be as lightweight as possible.
Create a set of data classes for all of the common AWS Event Triggers these data classes will include:
- Docstrings for each of the fields
- Type hinting and code completion
- Later support for validation via the Json schema PR
- Helper functions to handle some of the decoding (CloudwatchLogsEvent decoding)
- Define enums where necessary
Motivation
When defining a new lambda you start with a handler method with event Dict[str, Any]
and LambdaContext
context parameter. You will then have to find the corresponding documentation for the event structure and field type etc..
Proposal
Each Lambda trigger event there is a corresponding typed data class which doc strings extracted from the AWS documentation, some helper methods to updating values as well as decoding any embedded data. In the test suite there is alot a series of example trigger events.
CloudWatchLogsEvent example usage:
from aws_lambda_powertools.utilities.trigger import CloudWatchLogsEvent
def handler(event: Dict[str, Any], context: LambdaContext):
# CloudWatchLogsEvent provides a typed data class with a method to decode gzipped log messages
decoded_data = CloudWatchLogsEvent(event).decode_cloud_watch_logs_data()
# CloudWatchLogsDecodedData is another typed data class with docstrings and getters
for log_event in decoded_data.log_events:
handle_log_message(log_event.message)
PreTokenGenerationTriggerEvent example usage:
def handler(event: Dict[str, Any], context: LambdaContext) -> Dict[str, Any]:
# PreTokenGenerationTriggerEvent data class includes docstrings and helper methods
pre_token_event = PreTokenGenerationTriggerEvent(event)
claims_override_details = pre_token_event.response.claims_override_details
if pre_token_event.user_name == "SpecialUser":
# ClaimsOverrideDetails has convenient setters
claims_override_details.claims_to_suppress = ["Email"]
claims_override_details.claims_to_add_or_override = {"attribute": "value"}
if "SpecialGroup" in pre_token_event.request.group_configuration.groups_to_override:
# A setter method for only part of groupOverrideDetails
claims_override_details.set_group_configuration_preferred_role("preferred_value")
# Updated are made to the original dict
return event
Example screenshot of the docs:
List of initial trigger events to support:
- API Gateway Poxy V1 and V2 events
- CloudWatch log event with decoding of the gzipped logs
- Cognito user pool events
- DynamoDB stream events
- Event bridge
- Kinesis stream events
- S3 event notifications
- SES events
- SNS events
- SQS events
Drawbacks
Why should we not do this?
This will include alot of extra code to maintain and we will have to keep it in sync when new event triggers are created. However all new Lambda users will have to do the same.
Do we need additional dependencies? Impact performance/package size?
No extra dependencies are needed
Rationale and alternatives
- What other designs have been considered? Why not them?
There are alternatives that include a large set of dependencies, and will still need the similar amount of work (like tracking down example events and documentation)
Unresolved questions
Mapping for keys like type
, id
, from
etc.. to the corresponding getter method like get_id
Optional, stash area for topics that need further development e.g. TBD
Add integration for validation code from other PRs
Metadata
Metadata
Assignees
Type
Projects
Status