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

documentationImprovements or additions to documentation

Type

No type

Projects

Status

Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions