From 7650c2745ff35eadb99bd78273b8031540689c6a Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Tue, 27 Jun 2023 11:50:16 +0100 Subject: [PATCH 1/5] feature: adding vpc lattice parser and envelope --- .../utilities/parser/envelopes/__init__.py | 2 + .../utilities/parser/envelopes/vpc_lattice.py | 33 ++++++++++++ .../utilities/parser/models/__init__.py | 2 + .../utilities/parser/models/vpc_lattice.py | 12 +++++ docs/utilities/parser.md | 2 + tests/functional/parser/schemas.py | 5 ++ tests/unit/parser/test_vpc_lattice.py | 53 +++++++++++++++++++ 7 files changed, 109 insertions(+) create mode 100644 aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py create mode 100644 aws_lambda_powertools/utilities/parser/models/vpc_lattice.py create mode 100644 tests/unit/parser/test_vpc_lattice.py diff --git a/aws_lambda_powertools/utilities/parser/envelopes/__init__.py b/aws_lambda_powertools/utilities/parser/envelopes/__init__.py index 0f985f29d88..cbac331089b 100644 --- a/aws_lambda_powertools/utilities/parser/envelopes/__init__.py +++ b/aws_lambda_powertools/utilities/parser/envelopes/__init__.py @@ -10,6 +10,7 @@ from .lambda_function_url import LambdaFunctionUrlEnvelope from .sns import SnsEnvelope, SnsSqsEnvelope from .sqs import SqsEnvelope +from .vpc_lattice import VPCLatticeEnvelope __all__ = [ "ApiGatewayEnvelope", @@ -25,4 +26,5 @@ "SqsEnvelope", "KafkaEnvelope", "BaseEnvelope", + "VPCLatticeEnvelope", ] diff --git a/aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py b/aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py new file mode 100644 index 00000000000..7a168eac0ee --- /dev/null +++ b/aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py @@ -0,0 +1,33 @@ +import logging +from typing import Any, Dict, Optional, Type, Union + +from ..models import VPCLatticeModel +from ..types import Model +from .base import BaseEnvelope + +logger = logging.getLogger(__name__) + + +class VPCLatticeEnvelope(BaseEnvelope): + """VPC Lattice envelope to extract data within body key""" + + def parse(self, data: Optional[Union[Dict[str, Any], Any]], model: Type[Model]) -> Optional[Model]: + """Parses data found with model provided + + Parameters + ---------- + data : Dict + Lambda event to be parsed + model : Type[Model] + Data model provided to parse after extracting data using envelope + + Returns + ------- + Any + Parsed detail payload with model provided + """ + logger.debug(f"Parsing incoming data with VPC Lattice model {VPCLatticeModel}") + parsed_envelope: VPCLatticeModel = VPCLatticeModel.parse_obj(data) + print(parsed_envelope.body) + logger.debug(f"Parsing event payload in `detail` with {model}") + return self._parse(data=parsed_envelope.body, model=model) diff --git a/aws_lambda_powertools/utilities/parser/models/__init__.py b/aws_lambda_powertools/utilities/parser/models/__init__.py index 952280a519c..2f746da1bb8 100644 --- a/aws_lambda_powertools/utilities/parser/models/__init__.py +++ b/aws_lambda_powertools/utilities/parser/models/__init__.py @@ -84,6 +84,7 @@ ) from .sns import SnsModel, SnsNotificationModel, SnsRecordModel from .sqs import SqsAttributesModel, SqsModel, SqsMsgAttributeModel, SqsRecordModel +from .vpc_lattice import VPCLatticeModel __all__ = [ "APIGatewayProxyEventV2Model", @@ -157,4 +158,5 @@ "CloudFormationCustomResourceDeleteModel", "CloudFormationCustomResourceCreateModel", "CloudFormationCustomResourceBaseModel", + "VPCLatticeModel", ] diff --git a/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py b/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py new file mode 100644 index 00000000000..dd50ed9960d --- /dev/null +++ b/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py @@ -0,0 +1,12 @@ +from typing import Dict, Type, Union + +from pydantic import BaseModel + + +class VPCLatticeModel(BaseModel): + method: str + raw_path: str + body: Union[str, Type[BaseModel]] + is_base64_encoded: bool + headers: Dict[str, str] + query_string_parameters: Dict[str, str] diff --git a/docs/utilities/parser.md b/docs/utilities/parser.md index 0e25f9441a4..9df1a957c10 100644 --- a/docs/utilities/parser.md +++ b/docs/utilities/parser.md @@ -180,6 +180,7 @@ Parser comes with the following built-in models: | **SesModel** | Lambda Event Source payload for Amazon Simple Email Service | | **SnsModel** | Lambda Event Source payload for Amazon Simple Notification Service | | **SqsModel** | Lambda Event Source payload for Amazon SQS | +| **VPCLatticeModel** | Lambda Event Source payload for Amazon VPC Lattice | #### Extending built-in models @@ -336,6 +337,7 @@ Parser comes with the following built-in envelopes, where `Model` in the return | **ApiGatewayV2Envelope** | 1. Parses data using `APIGatewayProxyEventV2Model`.
2. Parses `body` key using your model and returns it. | `Model` | | **LambdaFunctionUrlEnvelope** | 1. Parses data using `LambdaFunctionUrlModel`.
2. Parses `body` key using your model and returns it. | `Model` | | **KafkaEnvelope** | 1. Parses data using `KafkaRecordModel`.
2. Parses `value` key using your model and returns it. | `Model` | +| **VPCLatticeEnvelope** | 1. Parses data using `VPCLatticeModel`.
2. Parses `value` key using your model and returns it. | `Model` | #### Bringing your own envelope diff --git a/tests/functional/parser/schemas.py b/tests/functional/parser/schemas.py index 907deb40aa0..117086eb135 100644 --- a/tests/functional/parser/schemas.py +++ b/tests/functional/parser/schemas.py @@ -99,3 +99,8 @@ class MyLambdaKafkaBusiness(BaseModel): class MyKinesisFirehoseBusiness(BaseModel): Hello: str + + +class myVPCLatticeBusiness(BaseModel): + username: str + name: str diff --git a/tests/unit/parser/test_vpc_lattice.py b/tests/unit/parser/test_vpc_lattice.py new file mode 100644 index 00000000000..e264a51dc52 --- /dev/null +++ b/tests/unit/parser/test_vpc_lattice.py @@ -0,0 +1,53 @@ +import pytest + +from aws_lambda_powertools.utilities.parser import ( + ValidationError, + envelopes, + event_parser, +) +from aws_lambda_powertools.utilities.parser.models import VPCLatticeModel +from aws_lambda_powertools.utilities.typing import LambdaContext +from tests.functional.parser.schemas import myVPCLatticeBusiness +from tests.functional.utils import load_event + + +@event_parser(model=myVPCLatticeBusiness, envelope=envelopes.VPCLatticeEnvelope) +def handle_lambda_vpclattice_with_envelope(event: myVPCLatticeBusiness, context: LambdaContext): + assert event.username == "Leandro" + assert event.name == "Damascena" + + +def test_vpclattice_event_with_envelope(): + event = load_event("vpcLatticeEvent.json") + event["body"] = '{"username": "Leandro", "name": "Damascena"}' + handle_lambda_vpclattice_with_envelope(event, LambdaContext()) + + +def test_vpclattice_event(): + raw_event = load_event("vpcLatticeEvent.json") + model = VPCLatticeModel(**raw_event) + + assert model.body == raw_event["body"] + assert model.method == raw_event["method"] + assert model.raw_path == raw_event["raw_path"] + assert model.is_base64_encoded == raw_event["is_base64_encoded"] + assert model.headers == raw_event["headers"] + assert model.query_string_parameters == raw_event["query_string_parameters"] + + +def test_vpclattice_event_custom_model(): + class MyCustomResource(VPCLatticeModel): + body: str + + raw_event = load_event("vpcLatticeEvent.json") + model = MyCustomResource(**raw_event) + + assert model.body == raw_event["body"] + + +def test_vpclattice_event_invalid(): + raw_event = load_event("vpcLatticeEvent.json") + raw_event["body"] = ["some_data"] + + with pytest.raises(ValidationError): + VPCLatticeModel(**raw_event) From 9a7ed41ab2aca58cc9a66af99c7c872ac19aa37e Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Tue, 27 Jun 2023 14:29:34 +0200 Subject: [PATCH 2/5] fix: renamed VPC into Vpc --- .../utilities/parser/envelopes/__init__.py | 4 ++-- .../utilities/parser/envelopes/vpc_lattice.py | 10 ++++----- .../utilities/parser/models/__init__.py | 4 ++-- .../utilities/parser/models/vpc_lattice.py | 2 +- docs/utilities/parser.md | 4 ++-- tests/functional/parser/schemas.py | 2 +- tests/unit/parser/test_vpc_lattice.py | 22 +++++++++---------- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/aws_lambda_powertools/utilities/parser/envelopes/__init__.py b/aws_lambda_powertools/utilities/parser/envelopes/__init__.py index cbac331089b..cbca982adf7 100644 --- a/aws_lambda_powertools/utilities/parser/envelopes/__init__.py +++ b/aws_lambda_powertools/utilities/parser/envelopes/__init__.py @@ -10,7 +10,7 @@ from .lambda_function_url import LambdaFunctionUrlEnvelope from .sns import SnsEnvelope, SnsSqsEnvelope from .sqs import SqsEnvelope -from .vpc_lattice import VPCLatticeEnvelope +from .vpc_lattice import VpcLatticeEnvelope __all__ = [ "ApiGatewayEnvelope", @@ -26,5 +26,5 @@ "SqsEnvelope", "KafkaEnvelope", "BaseEnvelope", - "VPCLatticeEnvelope", + "VpcLatticeEnvelope", ] diff --git a/aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py b/aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py index 7a168eac0ee..1ad569b9b1c 100644 --- a/aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py +++ b/aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py @@ -1,15 +1,15 @@ import logging from typing import Any, Dict, Optional, Type, Union -from ..models import VPCLatticeModel +from ..models import VpcLatticeModel from ..types import Model from .base import BaseEnvelope logger = logging.getLogger(__name__) -class VPCLatticeEnvelope(BaseEnvelope): - """VPC Lattice envelope to extract data within body key""" +class VpcLatticeEnvelope(BaseEnvelope): + """Amazon VPC Lattice envelope to extract data within body key""" def parse(self, data: Optional[Union[Dict[str, Any], Any]], model: Type[Model]) -> Optional[Model]: """Parses data found with model provided @@ -26,8 +26,8 @@ def parse(self, data: Optional[Union[Dict[str, Any], Any]], model: Type[Model]) Any Parsed detail payload with model provided """ - logger.debug(f"Parsing incoming data with VPC Lattice model {VPCLatticeModel}") - parsed_envelope: VPCLatticeModel = VPCLatticeModel.parse_obj(data) + logger.debug(f"Parsing incoming data with VPC Lattice model {VpcLatticeModel}") + parsed_envelope: VpcLatticeModel = VpcLatticeModel.parse_obj(data) print(parsed_envelope.body) logger.debug(f"Parsing event payload in `detail` with {model}") return self._parse(data=parsed_envelope.body, model=model) diff --git a/aws_lambda_powertools/utilities/parser/models/__init__.py b/aws_lambda_powertools/utilities/parser/models/__init__.py index 2f746da1bb8..ddc76dc7819 100644 --- a/aws_lambda_powertools/utilities/parser/models/__init__.py +++ b/aws_lambda_powertools/utilities/parser/models/__init__.py @@ -84,7 +84,7 @@ ) from .sns import SnsModel, SnsNotificationModel, SnsRecordModel from .sqs import SqsAttributesModel, SqsModel, SqsMsgAttributeModel, SqsRecordModel -from .vpc_lattice import VPCLatticeModel +from .vpc_lattice import VpcLatticeModel __all__ = [ "APIGatewayProxyEventV2Model", @@ -158,5 +158,5 @@ "CloudFormationCustomResourceDeleteModel", "CloudFormationCustomResourceCreateModel", "CloudFormationCustomResourceBaseModel", - "VPCLatticeModel", + "VpcLatticeModel", ] diff --git a/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py b/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py index dd50ed9960d..8442fc92781 100644 --- a/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py +++ b/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py @@ -3,7 +3,7 @@ from pydantic import BaseModel -class VPCLatticeModel(BaseModel): +class VpcLatticeModel(BaseModel): method: str raw_path: str body: Union[str, Type[BaseModel]] diff --git a/docs/utilities/parser.md b/docs/utilities/parser.md index 9df1a957c10..f482dcb0410 100644 --- a/docs/utilities/parser.md +++ b/docs/utilities/parser.md @@ -180,7 +180,7 @@ Parser comes with the following built-in models: | **SesModel** | Lambda Event Source payload for Amazon Simple Email Service | | **SnsModel** | Lambda Event Source payload for Amazon Simple Notification Service | | **SqsModel** | Lambda Event Source payload for Amazon SQS | -| **VPCLatticeModel** | Lambda Event Source payload for Amazon VPC Lattice | +| **VpcLatticeModel** | Lambda Event Source payload for Amazon VPC Lattice | #### Extending built-in models @@ -337,7 +337,7 @@ Parser comes with the following built-in envelopes, where `Model` in the return | **ApiGatewayV2Envelope** | 1. Parses data using `APIGatewayProxyEventV2Model`.
2. Parses `body` key using your model and returns it. | `Model` | | **LambdaFunctionUrlEnvelope** | 1. Parses data using `LambdaFunctionUrlModel`.
2. Parses `body` key using your model and returns it. | `Model` | | **KafkaEnvelope** | 1. Parses data using `KafkaRecordModel`.
2. Parses `value` key using your model and returns it. | `Model` | -| **VPCLatticeEnvelope** | 1. Parses data using `VPCLatticeModel`.
2. Parses `value` key using your model and returns it. | `Model` | +| **VpcLatticeEnvelope** | 1. Parses data using `VpcLatticeModel`.
2. Parses `value` key using your model and returns it. | `Model` | #### Bringing your own envelope diff --git a/tests/functional/parser/schemas.py b/tests/functional/parser/schemas.py index 117086eb135..1da0213ff45 100644 --- a/tests/functional/parser/schemas.py +++ b/tests/functional/parser/schemas.py @@ -101,6 +101,6 @@ class MyKinesisFirehoseBusiness(BaseModel): Hello: str -class myVPCLatticeBusiness(BaseModel): +class MyVpcLatticeBusiness(BaseModel): username: str name: str diff --git a/tests/unit/parser/test_vpc_lattice.py b/tests/unit/parser/test_vpc_lattice.py index e264a51dc52..f0476509cea 100644 --- a/tests/unit/parser/test_vpc_lattice.py +++ b/tests/unit/parser/test_vpc_lattice.py @@ -5,27 +5,27 @@ envelopes, event_parser, ) -from aws_lambda_powertools.utilities.parser.models import VPCLatticeModel +from aws_lambda_powertools.utilities.parser.models import VpcLatticeModel from aws_lambda_powertools.utilities.typing import LambdaContext -from tests.functional.parser.schemas import myVPCLatticeBusiness +from tests.functional.parser.schemas import MyVpcLatticeBusiness from tests.functional.utils import load_event -@event_parser(model=myVPCLatticeBusiness, envelope=envelopes.VPCLatticeEnvelope) -def handle_lambda_vpclattice_with_envelope(event: myVPCLatticeBusiness, context: LambdaContext): +@event_parser(model=MyVpcLatticeBusiness, envelope=envelopes.VpcLatticeEnvelope) +def handle_lambda_vpclattice_with_envelope(event: MyVpcLatticeBusiness, context: LambdaContext): assert event.username == "Leandro" assert event.name == "Damascena" -def test_vpclattice_event_with_envelope(): +def test_vpc_lattice_event_with_envelope(): event = load_event("vpcLatticeEvent.json") event["body"] = '{"username": "Leandro", "name": "Damascena"}' handle_lambda_vpclattice_with_envelope(event, LambdaContext()) -def test_vpclattice_event(): +def test_vpc_lattice_event(): raw_event = load_event("vpcLatticeEvent.json") - model = VPCLatticeModel(**raw_event) + model = VpcLatticeModel(**raw_event) assert model.body == raw_event["body"] assert model.method == raw_event["method"] @@ -35,8 +35,8 @@ def test_vpclattice_event(): assert model.query_string_parameters == raw_event["query_string_parameters"] -def test_vpclattice_event_custom_model(): - class MyCustomResource(VPCLatticeModel): +def test_vpc_lattice_event_custom_model(): + class MyCustomResource(VpcLatticeModel): body: str raw_event = load_event("vpcLatticeEvent.json") @@ -45,9 +45,9 @@ class MyCustomResource(VPCLatticeModel): assert model.body == raw_event["body"] -def test_vpclattice_event_invalid(): +def test_vpc_lattice_event_invalid(): raw_event = load_event("vpcLatticeEvent.json") raw_event["body"] = ["some_data"] with pytest.raises(ValidationError): - VPCLatticeModel(**raw_event) + VpcLatticeModel(**raw_event) From f1c2abd5482227775785258874a09ea65ccf80ed Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Tue, 27 Jun 2023 14:39:40 +0200 Subject: [PATCH 3/5] Empty-Commit From 71d9b5956e309fb7d124f9dc6f439edcaaae7c23 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Tue, 27 Jun 2023 13:45:28 +0100 Subject: [PATCH 4/5] fix: changing returns Co-authored-by: Ruben Fonseca Signed-off-by: Leandro Damascena --- aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py b/aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py index 1ad569b9b1c..0ff132dd1e4 100644 --- a/aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py +++ b/aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py @@ -23,7 +23,7 @@ def parse(self, data: Optional[Union[Dict[str, Any], Any]], model: Type[Model]) Returns ------- - Any + Optional[Model] Parsed detail payload with model provided """ logger.debug(f"Parsing incoming data with VPC Lattice model {VpcLatticeModel}") From 430b707786867cdfc428c1c06b5c337767b74cf2 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Tue, 27 Jun 2023 13:46:01 +0100 Subject: [PATCH 5/5] fix: removing debug Co-authored-by: Ruben Fonseca Signed-off-by: Leandro Damascena --- aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py | 1 - 1 file changed, 1 deletion(-) diff --git a/aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py b/aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py index 0ff132dd1e4..fb95ac05a8d 100644 --- a/aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py +++ b/aws_lambda_powertools/utilities/parser/envelopes/vpc_lattice.py @@ -28,6 +28,5 @@ def parse(self, data: Optional[Union[Dict[str, Any], Any]], model: Type[Model]) """ logger.debug(f"Parsing incoming data with VPC Lattice model {VpcLatticeModel}") parsed_envelope: VpcLatticeModel = VpcLatticeModel.parse_obj(data) - print(parsed_envelope.body) logger.debug(f"Parsing event payload in `detail` with {model}") return self._parse(data=parsed_envelope.body, model=model)