Skip to content

Commit 9047f41

Browse files
leandrodamascenarubenfonseca
authored andcommitted
feat(parser): add support to VpcLatticeModel (aws-powertools#2584)
Co-authored-by: Ruben Fonseca <[email protected]>
1 parent 5761101 commit 9047f41

File tree

7 files changed

+108
-0
lines changed

7 files changed

+108
-0
lines changed

aws_lambda_powertools/utilities/parser/envelopes/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from .lambda_function_url import LambdaFunctionUrlEnvelope
1111
from .sns import SnsEnvelope, SnsSqsEnvelope
1212
from .sqs import SqsEnvelope
13+
from .vpc_lattice import VpcLatticeEnvelope
1314

1415
__all__ = [
1516
"ApiGatewayEnvelope",
@@ -25,4 +26,5 @@
2526
"SqsEnvelope",
2627
"KafkaEnvelope",
2728
"BaseEnvelope",
29+
"VpcLatticeEnvelope",
2830
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import logging
2+
from typing import Any, Dict, Optional, Type, Union
3+
4+
from ..models import VpcLatticeModel
5+
from ..types import Model
6+
from .base import BaseEnvelope
7+
8+
logger = logging.getLogger(__name__)
9+
10+
11+
class VpcLatticeEnvelope(BaseEnvelope):
12+
"""Amazon VPC Lattice envelope to extract data within body key"""
13+
14+
def parse(self, data: Optional[Union[Dict[str, Any], Any]], model: Type[Model]) -> Optional[Model]:
15+
"""Parses data found with model provided
16+
17+
Parameters
18+
----------
19+
data : Dict
20+
Lambda event to be parsed
21+
model : Type[Model]
22+
Data model provided to parse after extracting data using envelope
23+
24+
Returns
25+
-------
26+
Optional[Model]
27+
Parsed detail payload with model provided
28+
"""
29+
logger.debug(f"Parsing incoming data with VPC Lattice model {VpcLatticeModel}")
30+
parsed_envelope: VpcLatticeModel = VpcLatticeModel.parse_obj(data)
31+
logger.debug(f"Parsing event payload in `detail` with {model}")
32+
return self._parse(data=parsed_envelope.body, model=model)

aws_lambda_powertools/utilities/parser/models/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
)
8585
from .sns import SnsModel, SnsNotificationModel, SnsRecordModel
8686
from .sqs import SqsAttributesModel, SqsModel, SqsMsgAttributeModel, SqsRecordModel
87+
from .vpc_lattice import VpcLatticeModel
8788

8889
__all__ = [
8990
"APIGatewayProxyEventV2Model",
@@ -157,4 +158,5 @@
157158
"CloudFormationCustomResourceDeleteModel",
158159
"CloudFormationCustomResourceCreateModel",
159160
"CloudFormationCustomResourceBaseModel",
161+
"VpcLatticeModel",
160162
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from typing import Dict, Type, Union
2+
3+
from pydantic import BaseModel
4+
5+
6+
class VpcLatticeModel(BaseModel):
7+
method: str
8+
raw_path: str
9+
body: Union[str, Type[BaseModel]]
10+
is_base64_encoded: bool
11+
headers: Dict[str, str]
12+
query_string_parameters: Dict[str, str]

docs/utilities/parser.md

+2
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ Parser comes with the following built-in models:
180180
| **SesModel** | Lambda Event Source payload for Amazon Simple Email Service |
181181
| **SnsModel** | Lambda Event Source payload for Amazon Simple Notification Service |
182182
| **SqsModel** | Lambda Event Source payload for Amazon SQS |
183+
| **VpcLatticeModel** | Lambda Event Source payload for Amazon VPC Lattice |
183184

184185
#### Extending built-in models
185186

@@ -336,6 +337,7 @@ Parser comes with the following built-in envelopes, where `Model` in the return
336337
| **ApiGatewayV2Envelope** | 1. Parses data using `APIGatewayProxyEventV2Model`. <br/> 2. Parses `body` key using your model and returns it. | `Model` |
337338
| **LambdaFunctionUrlEnvelope** | 1. Parses data using `LambdaFunctionUrlModel`. <br/> 2. Parses `body` key using your model and returns it. | `Model` |
338339
| **KafkaEnvelope** | 1. Parses data using `KafkaRecordModel`. <br/> 2. Parses `value` key using your model and returns it. | `Model` |
340+
| **VpcLatticeEnvelope** | 1. Parses data using `VpcLatticeModel`. <br/> 2. Parses `value` key using your model and returns it. | `Model` |
339341

340342
#### Bringing your own envelope
341343

tests/functional/parser/schemas.py

+5
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,8 @@ class MyLambdaKafkaBusiness(BaseModel):
9999

100100
class MyKinesisFirehoseBusiness(BaseModel):
101101
Hello: str
102+
103+
104+
class MyVpcLatticeBusiness(BaseModel):
105+
username: str
106+
name: str

tests/unit/parser/test_vpc_lattice.py

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import pytest
2+
3+
from aws_lambda_powertools.utilities.parser import (
4+
ValidationError,
5+
envelopes,
6+
event_parser,
7+
)
8+
from aws_lambda_powertools.utilities.parser.models import VpcLatticeModel
9+
from aws_lambda_powertools.utilities.typing import LambdaContext
10+
from tests.functional.parser.schemas import MyVpcLatticeBusiness
11+
from tests.functional.utils import load_event
12+
13+
14+
@event_parser(model=MyVpcLatticeBusiness, envelope=envelopes.VpcLatticeEnvelope)
15+
def handle_lambda_vpclattice_with_envelope(event: MyVpcLatticeBusiness, context: LambdaContext):
16+
assert event.username == "Leandro"
17+
assert event.name == "Damascena"
18+
19+
20+
def test_vpc_lattice_event_with_envelope():
21+
event = load_event("vpcLatticeEvent.json")
22+
event["body"] = '{"username": "Leandro", "name": "Damascena"}'
23+
handle_lambda_vpclattice_with_envelope(event, LambdaContext())
24+
25+
26+
def test_vpc_lattice_event():
27+
raw_event = load_event("vpcLatticeEvent.json")
28+
model = VpcLatticeModel(**raw_event)
29+
30+
assert model.body == raw_event["body"]
31+
assert model.method == raw_event["method"]
32+
assert model.raw_path == raw_event["raw_path"]
33+
assert model.is_base64_encoded == raw_event["is_base64_encoded"]
34+
assert model.headers == raw_event["headers"]
35+
assert model.query_string_parameters == raw_event["query_string_parameters"]
36+
37+
38+
def test_vpc_lattice_event_custom_model():
39+
class MyCustomResource(VpcLatticeModel):
40+
body: str
41+
42+
raw_event = load_event("vpcLatticeEvent.json")
43+
model = MyCustomResource(**raw_event)
44+
45+
assert model.body == raw_event["body"]
46+
47+
48+
def test_vpc_lattice_event_invalid():
49+
raw_event = load_event("vpcLatticeEvent.json")
50+
raw_event["body"] = ["some_data"]
51+
52+
with pytest.raises(ValidationError):
53+
VpcLatticeModel(**raw_event)

0 commit comments

Comments
 (0)