-
Notifications
You must be signed in to change notification settings - Fork 406
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
Bug: APIGatewayProxyEventV2Model not deserializing str to custom model #1518
Comments
Thanks for opening your first issue here! We'll come back to you as soon as we can. |
hey @nleipi , Here's a sample code that will get it working for you: from aws_lambda_powertools.utilities.parser import BaseModel
from aws_lambda_powertools.utilities.parser.models import (
APIGatewayProxyEventV2Model
)
import json
from pydantic import validator
class OrderCancelationRequest(BaseModel):
reason: str
orderNo: str
class MyEventModel(APIGatewayProxyEventV2Model):
body: OrderCancelationRequest
@validator("body", pre=True)
def transform_body_to_dict(cls, value: str):
return json.loads(value) @leandrodamascena maybe we should include this example in the docs for extending the models that have a non dict base type like this one. |
I think the correct way to handle this is to use pydantics own Json type as a wrapper for the model.
That should be definitely highlighted in the documentation. |
Nice! even prettier |
Hi @nleipi, thanks for opening this! As @ran-isenberg mentioned, parser envelopes were created exactly with this use case in mind. In your case, the code would look something like this: from aws_lambda_powertools.utilities.parser import event_parser, BaseModel, envelopes
from aws_lambda_powertools.utilities.typing import LambdaContext
class OrderCancelationRequest(BaseModel):
reason: str
orderNo: str
@event_parser(model=OrderCancelationRequest, envelope=envelopes.ApiGatewayV2Envelope)
def handler(event: OrderCancelationRequest, context: LambdaContext):
assert event.reason != "" What do you think of giving this a try? |
I would have used envelope approach, but I need access to pathParamters. Can I access them in other way than through event model? |
In order to get the path params, you must extend the model like you did and not use the envelope. class MyEventModel(APIGatewayProxyEventV2Model):
body: OrderCancelationRequest
pathParameters: MyPathParams
@validator("body", pre=True)
def transform_body_to_dict(cls, value: str):
return json.loads(value) |
Stronger validation of pathParameters is a really good point, thanks! |
Thanks! We already have some documentation about extending built-in modules. Do you think people could benefit from this example too? |
The example describes a simple use case where the business payload param is a dict. |
Thank you so much for your input! I've opened a PR now to add this use case to our parser docs :) |
Hi @nleipi @ran-isenberg I was trying out this snippet, but I still got a mypy error on the body field:
Can you check if it's the same, or if I'm missing something? I'm starting to feel that the only way around this is to use the validator route. |
Sorry, I dont use mypy that extensively. |
This is now released under 1.30.0 version! |
Expected Behaviour
It should be possible to use own model classes for body in APIGatewayProxyEventV2Model
Current Behaviour
When I extend APIGatewayProxyEventV2Model model to include my own model for the body following exception is raised
1 validation error for Event\nbody\n value is not a valid dict (type=type_error.dict)
. I suppose the reason for that is that body of apigw v2 event is a stringCode snippet
Possible Solution
No response
Steps to Reproduce
parse(model=MyEventModel, event=any valid apigw event)
AWS Lambda Powertools for Python version
latest
AWS Lambda function runtime
3.9
Packaging format used
PyPi
Debugging logs
No response
The text was updated successfully, but these errors were encountered: