Skip to content

Bug: Pydantic objects always serialized using alias #6728

Open
@dehanjl

Description

@dehanjl

Expected Behaviour

The default behavior of Pydantic is to model dump using by_alias=False. Lambda powertools seems to override this somehow.

Expected return from code snippet below:

{
  "fieldOne": "value1",
  "field_two": "value2"
}

Note: When I remove the alias generator, and set the fields manually, the issue does not occur; hence why I suspect this has something to do with aliases.

Current Behaviour

Currently, when creating a Pydantic object that has an alias generator, and model dumping it explicitly using by_alias=False before returning it from an API Gateway Rest Resolver endpoint, it is always return by the alias, even when it should not be.

Actually returned from code snippet below:

{
  "field_one": "value1",
  "field_two": "value2"
}

Code snippet

### handler.py
import json

from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools.utilities.typing import LambdaContext

from models import LegacyInconsistentModel, ShinyNewConsistentModel

app = APIGatewayRestResolver(enable_validation=True)


@app.get("/hello")
def hello():
    return {"message": "Hello, World!"}


@app.get("/info")
def info() -> LegacyInconsistentModel:
    obj = ShinyNewConsistentModel(field_one="value1", field_two="value2")
    ret_obj = LegacyInconsistentModel(**obj.model_dump())
    ret_dict = ret_obj.model_dump(by_alias=False)
    return ret_dict


def lambda_handler(event: dict, context: LambdaContext):
    return app.resolve(event, context)

### models.py
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_snake


class LegacyInconsistentModel(BaseModel):
    model_config = ConfigDict(alias_generator=to_snake, populate_by_name=True)

    fieldOne: str
    field_two: str


class ShinyNewConsistentModel(BaseModel):
    field_one: str
    field_two: str

Possible Solution

No response

Steps to Reproduce

I have created a sample repository where I isolated the issue: https://github.com/dehanjl/lambda-powertools-serialization-test.

I've investigated the serializer and the layers it goes into; but nowhere that I can see is by_alias=True passed.

self._serializer = serializer or partial(json.dumps, separators=(",", ":"), cls=Encoder)

https://github.com/aws-powertools/powertools-lambda-python/blob/f106e368cf760b3585e36ebf7dc0f65a62c632b8/aws_lambda_powertools/shared/json_encoder.py
from aws_lambda_powertools.event_handler.openapi.compat import _model_dump

def _model_dump(model: BaseModel, mode: Literal["json", "python"] = "json", **kwargs: Any) -> Any:

Powertools for AWS Lambda (Python) version

latest

AWS Lambda function runtime

3.12

Packaging format used

Lambda Layers

Debugging logs

Metadata

Metadata

Labels

bugSomething isn't workingneed-customer-feedbackRequires more customers feedback before making or revisiting a decision

Type

No type

Projects

Status

Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions