From drf-yasg to OpenAPI 3

drf-yasg is an excellent library and the most popular choice for generating OpenAPI 2.0 (formerly known as Swagger 2.0) schemas with Django REST Framework. Unfortunately, it currently does not provide support for OpenAPI 3.x. Migration from drf-yasg to drf-spectacular requires some modifications, the complexity of which depends on what features are being used.

Note

In contrast to drf-yasg, we don’t package Redoc & Swagger UI but serve them via hyperlinked CDNs instead. If you want or need to serve those files yourself, you can do that with the optional drf-spectacular-sidecar package. See installation instructions for further details.

Decorators

  • @swagger_auto_schema is largely equivalent to @extend_schema.

    • operation_description argument is called description

    • operation_summary argument is called summary

    • manual_parameters and query_serializer arguments are merged into a single parameters argument

    • security argument is called auth

    • request_body arguments is called request

      • Use None instead of drf_yasg.utils.no_body

    • method argument doesn’t exist, use methods instead (also supported by drf-yasg)

    • auto_schema has no equivalent.

    • extra_overrides has no equivalent.

    • field_inspectors has no equivalent.

    • filter_inspectors has no equivalent.

    • paginator_inspectors has no equivalent.

    • Additional arguments are also available: exclude, operation, versions, examples.

  • @swagger_serializer_method is equivalent to @extend_schema_field.

    • component_name can be provided to break the field out as a separate component.

  • @extend_schema_serializer is available for overriding behavior of serializers.

  • Instead of using @method_decorator, use @extend_schema_view.

  • Instead of using swagger_schema_field, use @extend_schema_field or @extend_schema_serializer.

Helper Classes

  • Parameter is roughly equivalent to OpenApiParameter.

    • in_ argument is called location.

    • schema argument should be passed as type.

    • format argument is merged into type argument by using OpenApiTypes.

    • setting the many argument to True causes the argument to take an array of values, and generates a schema similar to using the drf_yasg Items class on the items property. The type of the items in the array are defined by the type argument.

  • Response is largely identical to OpenApiResponse.

    • schema argument is called response

    • Order of arguments differs, so use keyword arguments.

  • OpenApiExample is available for providing examples to @extend_schema.

  • Schema is not required and can be eliminated. Use a plain dict instead.

Types & Formats

In place of separate drf_yasg.openapi.TYPE_* and drf_yasg.openapi.FORMAT_* constants, drf-spectacular provides the OpenApiTypes enum:

  • TYPE_BOOLEAN is called BOOL, but you can use bool.

  • TYPE_FILE should be replaced by BINARY

  • TYPE_INTEGER is called INT, but you can use int.

  • TYPE_INTEGER with FORMAT_INT32 is called INT32

  • TYPE_INTEGER with FORMAT_INT64 is called INT64

  • TYPE_NUMBER is called NUMBER

  • TYPE_NUMBER with FORMAT_FLOAT is called FLOAT, but you can use float.

  • TYPE_NUMBER with FORMAT_DOUBLE is called DOUBLE (or DECIMAL, but you can use Decimal)

  • TYPE_OBJECT is called OBJECT, but you can use dict.

  • TYPE_STRING is called STR, but you can use str.

  • TYPE_STRING with FORMAT_BASE64 is called BYTE (which is base64 encoded).

  • TYPE_STRING with FORMAT_BINARY is called BINARY, but you can use bytes.

  • TYPE_STRING with FORMAT_DATETIME is called DATETIME, but you can use datetime.datetime.

  • TYPE_STRING with FORMAT_DATE is called DATE, but you can use datetime.date.

  • TYPE_STRING with FORMAT_EMAIL is called EMAIL

  • TYPE_STRING with FORMAT_IPV4 is called IP4, but you can use ipaddress.IPv4Address.

  • TYPE_STRING with FORMAT_IPV6 is called IP6, but you can use ipaddress.IPv6Address.

  • TYPE_STRING with FORMAT_PASSWORD is called PASSWORD

  • TYPE_STRING with FORMAT_URI is called URI

  • TYPE_STRING with FORMAT_UUID is called UUID, but you can use uuid.UUID.

  • TYPE_STRING with FORMAT_SLUG has no direct equivalent. Use STR or str instead.

  • TYPE_ARRAY is handled by providing OpenApiParameter with many=True as a parameter. There is no need to set the items property on the parameter - the presence of many=True turns the parameter into an array parameter.

  • The following additional types are also available:

Parameter Location

drf_yasg.openapi.IN_* constants are roughly equivalent to constants defined on the OpenApiParameter class:

  • IN_PATH is called PATH

  • IN_QUERY is called QUERY

  • IN_HEADER is called HEADER

  • IN_BODY and IN_FORM have no direct equivalent. Instead you can use @extend_schema(request={"<media-type>": ...}).

  • COOKIE is also available.

Docstring Parsing

drf-yasg has some special handling for docstrings that is not supported by drf-spectacular.

It attempts to split the first line from the rest of the docstring to use as the operation summary, and the remainder is used as the operation description. drf-spectacular uses the entire docstring as the description. Use the summary and description arguments of @extend_schema instead. Optionally, the docstring can still be used to populate the operation description.

# Supported by drf-yasg:
class UserViewSet(ViewSet):
    def list(self, request):
        """
        List all the users.

        Return a list of all usernames in the system.
        """
        ...

# Updated for drf-spectacular using decorator for description:
class UserViewSet(ViewSet):
    @extend_schema(
        summary="List all the users.",
        description="Return a list of all usernames in the system.",
    )
    def list(self, request):
        ...

# Updated for drf-spectacular using docstring for description:
class UserViewSet(ViewSet):
    @extend_schema(summary="List all the users.")
    def list(self, request):
        """Return a list of all usernames in the system."""
        ...

In addition, drf-yasg also supports named sections, but these are not supported by drf-spectacular. Again, use the summary and description arguments of @extend_schema instead:

# Supported by drf-yasg:
class UserViewSet(ViewSet):
    """
    list:
        List all the users.

        Return a list of all usernames in the system.

    retrieve:
        Retrieve user

        Get details of a specific user
    """
    ...

# Updated for drf-spectacular using decorator for description:
@extend_schema_view(
    list=extend_schema(
        summary="List all the users.",
        description="Return a list of all usernames in the system.",
    ),
    retrieve=extend_schema(
        summary="Retrieve user",
        description="Get details of a specific user",
    ),
)
class UserViewSet(ViewSet):
    ...

Authentication

In drf-yasg it was necessary to manually describe authentication schemes.

In drf-spectacular there is support for auto-generating the security definitions for a number of authentication classes built in to DRF as well as other popular third-party packages. OpenApiAuthenticationExtension is available to help tie in custom authentication clasees – see the customization guide.

Compatibility

For compatibility, the following features of drf-yasg have been implemented:

  • ref_name on Serializer Meta classes is supported (excluding inlining with ref_name=None)

    • See drf-yasg’s documentation for further details.

    • The equivalent in drf-spectacular is @extend_schema_serializer(component_name="...")

  • swagger_fake_view is available as attribute on views to signal schema generation