Skip to content
Back to top
View this page

# 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:

  - `ANY` for which you can use `typing.Any`.

  - `DURATION` for which you can use `datetime.timedelta`.

  - `HOSTNAME`

  - `IDN_EMAIL`

  - `IDN_HOSTNAME`

  - `IRI_REF`

  - `IRI`

  - `JSON_PTR_REL`

  - `JSON_PTR`

  - `NONE` for which you can use `None`.

  - `REGEX`

  - `TIME` for which you can use `datetime.time`.

  - `URI_REF`

  - `URI_TPL`

## 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