generated from amazon-archives/__template_MIT-0
-
Notifications
You must be signed in to change notification settings - Fork 455
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Expected Behaviour
Annotated parameter types using annotated_types should be validated by Pydantic. This used to work, but regressed starting from 3.21.0. Types are still validated, but constraint annotations are not.
I thought #7227 would have enabled using Pydantic Field annotations for this use case, and tried to switch to that, but that also doesn't work (in any Powertools version). Should I report this separately (perhaps as a feature request)?
Current Behaviour
Parameter types are validated, but constraints expressed using annotated_types are not enforced. Handler functions can be called with invalid parameter values.
Code snippet
from http import HTTPStatus
from typing import Annotated
from aws_lambda_powertools.event_handler import APIGatewayHttpResolver
from aws_lambda_powertools.event_handler.openapi.params import Body, Query
import pytest
# aws-lambda-powertools 3.20.0: ok
# aws-lambda-powertools 3.21.0 and 3.22.0: fail (value outside of range allowed)
from annotated_types import Interval
ConstrainedInt = Annotated[int, Interval(ge=0, le=100)]
# aws-lambda-powertools 3.20.0 and 3.21.0 and 3.22.0: error (Only one FieldInfo can be used per parameter)
#from pydantic.fields import Field
#ConstrainedInt = Annotated[int, Field(ge=0, le=100)]
app = APIGatewayHttpResolver(enable_validation=True)
@app.post('/body')
def handle_body(value: Annotated[ConstrainedInt, Body()]) -> None:
assert isinstance(value, int)
assert value >= 0
assert value <= 100
@app.post('/query')
def handle_body(value: Annotated[ConstrainedInt, Query()]) -> None:
assert isinstance(value, int)
assert value >= 0
assert value <= 100
def handler(event, context):
return app.resolve(event, context)
params = [
(0, HTTPStatus.OK),
(50, HTTPStatus.OK),
(100, HTTPStatus.OK),
(-1, HTTPStatus.UNPROCESSABLE_ENTITY),
(101, HTTPStatus.UNPROCESSABLE_ENTITY),
('not an int', HTTPStatus.UNPROCESSABLE_ENTITY),
]
@pytest.mark.parametrize('value,expected_status', params)
def test_handle_body(value, expected_status):
event = {
'rawPath': '/body',
'requestContext': {
'http': {
'method': 'POST'
},
'stage': '$default'
},
'body': str(value)
}
response = handler(event, object())
assert expected_status == response['statusCode']
@pytest.mark.parametrize('value,expected_status', params)
def test_handle_query(value, expected_status):
event = {
'rawPath': '/query',
'requestContext': {
'http': {
'method': 'POST'
},
'stage': '$default'
},
'queryStringParameters': {
'value': str(value)
}
}
response = handler(event, object())
assert expected_status == response['statusCode']Possible Solution
No response
Steps to Reproduce
Run code snippet: pytest test_annotated_types.py
Powertools for AWS Lambda (Python) version
3.21.0, 3.22.0
AWS Lambda function runtime
3.11
Packaging format used
Lambda Layers
Debugging logs
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working
Type
Projects
Status
Backlog