Skip to main content

build-status codecov docs pypi-version pypi-dl

Sane and flexible OpenAPI (3.0.3, 3.1 & 3.2) schema generation for Django REST framework.

This project has 3 goals:
  1. Extract as much schema information from DRF as possible.

  2. Provide flexibility to make the schema usable in the real world (not only toy examples).

  3. 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

For more information visit the documentation.

License

Provided by T. Franzel. Licensed under 3-Clause BSD.

Requirements

  • Python >= 3.8

  • Django (3.2, 4.0, 4.1, 4.2, 5.0, 5.1, 5.2, 6.0)

  • Django REST Framework (3.12, 3.13, 3.14, 3.15, 3.16, 3.17)

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',
}

drf-spectacular ships with sane default settings that should work reasonably well out of the box. It is not necessary to specify any settings, but we recommend to specify at least some metadata.

SPECTACULAR_SETTINGS = {
    'TITLE': 'Your Project API',
    'DESCRIPTION': 'Your project description',
    'VERSION': '1.0.0',
    'SERVE_INCLUDE_SCHEMA': False,
    # OTHER SETTINGS
}

Self-contained UI installation

Certain environments have no direct access to the internet and as such are unable to retrieve Swagger UI or Redoc from CDNs. drf-spectacular-sidecar provides these static files as a separate optional package. Usage is as follows:

$ pip install drf-spectacular[sidecar]
INSTALLED_APPS = [
    # ALL YOUR APPS
    'drf_spectacular',
    'drf_spectacular_sidecar',  # required for Django collectstatic discovery
]
SPECTACULAR_SETTINGS = {
    'SWAGGER_UI_DIST': 'SIDECAR',  # shorthand to use the sidecar instead
    'SWAGGER_UI_FAVICON_HREF': 'SIDECAR',
    'REDOC_DIST': 'SIDECAR',
    # OTHER SETTINGS
}

Release management

drf-spectacular deliberately stays below version 1.x.x to signal that every new version may potentially break you. For production we strongly recommend pinning the version and inspecting a schema diff on update.

With that said, we aim to be extremely defensive w.r.t. breaking API changes. However, we also acknowledge the fact that even slight schema changes may break your toolchain, as any existing bug may somehow also be used as a feature.

We define version increments with the following semantics. y-stream increments may contain potentially breaking changes to both API and schema. z-stream increments will never break the API and may only contain schema changes that should have a low chance of breaking you.

Take it for a spin

Generate your schema with the CLI:

$ ./manage.py spectacular --color --file schema.yml
$ docker run -p 8080: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, SpectacularRedocView, SpectacularSwaggerView
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.

Customization by using @extend_schema

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, OpenApiExample
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',
                examples=[
                    OpenApiExample(
                        'Example 1',
                        summary='short optional summary',
                        description='longer description',
                        value='1993-08-23'
                    ),
                    ...
                ],
            ),
        ],
        # 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,
        # attach request/response examples to the operation.
        examples=[
            OpenApiExample(
                'Example 1',
                description='longer description',
                value=...
            ),
            ...
        ],
    )
    def list(self, request):
        # your non-standard behaviour
        return super().list(request)

    @extend_schema(
        request=AlbumLikeSerializer,
        responses={204: None},
        methods=["POST"]
    )
    @extend_schema(description='Override a specific method', methods=["GET"])
    @action(detail=True, methods=['post', 'get'])
    def set_password(self, request, pk=None):
        # your action behaviour
        ...

More customization

Still not satisfied? 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

Metadata

Release files for drf-spectacular 0.30.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for drf-spectacular 0.30.0
File Size Uploaded Provenance
drf_spectacular-0.30.0.tar.gz 252.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for drf-spectacular 0.30.0
File Interpreter ABI Platform
drf_spectacular-0.30.0-py3-none-any.whl Python 3 none any Details

Total release size: 363.5 kB

Release files / drf_spectacular-0.30.0.tar.gz

Download URL drf_spectacular-0.30.0.tar.gz
Size 252.3 kB
Tags Source
SHA-256 checksum
How to use checksums
53e79e7ba00e240441b63c32273754a5368e4c2ab44a19f2595277cc1cd559c9
BLAKE2b-256 checksum
How to use checksums
504341d25039a6a53545420ebc98eb9f877ec9fe30c7bd03fefabcaf9b953af7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Release files / drf_spectacular-0.30.0-py3-none-any.whl

Download URL drf_spectacular-0.30.0-py3-none-any.whl
Size 111.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
006cf5921ebe20a9bd24f7c846261ebbf78780be5961b0d6e87afaa82afd62ff
BLAKE2b-256 checksum
How to use checksums
c35674dd7b45bbde6d24494220b98d6961cb1200b63a1800332b430daa2c4551
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Security for drf-spectacular 0.30.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.30.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page