|
|
||
|---|---|---|
| drf_swagger | ||
| screenshots | ||
| testproj | ||
| .gitignore | ||
| LICENSE | ||
| MANIFEST.in | ||
| README.md | ||
| package-lock.json | ||
| package.json | ||
| requirements.txt | ||
| requirements_dev.txt | ||
| requirements_test.txt | ||
| requirements_validation.txt | ||
| setup.py | ||
README.md
drf-swagger - Yet another Swagger generator for Django Rest Framework
WARNING: this project is under rapid development; the APIs described here might change at any time without notice
Background
OpenAPI 2.0, 'formerly known as' Swagger, is a format designed to encode information about a Web API into an
easily parsable schema that can then be used for rendering documentation, generating code, etc.
More details are available on swagger.io and on the OpenAPI 2.0 specification page.
From here on, the terms "OpenAPI" and "Swagger" are used interchangeably.
Swagger in Django Rest Framework
Since Django Rest 3.7, there is now built in support for automatic OpenAPI (Swagger) 2.0 schema generation. However, this generation is based on the coreapi standard, which for the moment is vastly inferior to OpenAPI in both support and features. In particular, the OpenAPI codec/compatibility layer provided has a few major problems:
- there is no support for documenting response schemas and status codes
- nested schemas do not work properly
- does not handle more complex fields such as
FileField,ChoiceField, ...
In short this makes the generated schema unusable for code generation, and mediocre at best for documentation.
Third-party libraries
There are currently two decent Swagger schema generators that I could find for django-rest-framework:
Out of the two, django-rest-swagger is just a wrapper around DRF 3.7 schema generation with an added UI, and thus has
the same problems. drf-openapi is a bit more involved and implements some custom handling for response schemas, but
ultimately still falls short in code generation because the responses are plain objects.
Both projects are also relatively dead and stagnant.
Table of contents
Design
Aim
This project aims for full compatibility with Swagger/OpenAPI 2.0 code generation tools. More precisely, this means:
- support documentation of response schemas for multiple possible status codes
- support unbounded schema nesting
- generate real OpenAPI Schema definitions instead of inline models
- allow easy and pluggable manual overrides for all schema components
Implementation progress
For the first release, most of django-rest-swagger's functionality is implemented. A lot of inspiration and code was
drawn from the existing implementations mentioned above, so thanks are due to their respective authors.
Features
- schema generation is a wrapper around coreapi & drf
- bundled latest version of swagger-ui and redoc
- supports dumping of schema in JSON and YAML
- schema view is cacheable out of the box
- generated Swagger schema can be automatically validated by flex or swagger-spec-validator
Usage
1. Quickstart
In settings.py:
INSTALLED_APPS = [
...
'drf_swagger',
...
]
In urls.py:
...
from drf_swagger.views import get_schema_view
from drf_swagger import openapi
...
schema_view = get_schema_view(
openapi.Info(
title="Snippets API",
default_version='v1',
description="Test description",
terms_of_service="https://www.google.com/policies/terms/",
contact=openapi.Contact(email="contact@snippets.local"),
license=openapi.License(name="BSD License"),
),
validators=['flex', 'ssv'],
public=False,
permission_classes=(permissions.AllowAny,),
)
urlpatterns = [
url(r'^swagger(?P<format>.json|.yaml)$', schema_view.without_ui(cache_timeout=None), name='schema-json'),
url(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=None), name='schema-swagger-ui'),
url(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=None), name='schema-redoc'),
...
]
You've just created:
- A JSON view of your schema at
/swagger.json - A YAML view of your schema at
/swagger.yaml - A swagger-ui view of your schema at
/swagger/ - A ReDoc view of your schema at
/redoc/
2. Configuration
a. get_schema_view parameters
info- Required. Swagger API Info objecturl- API base url; if left blank will be deduced from the location the view is served atpatterns- passed to SchemaGeneratorurlconf- passed to SchemaGeneratorpublic- if False, includes only endpoints the current user has access tovalidators- a list of validator names to apply on the generated schema; allowed values areflex,ssvauthentication_classes- authentication classes for the schema view itselfpermission_classes- permission classes for the schema view itself
b. SchemaView instantiators
SchemaView.with_ui(renderer, ...)- get a view instance using the specified UI renderer; one ofswagger,redocSchemaView.without_ui(...)- get a view instance with no UI renderer; same asas_cached_viewwith no kwargsSchemaView.as_cached_view(...)- same asas_view, but with optional caching- you can, of course, call
as_viewas usual
All of the first 3 methods take two optional arguments, cache_timeout and cache_kwargs; if present, these are
passed on to Django's cached_page decorator in order to enable caching on the resulting viewl.
See 4. Caching.
c. SWAGGER_SETTINGS and REDOC_SETTINGS
Additionally, you can include some more settings in your settings.py file.
The possible settings and their default values are as follows:
SWAGGER_SETTINGS = {
'USE_SESSION_AUTH': True, # add Django Login and Django Logout buttons, CSRF token to swagger UI page
'LOGIN_URL': getattr(django.conf.settings, 'LOGIN_URL', None), # URL for the login button
'LOGOUT_URL': getattr(django.conf.settings, 'LOGOUT_URL', None), # URL for the logout button
# Swagger security definitions to include in the schema;
# see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#security-definitions-object
'SECURITY_DEFINITIONS': {
'basic': {
'type': 'basic'
}
},
# url to an external Swagger validation service; defaults to 'http://online.swagger.io/validator/'
# set to None to disable the schema validation badge in the UI
'VALIDATOR_URL': '',
# swagger-ui configuration settings, see https://github.com/swagger-api/swagger-ui#parameters of the same name
'OPERATIONS_SORTER': None,
'TAGS_SORTER': None,
'DOC_EXPANSION': 'list',
'DEEP_LINKING': False,
'SHOW_EXTENSIONS': True,
'DEFAULT_MODEL_RENDERING': 'model',
'DEFAULT_MODEL_DEPTH': 2,
}
REDOC_SETTINGS = {
# ReDoc UI configuration settings, see https://github.com/Rebilly/ReDoc#redoc-tag-attributes
'LAZY_RENDERING': True,
'HIDE_HOSTNAME': False,
'EXPAND_RESPONSES': 'all',
'PATH_IN_MIDDLE': False,
}
3. More customization
Should you have need of more fine-grained customization over the schema view and generation, you are on your own to figure out where you need to subclass and plug your functionality. Here are a few high-level hints:
-
OpenAPISchemaGeneratorenumerates all the API endpoints registered in Django Rest Framework, inspects their view classes and generates an appropriateSwaggerobject describing the API structure -
SchemaViewgets adrf_swagger.openapi.Swaggerschema object from a generator and renders it into an HTTP response- you can subclass
SchemaViewby extending the return value ofget_schema_view, e.g.:SchemaView = get_schema_view(info, ...) class CustomSchemaView(SchemaView): generator_class = CustomSchemaGenerator renderer_classes = (CustomRenderer1, CustomRenderer2,)
- you can subclass
-
drf_swagger.rendererstake aSwaggerobject and transform it into an OpenAPI 2.0 specification document usingOpenAPICodecJson,OpenAPICodecYaml, or into a web interface using an OpenAPI renderer library. -
drf_swagger.codecstake aSwaggerobject and encode it in an exportable format (json or yaml by default).
4. Caching
Since the schema does not usually change during the lifetime of the django process, there is out of the box support for caching the schema view in-memory, with some sane defaults:
- caching is enabled by the
cache_pagedecorator, using the default Django cache backend but this can be changed using thecache_kwargsargument - HTTP caching of the response is blocked to avoid confusing situations caused by being served stale schemas
- the cached schema varies on the
CookieandAuthorizationHTTP headers to enable filtering of visible endpoints according to the authentication credentials of each user; note that this means that every user accessing the schema will have a separate schema cached in memory.
5. Validation
Given the numerous methods to manually customzie the generated schema, it makes sense to validate the result to ensure
it still conforms to OpenAPI 2.0. To this end, validation is provided at the generation point using python swagger
libraries, and can be activated by passing validators=['flex', 'ssv'] to get_schema_view; if the generated schema
is not valid, a SwaggerValidationError is raised by the handling codec and nothing is returned.
Warning: This internal validation is quite slow and can be a DOS vector if left activated on a publicly available view.
Caching can mitigate the speed impact of validation on restricted views.
The provided validation will catch syntactic errors, but more subtle violations of the spec might slip by them. To ensure compatibility with code generation tools, it is recommended to also employ one or more of the following methods:
-
swagger-uivalidation badgeOnline
If your schema is publicly accessible,
swagger-uiwill automatically validate it against the official swagger online validator and display the result in the bottom-right validation badge.Offline
If your schema is not accessible from the internet, you can run a local copy of swagger-validator and set the
VALIDATOR_URLaccordingly:SWAGGER_SETTINGS = { ... 'VALIDATOR_URL': 'http://localhost:8189', ... }$ docker run --name swagger-validator -d -p 8189:8080 --add-host test.local:10.0.75.1 swaggerapi/swagger-validator 84dabd52ba967c32ae6b660934fa6a429ca6bc9e594d56e822a858b57039c8a2 $ curl http://localhost:8189/debug?url=http://test.local:8002/swagger/?format=openapi {} -
using
swagger-clihttps://www.npmjs.com/package/swagger-cli
$ npm install -g swagger-cli [...] $ swagger-cli validate http://test.local:8002/swagger.yaml http://test.local:8002/swagger.yaml is valid -
manually, on
editor.swagger.ioImporting the generated spec into https://editor.swagger.io/ will automatically trigger validation on it.
Planned feature support
- OpenAPI 3.0 - if I get 2.0 working like I want, and it's not too hard to adapt to 3.0

