generated from amazon-archives/__template_MIT-0
- Notifications
You must be signed in to change notification settings - Fork 455
feat: Advanced parser utility (pydantic) #118
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
Changes from 1 commit
Commits
Show all changes
21 commits Select commit Hold shift + click to select a range
913e310 feat: RFC: Validate incoming and outgoing events utility #95
3f9865a Merge branch 'develop' into pydantic
heitorlessa 7c55154 Merge branch 'develop' into pydantic
heitorlessa d50e261 improv: refactor structure to fit with utilities
heitorlessa bce7aab added SQS schema & tests and sns skeleton
dc64b8a Add validate function, fix flake8 issues
637a696 refactor: change to advanced parser
f986512 Merge branch 'develop' of github.com:risenberg-cyberark/aws-lambda-po…
3418767 refactor: pydantic as optional dependancy, remove lambdaContext
47cd711 feat: Advanced parser utility (pydantic)
b7cb539 Merge branch 'develop' of github.com:risenberg-cyberark/aws-lambda-po…
0edaf9a Merge branch 'develop' of github.com:risenberg-cyberark/aws-lambda-po…
6ae1769 fix: add only pydantic (+1 squashed commit)
19a597f Revert "fix: remove jmespath extras in Make"
heitorlessa 57b6d23 poetry update (+2 squashed commits)
heitorlessa ad80cd3 chore: remove kitchen sink example
heitorlessa f1d39e1 chore: remove dev deps from example project
heitorlessa 38e1582 fix: poetry update + pydantic, typing_extensions as optional
b1b7fb3 Merge branch 'develop' into pydantic
ran-isenberg a47056f fix: reduce complexity of dynamo envelope
10d0079 fix: CR fixes
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
feat: Advanced parser utility (pydantic)
- Loading branch information
There are no files selected for viewing
16 changes: 4 additions & 12 deletions 16 aws_lambda_powertools/utilities/advanced_parser/__init__.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,6 @@ | ||
| """Validation utility | ||
| """Advanced parser utility | ||
| """ | ||
| from .envelopes import DynamoDBEnvelope, EventBridgeEnvelope, SnsEnvelope, SqsEnvelope, UserEnvelope | ||
| from .validator import validate, validator | ||
| from .envelopes import Envelope, InvalidEnvelopeError, parse_envelope | ||
| from .parser import parser | ||
| | ||
| __all__ = [ | ||
| "UserEnvelope", | ||
| "DynamoDBEnvelope", | ||
| "EventBridgeEnvelope", | ||
| "SnsEnvelope", | ||
| "SqsEnvelope", | ||
| "validate", | ||
| "validator", | ||
| ] | ||
| __all__ = ["InvalidEnvelopeError", "Envelope", "parse_envelope", "parser"] |
8 changes: 2 additions & 6 deletions 8 aws_lambda_powertools/utilities/advanced_parser/envelopes/__init__.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,3 @@ | ||
| from .base import UserEnvelope | ||
| from .dynamodb import DynamoDBEnvelope | ||
| from .event_bridge import EventBridgeEnvelope | ||
| from .sns import SnsEnvelope | ||
| from .sqs import SqsEnvelope | ||
| from .envelopes import Envelope, InvalidEnvelopeError, parse_envelope | ||
| | ||
| __all__ = ["UserEnvelope", "DynamoDBEnvelope", "EventBridgeEnvelope", "SqsEnvelope", "SnsEnvelope"] | ||
| __all__ = ["InvalidEnvelopeError", "Envelope", "parse_envelope"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| | @@ -8,35 +8,26 @@ | |
| | ||
| | ||
| class BaseEnvelope(ABC): | ||
| def _parse_user_dict_schema(self, user_event: Dict[str, Any], inbound_schema_model: BaseModel) -> Any: | ||
| def _parse_user_dict_schema(self, user_event: Dict[str, Any], schema: BaseModel) -> Any: | ||
| logger.debug("parsing user dictionary schema") | ||
| try: | ||
| return inbound_schema_model(**user_event) | ||
| return schema(**user_event) | ||
| except (ValidationError, TypeError): | ||
| logger.exception("Validation exception while extracting user custom schema") | ||
| raise | ||
| | ||
| def _parse_user_json_string_schema(self, user_event: str, inbound_schema_model: BaseModel) -> Any: | ||
| def _parse_user_json_string_schema(self, user_event: str, schema: BaseModel) -> Any: | ||
| logger.debug("parsing user dictionary schema") | ||
| if inbound_schema_model == str: | ||
| if schema == str: | ||
| logger.debug("input is string, returning") | ||
| return user_event | ||
| logger.debug("trying to parse as json encoded string") | ||
| try: | ||
| return inbound_schema_model.parse_raw(user_event) | ||
| return schema.parse_raw(user_event) | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. docs: could you add a comment as a context for parse_raw for non-pydantic maintainers? | ||
| except (ValidationError, TypeError): | ||
| logger.exception("Validation exception while extracting user custom schema") | ||
| raise | ||
| | ||
| @abstractmethod | ||
| def parse(self, event: Dict[str, Any], inbound_schema_model: BaseModel) -> Any: | ||
| def parse(self, event: Dict[str, Any], schema: BaseModel): | ||
| return NotImplemented | ||
| | ||
| | ||
| class UserEnvelope(BaseEnvelope): | ||
| def parse(self, event: Dict[str, Any], inbound_schema_model: BaseModel) -> Any: | ||
| try: | ||
| return inbound_schema_model(**event) | ||
| except (ValidationError, TypeError): | ||
| logger.exception("Validation exception received from input user custom envelopes event") | ||
| raise | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions 42 aws_lambda_powertools/utilities/advanced_parser/envelopes/envelopes.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| import logging | ||
| from enum import Enum | ||
| from typing import Any, Dict | ||
| | ||
| from pydantic import BaseModel | ||
| | ||
| from aws_lambda_powertools.utilities.advanced_parser.envelopes.base import BaseEnvelope | ||
| from aws_lambda_powertools.utilities.advanced_parser.envelopes.dynamodb import DynamoDBEnvelope | ||
| from aws_lambda_powertools.utilities.advanced_parser.envelopes.event_bridge import EventBridgeEnvelope | ||
| from aws_lambda_powertools.utilities.advanced_parser.envelopes.sqs import SqsEnvelope | ||
| | ||
| logger = logging.getLogger(__name__) | ||
| | ||
| | ||
| """Built-in envelopes""" | ||
| | ||
| | ||
| class Envelope(str, Enum): | ||
| SQS = "sqs" | ||
| EVENTBRIDGE = "eventbridge" | ||
| DYNAMODB_STREAM = "dynamodb_stream" | ||
| | ||
| | ||
| class InvalidEnvelopeError(Exception): | ||
| """Input envelope is not one of the Envelope enum values""" | ||
| | ||
| | ||
| # enum to BaseEnvelope handler class | ||
| __ENVELOPE_MAPPING = { | ||
| Envelope.SQS: SqsEnvelope, | ||
| Envelope.DYNAMODB_STREAM: DynamoDBEnvelope, | ||
| Envelope.EVENTBRIDGE: EventBridgeEnvelope, | ||
| } | ||
| | ||
| | ||
| def parse_envelope(event: Dict[str, Any], envelope: Envelope, schema: BaseModel): | ||
| envelope_handler: BaseEnvelope = __ENVELOPE_MAPPING.get(envelope) | ||
| if envelope_handler is None: | ||
| logger.exception("envelope must be an instance of Envelope enum") | ||
| raise InvalidEnvelopeError("envelope must be an instance of Envelope enum") | ||
| logger.debug(f"Parsing and validating event schema, envelope={str(envelope.value)}") | ||
| return envelope_handler().parse(event=event, schema=schema) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
19 changes: 0 additions & 19 deletions 19 aws_lambda_powertools/utilities/advanced_parser/envelopes/sns.py
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| import logging | ||
| from typing import Any, Callable, Dict, Optional | ||
| | ||
| from pydantic import BaseModel, ValidationError | ||
| | ||
| from aws_lambda_powertools.middleware_factory import lambda_handler_decorator | ||
| from aws_lambda_powertools.utilities.advanced_parser.envelopes import Envelope, parse_envelope | ||
| | ||
| logger = logging.getLogger(__name__) | ||
| | ||
| | ||
| @lambda_handler_decorator | ||
| def parser( | ||
| handler: Callable[[Dict, Any], Any], | ||
| event: Dict[str, Any], | ||
| context: Dict[str, Any], | ||
| schema: BaseModel, | ||
| envelope: Optional[Envelope] = None, | ||
| ) -> Any: | ||
| """Decorator to conduct advanced parsing & validation for lambda handlers events | ||
| | ||
| As Lambda follows (event, context) signature we can remove some of the boilerplate | ||
| and also capture any exception any Lambda function throws as metadata. | ||
| Event will be the parsed & validated BaseModel pydantic object of the input type "schema" | ||
| | ||
| Example | ||
| ------- | ||
| **Lambda function using validation decorator** | ||
| | ||
| @parser(schema=MyBusiness, envelope=envelopes.EVENTBRIDGE) | ||
| def handler(event: inbound_schema_model , context: LambdaContext): | ||
| ... | ||
| | ||
| Parameters | ||
| ---------- | ||
| todo add | ||
heitorlessa marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| | ||
| Raises | ||
| ------ | ||
| err | ||
| TypeError or pydantic.ValidationError or any exception raised by the lambda handler itself | ||
| """ | ||
| lambda_handler_name = handler.__name__ | ||
| parsed_event = None | ||
| if envelope is None: | ||
| try: | ||
| logger.debug("Parsing and validating event schema, no envelope is used") | ||
| parsed_event = schema(**event) | ||
| except (ValidationError, TypeError): | ||
| logger.exception("Validation exception received from input event") | ||
| raise | ||
| else: | ||
| parsed_event = parse_envelope(event, envelope, schema) | ||
| | ||
| logger.debug(f"Calling handler {lambda_handler_name}") | ||
| handler(parsed_event, context) | ||
heitorlessa marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
9 changes: 5 additions & 4 deletions 9 aws_lambda_powertools/utilities/advanced_parser/schemas/__init__.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,12 @@ | ||
| from .dynamodb import DynamoDBSchema | ||
| from .dynamodb import DynamoDBSchema, DynamoRecordSchema, DynamoScheme | ||
| from .event_bridge import EventBridgeSchema | ||
| from .sns import SnsSchema | ||
| from .sqs import SqsSchema | ||
| from .sqs import SqsRecordSchema, SqsSchema | ||
| | ||
| __all__ = [ | ||
| "DynamoDBSchema", | ||
| "EventBridgeSchema", | ||
| "SnsSchema", | ||
| "DynamoScheme", | ||
| "DynamoRecordSchema", | ||
| "SqsSchema", | ||
| "SqsRecordSchema", | ||
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
5 changes: 3 additions & 2 deletions 5 aws_lambda_powertools/utilities/advanced_parser/schemas/event_bridge.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,15 +1,16 @@ | ||
| from datetime import datetime | ||
| from typing import Any, Dict, List | ||
| | ||
| from pydantic import BaseModel | ||
| from pydantic import BaseModel, Field | ||
| | ||
| | ||
| class EventBridgeSchema(BaseModel): | ||
| version: str | ||
| id: str # noqa: A003,VNE003 | ||
| source: str | ||
| account: int | ||
| account: str | ||
| time: datetime | ||
| region: str | ||
| resources: List[str] | ||
| detailtype: str = Field(None, alias="detail-type") | ||
| detail: Dict[str, Any] |
5 changes: 0 additions & 5 deletions 5 aws_lambda_powertools/utilities/advanced_parser/schemas/sns.py
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.