diff --git a/aws_lambda_powertools/utilities/parser/models/__init__.py b/aws_lambda_powertools/utilities/parser/models/__init__.py index 36ba05240b0..5c5c0b817c9 100644 --- a/aws_lambda_powertools/utilities/parser/models/__init__.py +++ b/aws_lambda_powertools/utilities/parser/models/__init__.py @@ -1,3 +1,4 @@ +from .alb import AlbModel, AlbRequestContext, AlbRequestContextData from .dynamodb import DynamoDBStreamChangedRecordModel, DynamoDBStreamModel, DynamoDBStreamRecordModel from .event_bridge import EventBridgeModel from .ses import SesModel, SesRecordModel @@ -5,6 +6,9 @@ from .sqs import SqsModel, SqsRecordModel __all__ = [ + "AlbModel", + "AlbRequestContext", + "AlbRequestContextData", "DynamoDBStreamModel", "EventBridgeModel", "DynamoDBStreamChangedRecordModel", diff --git a/aws_lambda_powertools/utilities/parser/models/alb.py b/aws_lambda_powertools/utilities/parser/models/alb.py new file mode 100644 index 00000000000..d4ea5fde2a1 --- /dev/null +++ b/aws_lambda_powertools/utilities/parser/models/alb.py @@ -0,0 +1,21 @@ +from typing import Dict + +from pydantic import BaseModel + + +class AlbRequestContextData(BaseModel): + targetGroupArn: str + + +class AlbRequestContext(BaseModel): + elb: AlbRequestContextData + + +class AlbModel(BaseModel): + httpMethod: str + path: str + body: str + isBase64Encoded: bool + headers: Dict[str, str] + queryStringParameters: Dict[str, str] + requestContext: AlbRequestContext diff --git a/docs/content/utilities/parser.mdx b/docs/content/utilities/parser.mdx index 0c571bc257a..9e64b172c16 100644 --- a/docs/content/utilities/parser.mdx +++ b/docs/content/utilities/parser.mdx @@ -156,6 +156,7 @@ Model name | Description **DynamoDBStreamModel** | Lambda Event Source payload for Amazon DynamoDB Streams **EventBridgeModel** | Lambda Event Source payload for Amazon EventBridge **SqsModel** | Lambda Event Source payload for Amazon SQS +**AlbModel** | Lambda Event Source payload for Amazon Application Load Balancer You can extend them to include your own models, and yet have all other known fields parsed along the way. diff --git a/tests/functional/parser/test_alb.py b/tests/functional/parser/test_alb.py new file mode 100644 index 00000000000..88631c7194c --- /dev/null +++ b/tests/functional/parser/test_alb.py @@ -0,0 +1,44 @@ +import pytest + +from aws_lambda_powertools.utilities.parser import ValidationError, event_parser +from aws_lambda_powertools.utilities.parser.models import AlbModel +from aws_lambda_powertools.utilities.typing import LambdaContext +from tests.functional.parser.utils import load_event + + +@event_parser(model=AlbModel) +def handle_alb(event: AlbModel, _: LambdaContext): + assert ( + event.requestContext.elb.targetGroupArn + == "arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-279XGJDqGZ5rsrHC2Fjr/49e9d65c45c6791a" # noqa E501 + ) + assert event.httpMethod == "GET" + assert event.path == "/lambda" + assert event.queryStringParameters == {"query": "1234ABCD"} + assert event.headers == { + "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", + "accept-encoding": "gzip", + "accept-language": "en-US,en;q=0.9", + "connection": "keep-alive", + "host": "lambda-alb-123578498.us-east-2.elb.amazonaws.com", + "upgrade-insecure-requests": "1", + "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36", # noqa E501 + "x-amzn-trace-id": "Root=1-5c536348-3d683b8b04734faae651f476", + "x-forwarded-for": "72.12.164.125", + "x-forwarded-port": "80", + "x-forwarded-proto": "http", + "x-imforwards": "20", + } + assert event.body == "Test" + assert not event.isBase64Encoded + + +def test_alb_trigger_event(): + event_dict = load_event("albEvent.json") + handle_alb(event_dict, LambdaContext()) + + +def test_validate_event_does_not_conform_with_model(): + event = {"invalid": "event"} + with pytest.raises(ValidationError): + handle_alb(event, LambdaContext())