This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
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
Generic pydantic model causes inconsistent OpenAPI spec generation #653
Comments
As of pydantic v1, there is support for overriding the naming behavior of a generic class; see bottom of the section on generic models in the docs https://pydantic-docs.helpmanual.io/usage/models/#generic-models. In the meantime until we have pydantic v1 support, your best bet is probably: ResponseListProjectOut = Response[List[ProjectOut]]
ResponseListProjectOut.__name__ = "Response[List[ProjectOut]]" # or whatever
...
@app.get('/projects', response_model=ResponseListProjectOut)
def get_projects() -> ResponseListProjectOut:
return ResponseListProjectOut(data=[out]) I'm working on a "fix" to the type thing now. PyCharm doesn't make it easy though since it is basically impossible to hide method definitions from it. But I think annotating |
Also have in mind that your path operation function might return something different, like a DB model, a In those cases, you would have to declare the return type of your function as such for Also, you're probably never calling your path operation function directly, FastAPI calls it for you, so you will probably never get a lot of benefit from annotating it's return type. My suggestion is, annotate everything else for your own sanity, but the path operation function... meh, no benefit from that. |
I am quite new to the annotations thing and did think through the implications. Thanks for the hint to skip annotations for the path operations. |
Sure! 😄 |
Assuming the original issue was solved, it will be automatically closed now. But feel free to add more comments or create new issues. |
Hello everyone. I have a similar issue to the one presented here. Basically I'm using a pydantic BaseModel to represent the Pagination response. This class extends generic with a TypeVar. T = TypeVar("T")
class PaginationModel(BaseModel, Generic[T]):
total: int = Field(description="Total number of elements on DB")
index: int = Field(description="The current page index")
size: int = Field(description="The size of the page")
results: List[T] Then I use as Generic input the object that should be in the results list class MyMockModel(BaseModel):
foo: int
bar: int Then use it as route response model def get_foo_bar(response_model=PaginationModel[MyMockModel]):
... When I print the openapi spec, I expect to have something like {
"total": 0,
"index": 0,
"size": 20,
"result": [
{
"foo": 0,
"bar": 0
}
]
} but what actually I get is {
"foo": 0,
"bar": 0
} I'm doing somethings wrong, or it is a bug? |
@KiraPC – I just stumbled upon the same issue as you and Google led me here, so I'll write down the solution to that: Instead of deriving your from pydantic import BaseModel
from pydantic.generics import GenericModel
Model = TypeVar("Model", bound=BaseModel)
class PaginationModel(GenericModel, Generic[Model]):
index: int
size: int
total: int
items: List[Model] |
Oh, thank you man. This was very useful. |
Assuming the original need was handled, this will be automatically closed now. But feel free to add more comments or create new issues or PRs. |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
Describe the bug
I am wrapping my responses in a generic model like below (full code in toggle section).
I see two issues:
/docs
endpoint renders things differently for a contained list or a contained single element.I am wondering if I am using the
GenericModel
in a wrong way or if there is a bug?Click to toggle
To Reproduce
Expected behavior
Response[List[ProjectOut]]
Screenshots
Environment:
Additional context
Add any other context about the problem here.
The text was updated successfully, but these errors were encountered: