Open ghost opened 3 years ago
@omfd I'm curious if anyone has experimented with making this work, e.g. using some transformer from pydantic's BaseModel.dict()
to drf-yasg's Schema
?
@omfd could you provide an example interface for how you think registering pydantic objects could look if this feature is built?
@JoelLefkowitz I think it would make sense to use the same facilities as are already in place. Allowing pydantic models in the responses
and request_body
arguments of swagger_auto_schema
, e.g. @swagger_auto_schema(request_body=SomeRequest, responses={200: SomeResponse})
. I think that would solve 95% of cases :)
@antonagestam exactly! If you have a look at the Fastapi sample I am mentioning below for reference !
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
@app.post("/items/", response_model=Item)
async def create_item(item: Item):
return item
The above is a POST request with Body as of type Item and response is also of the same type Item
Below is the screenshot for the swagger generator Fastapi guys have done for themselves where default support is Pydantic Data Models
If we add support for adding request_body and responses object derived from Pydantic BaseModels it will be pretty good.
Regards
@omfd I'm curious if anyone has experimented with making this work, e.g. using some transformer from pydantic's
BaseModel.dict()
to drf-yasg'sSchema
?
@antonagestam I tried to extend SwaggerAutoSchema to accomodate support for the pydantic objects.
But the prime issue is the base class has a strict check of object being of type serializer which makes it incompatible
Even if that base method can be released with support of Union[Serializer, BaseModel]
we can customize it and extend it accordingly as per the need but the above support needs to be there !!
Rest pydantic by default have pretty good method to make it work once that strict check and include pydantic object support
@omfd
But the prime issue is the base class has a strict check of object being of type serializer which makes it incompatible
Which check is that? Is it in BaseInspector
?
def get_request_body_parameters(self, consumes):
"""Return the request body parameters for this view. |br|
This is either:
- a list with a single object Parameter with a :class:`.Schema` derived from the request serializer
- a list of primitive Parameters parsed as form data
:param list[str] consumes: a list of accepted MIME types as returned by :meth:`.get_consumes`
:return: a (potentially empty) list of :class:`.Parameter`\\ s either ``in: body`` or ``in: formData``
:rtype: list[openapi.Parameter]
"""
serializer = self.get_request_serializer()
schema = None
if serializer is None:
return []
if isinstance(serializer, openapi.Schema.OR_REF):
schema = serializer
if any(is_form_media_type(encoding) for encoding in consumes):
if schema is not None:
raise SwaggerGenerationError("form request body cannot be a Schema")
return self.get_request_form_parameters(serializer)
else:
if schema is None:
schema = self.get_request_body_schema(serializer)
return [self.make_body_parameter(schema)] if schema is not None else []
If you follow the method self.get_request_serializer() you will land up at the below method where the check is happening!!!
def force_serializer_instance(serializer):
"""Force `serializer` into a ``Serializer`` instance. If it is not a ``Serializer`` class or instance, raises
an assertion error.
:param serializer: serializer class or instance
:type serializer: serializers.BaseSerializer or type[serializers.BaseSerializer]
:return: serializer instance
:rtype: serializers.BaseSerializer
"""
if inspect.isclass(serializer):
assert issubclass(serializer, serializers.BaseSerializer), "Serializer required, not %s" % serializer.__name__
return serializer()
assert isinstance(serializer, serializers.BaseSerializer), \
"Serializer class or instance required, not %s" % type(serializer).__name__
return serializer
@omfd
But the prime issue is the base class has a strict check of object being of type serializer which makes it incompatible
Which check is that? Is it in
BaseInspector
?
Please look the above comment ---- the idea was to override the get_request_body_parameters method
@antonagestam
@JoelLefkowitz Hi Joel I have added couple of examples in the thread above as well mentioned the code where I am having trouble in extending the SwaggerAutoSchema to accomodate pydantic support for request body and response
Has anyone tried using already provided schema()
method in pydantic
with already provided openapi.Schema
class in drf_yasg
to generate the docs, something like this --
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
from drf_yasg.openapi import Schema
from drf_yasg.utils import swagger_auto_schema
@swagger_auto_schema(
responses={
status.HTTP_200_OK: Schema(**Item.schema())
}
)
Has anyone tried using already provided
schema()
method inpydantic
with already providedopenapi.Schema
class indrf_yasg
to generate the docs, something like this --
This does not seem to work with nested models. I am getting
drf_yasg.errors.SwaggerValidationError: spec validation failed:
{'ssv': '("Unresolvable JSON pointer: \'definitions/SubModel\'")'}
Consider using the approach here (https://github.com/pydantic/pydantic/issues/889#issuecomment-1064688675) to avoid submodels in the JSON schema generated by pydantic.
Hi Guys,
Pydantic by default provide support for schema generation from the Data Model. If someone can create a feature branch for support pydantic objects as well for the above mentioned things - it will be awesome !!
currently it works for drf serializers only -
just a request - might prove helpful for a quite a lot of developers !!
Regards