Skip to content
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

Enhancement: Support all kwargs for model_dump in PydanticPlugin #3147

Open
bunny-therapist opened this issue Feb 29, 2024 · 1 comment · May be fixed by #3327
Open

Enhancement: Support all kwargs for model_dump in PydanticPlugin #3147

bunny-therapist opened this issue Feb 29, 2024 · 1 comment · May be fixed by #3327
Assignees
Labels
Enhancement This is a new feature or request Good First Issue This is good for newcomers to take on

Comments

@bunny-therapist
Copy link

bunny-therapist commented Feb 29, 2024

Summary

litestar.contrib.pydantic.PydanticPlugin has the argument prefer_alias which sets the by_alias argument of the created Pydantic type encoders. The type encoders are based on pydantic.BaseModel.model_dump which also has the arguments exclude_none and exclude_defaults. This enhancement suggests to add similar arguments to PydanticPlugin to configure the type encoders.

Basic Example

import pydantic
import typing
import litestar
import litestar.contrib.pydantic

class MyModel(pydantic.BaseModel):
    some_number: int = pydantic.Field(alias="someNumber")
    title: str = "a number"
    comment: typing.Optional[str] = None

@litestar.get("/")
def get_stuff() -> MyModel:
    return MyModel(some_number=42)

app = litestar.Litestar(
    route_handlers=[get_stuff],
    plugins=[
        litestar.contrib.pydantic.PydanticPlugin(
            prefer_alias=True,
            # NOTE: The argument names are just provisional
            exclude_none=True,  # new
            exclude_defaults=True,  # new
        )
    ],
)

A GET request to / would return {"someNumber":42} because of the plugin configuration. Without it, it would return {"some_number":42,"title":"a number","comment":null}.

Drawbacks and Impact

You can currently achieve the same result without this feature by adding a custom type encoder for pydantic.BaseModel. However, it must be combined with PydanticPlugin for the generated schema to use aliases.

import pydantic
import typing
import litestar
import litestar.contrib.pydantic

class MyModel(pydantic.BaseModel):
    some_number: int = pydantic.Field(alias="someNumber")
    title: str = "a number"
    comment: typing.Optional[str] = None

@litestar.get("/")
def get_stuff() -> MyModel:
    return MyModel(some_number=42)


app = litestar.Litestar(
    route_handlers=[get_stuff],
    plugins=[litestar.contrib.pydantic.PydanticPlugin(prefer_alias=True)],
    type_encoders={
        pydantic.BaseModel: lambda x: x.model_dump(mode="json", by_alias=True, exclude_none=True, exclude_default=True),
    },
)

Therefore, the only purpose of this enhancement is to make this use case (which I believe to be a common one) simpler to express in code by making the plugin able to do more, reducing the need for type encoders. The community must decide if this is desirable or not.

As long as the default values of the new arguments match the old behavior, this should not cause any issues with backwards compatibility.

Unresolved questions

I can see that there may be concerns about having to support a growing list of pydantic.BaseModel.model_dump arguments (for example exlude_unset). I believe that concern to be valid, but you could always draw a line and say "the plugin supports these extremely common arguments, if you want more, use a custom type encoder". Still, the concern is valid and I believe it should be part of the discussion.


Note

While we are open for sponsoring on GitHub Sponsors and
OpenCollective, we also utilize Polar.sh to engage in pledge-based sponsorship.

Check out all issues funded or available for funding on our Polar.sh dashboard

  • If you would like to see an issue prioritized, make a pledge towards it!
  • We receive the pledge once the issue is completed & verified
  • This, along with engagement in the community, helps us know which features are a priority to our users.
Fund with Polar
@bunny-therapist bunny-therapist added the Enhancement This is a new feature or request label Feb 29, 2024
@guacs
Copy link
Member

guacs commented Mar 2, 2024

I think it's reasonable to include not just the ones mentioned, but all the arguments supported by model_dump. There's only 6 arguments to model_dump that we would need to take from the user.

@guacs guacs added the Good First Issue This is good for newcomers to take on label Mar 4, 2024
@guacs guacs changed the title Enhancement: Support exclude_none and exlude_defaults in PydanticPlugin Enhancement: Support all kwags for model_dump in PydanticPlugin Mar 4, 2024
@JacobCoffee JacobCoffee changed the title Enhancement: Support all kwags for model_dump in PydanticPlugin Enhancement: Support all kwargs for model_dump in PydanticPlugin Mar 4, 2024
@kedod kedod self-assigned this Apr 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement This is a new feature or request Good First Issue This is good for newcomers to take on
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants