drf-spectacular
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
- 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.
License
Provided by T. Franzel, Cashlink Technologies GmbH. Licensed under 3-Clause BSD.
Requirements
- Python >= 3.6
- Django (2.2, 3.0)
- Django REST Framework (3.10, 3.11)
Installation
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',
}
Take it for a spin
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'),
]
Usage
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.
@extend_schema
Customization by using 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
More customization
Still not satisifed? You want more! We still got you covered. Visit customization for more information.
Testing
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