Sane and flexible OpenAPI 3.0 schema generation for Django REST framework.
- This project has 3 goals:
- Extract as much schema information from DRF as possible.
- Provide flexibility to make the schema usable in the real world (not only toy examples).
- Generate a schema that works well with the most popular client generators.
The code is a heavily modified fork of the DRF OpenAPI generator, which is/was lacking all of the below listed features.
- Features
- Serializers modelled as components. (arbitrary nesting and recursion supported)
- @extend_schema decorator for customization of APIView, Viewsets, function-based views, and
@action
- additional parameters
- request/response serializer override (with status codes)
- polymorphic responses either manually with
PolymorphicProxySerializer
helper or viarest_polymorphic
's PolymorphicSerializer) - ... and more customization options
- @extend_schema decorator for customization of APIView, Viewsets, function-based views, and
- Authentication support (DRF natives included, easily extendable)
- Custom serializer class support (easily extendable)
MethodSerializerField()
type via type hinting or@extend_schema_field
- i18n support
- Tags extraction
- Description extraction from
docstrings
- Sane fallbacks
- Sane
operation_id
naming (based on path) - Schema serving with
SpectacularAPIView
(Redoc and Swagger-UI views are also available) - Optional input/output serializer component split
- Included support for:
- django-polymorphic / django-rest-polymorphic
- SimpleJWT
- DjangoOAuthToolkit
- djangorestframework-jwt (tested fork drf-jwt)
- djangorestframework-camel-case (via postprocessing hook
camelize_serializer_fields
)
For more information visit the documentation.
Provided by T. Franzel, Cashlink Technologies GmbH. Licensed under 3-Clause BSD.
- Python >= 3.6
- Django (2.2, 3.0)
- Django REST Framework (3.10, 3.11)
Install using pip
…
$ pip install drf-spectacular
then add drf-spectacular to installed apps in settings.py
INSTALLED_APPS = [
# ALL YOUR APPS
'drf_spectacular',
]
and finally register our spectacular AutoSchema with DRF
REST_FRAMEWORK = {
# YOUR SETTINGS
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}
Generate your schema with the CLI:
$ ./manage.py spectacular --file schema.yml
$ docker run -p 80:8080 -e SWAGGER_JSON=/schema.yml -v ${PWD}/schema.yml:/schema.yml swaggerapi/swagger-ui
If you also want to validate your schema add the --validate flag. Or serve your schema directly from your API. We also provide convenience wrappers for swagger-ui or redoc.
from drf_spectacular.views import SpectacularAPIView
urlpatterns = [
# YOUR PATTERNS
path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
# Optional UI:
path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
]
drf-spectacular works pretty well out of the box. You might also want to set some metadata for your API.
Just create a SPECTACULAR_SETTINGS
dictionary in your settings.py
and override the defaults.
Have a look at the available settings.
The toy examples do not cover your cases? No problem, you can heavily customize how your schema will be rendered.
Most customization cases should be covered by the extend_schema
decorator. We usually get
pretty far with specifying OpenApiParameter
and splitting request/response serializers, but
the sky is the limit.
from drf_spectacular.utils import extend_schema, OpenApiParameter
from drf_spectacular.types import OpenApiTypes
class AlbumViewset(viewset.ModelViewset)
serializer_class = AlbumSerializer
@extend_schema(
request=AlbumCreationSerializer
responses={201: AlbumSerializer},
)
def create(self, request):
# your non-standard behaviour
return super().create(request)
@extend_schema(
# extra parameters added to the schema
parameters=[
OpenApiParameter(name='artist', description='Filter by artist', required=False, type=str),
OpenApiParameter(
name='release',
type=OpenApiTypes.DATE,
location=OpenApiParameter.QUERY,
description='Filter by release date',
),
],
# override default docstring extraction
description='More descriptive text',
# provide Authentication class that deviates from the views default
auth=None,
# change the auto-generated operation name
operation_id=None,
# or even completely override what AutoSchema would generate. Provide raw Open API spec as Dict.
operation=None,
)
def list(self, request):
# your non-standard behaviour
return super().list(request)
@extend_schema(
request=AlbumLikeSerializer
responses={204: None},
)
@action(detail=True, methods=['post'])
def set_password(self, request, pk=None):
# your action behaviour
Still not satisifed? You want more! We still got you covered. Visit customization for more information.
Install testing requirements.
$ pip install -r requirements.txt
Run with runtests.
$ ./runtests.py
You can also use the excellent tox testing tool to run the tests against all supported versions of Python and Django. Install tox globally, and then simply run:
$ tox