Add OpenAPIRenderer by default, and add schema docs. (#6233)

* Add OpenAPIRenderer as a default for get_schema_view, and start adding schema docs

* Add optional pyyaml

* Updating schema docs
This commit is contained in:
Tom Christie 2018-10-04 14:05:55 +01:00 committed by GitHub
parent 18ad3290ef
commit 6522d4ae20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 56 deletions

View File

@ -10,12 +10,50 @@ API schemas are a useful tool that allow for a range of use cases, including
generating reference documentation, or driving dynamic client libraries that
can interact with your API.
## Install Core API
## Install Core API & PyYAML
You'll need to install the `coreapi` package in order to add schema support
for REST framework.
for REST framework. You probably also want to install `pyyaml`, so that you
can render the schema into the commonly used YAML-based OpenAPI format.
pip install coreapi
pip install coreapi pyyaml
## Quickstart
There are two different ways you can serve a schema description for you API.
### Generating a schema with the `generateschema` management command
To generate a static API schema, use the `generateschema` management command.
```shell
$ python manage.py generateschema > schema.yml
```
Once you've generated a schema in this way you can annotate it with any
additional information that cannot be automatically inferred by the schema
generator.
You might want to check your API schema into version control and update it
with each new release, or serve the API schema from your site's static media.
### Adding a view with `get_schema_view`
To add a dynamically generated schema view to your API, use `get_schema_view`.
```python
from rest_framework.schemas import get_schema_view
schema_view = get_schema_view(title="Example API")
urlpatterns = [
url('^schema$', schema_view),
...
]
```
See below [for more details](#the-get_schema_view-shortcut) on customizing a
dynamically generated schema view.
## Internal schema representation
@ -71,38 +109,19 @@ endpoint:
In order to be presented in an HTTP response, the internal representation
has to be rendered into the actual bytes that are used in the response.
REST framework includes a few different renderers that you can use for
encoding the API schema.
* `renderers.OpenAPIRenderer` - Renders into YAML-based [OpenAPI][openapi], the most widely used API schema format.
* `renderers.JSONOpenAPIRenderer` - Renders into JSON-based [OpenAPI][openapi].
* `renderers.CoreJSONRenderer` - Renders into [Core JSON][corejson], a format designed for
use with the `coreapi` client library.
[Core JSON][corejson] is designed as a canonical format for use with Core API.
REST framework includes a renderer class for handling this media type, which
is available as `renderers.CoreJSONRenderer`.
### Alternate schema formats
Other schema formats such as [Open API][open-api] ("Swagger"),
[JSON HyperSchema][json-hyperschema], or [API Blueprint][api-blueprint] can also
be supported by implementing a custom renderer class that handles converting a
`Document` instance into a bytestring representation.
If there is a Core API codec package that supports encoding into the format you
want to use then implementing the renderer class can be done by using the codec.
#### Example
For example, the `openapi_codec` package provides support for encoding or decoding
to the Open API ("Swagger") format:
from rest_framework import renderers
from openapi_codec import OpenAPICodec
class SwaggerRenderer(renderers.BaseRenderer):
media_type = 'application/openapi+json'
format = 'swagger'
def render(self, data, media_type=None, renderer_context=None):
codec = OpenAPICodec()
return codec.dump(data)
## Schemas vs Hypermedia
@ -325,13 +344,12 @@ ROOT_URLCONF setting.
May be used to pass the set of renderer classes that can be used to render the API root endpoint.
from rest_framework.schemas import get_schema_view
from rest_framework.renderers import CoreJSONRenderer
from my_custom_package import APIBlueprintRenderer
from rest_framework.renderers import JSONOpenAPIRenderer
schema_view = get_schema_view(
title='Server Monitoring API',
url='https://www.example.org/api/',
renderer_classes=[CoreJSONRenderer, APIBlueprintRenderer]
renderer_classes=[JSONOpenAPIRenderer]
)
#### `patterns`
@ -364,7 +382,6 @@ Defaults to `settings.DEFAULT_AUTHENTICATION_CLASSES`
May be used to specify the list of permission classes that will apply to the schema endpoint.
Defaults to `settings.DEFAULT_PERMISSION_CLASSES`
## Using an explicit schema view
If you need a little more control than the `get_schema_view()` shortcut gives you,
@ -386,7 +403,7 @@ return the schema.
generator = schemas.SchemaGenerator(title='Bookings API')
@api_view()
@renderer_classes([renderers.CoreJSONRenderer])
@renderer_classes([renderers.OpenAPIRenderer])
def schema_view(request):
schema = generator.get_schema(request)
return response.Response(schema)
@ -408,7 +425,7 @@ In order to present a schema with endpoints filtered by user permissions,
you need to pass the `request` argument to the `get_schema()` method, like so:
@api_view()
@renderer_classes([renderers.CoreJSONRenderer])
@renderer_classes([renderers.OpenAPIRenderer])
def schema_view(request):
generator = schemas.SchemaGenerator(title='Bookings API')
return response.Response(generator.get_schema(request=request))
@ -432,21 +449,10 @@ representation.
)
@api_view()
@renderer_classes([renderers.CoreJSONRenderer])
@renderer_classes([renderers.OpenAPIRenderer])
def schema_view(request):
return response.Response(schema)
## Static schema file
A final option is to write your API schema as a static file, using one
of the available formats, such as Core JSON or Open API.
You could then either:
* Write a schema definition as a static file, and [serve the static file directly][static-files].
* Write a schema definition that is loaded using `Core API`, and then
rendered to one of many available formats, depending on the client request.
---
# Schemas as documentation
@ -535,7 +541,7 @@ Arguments:
Returns a `coreapi.Document` instance that represents the API schema.
@api_view
@renderer_classes([renderers.CoreJSONRenderer])
@renderer_classes([renderers.OpenAPIRenderer])
def schema_view(request):
generator = schemas.SchemaGenerator(title='Bookings API')
return Response(generator.get_schema())

View File

@ -5,3 +5,4 @@ django-guardian==1.4.9
django-filter==1.1.0
coreapi==2.3.1
coreschema==0.0.4
pyyaml

View File

@ -19,13 +19,12 @@ class SchemaView(APIView):
def __init__(self, *args, **kwargs):
super(SchemaView, self).__init__(*args, **kwargs)
if self.renderer_classes is None:
if renderers.BrowsableAPIRenderer in api_settings.DEFAULT_RENDERER_CLASSES:
self.renderer_classes = [
renderers.CoreJSONRenderer,
renderers.BrowsableAPIRenderer,
renderers.OpenAPIRenderer,
renderers.CoreJSONRenderer
]
else:
self.renderer_classes = [renderers.CoreJSONRenderer]
if renderers.BrowsableAPIRenderer in api_settings.DEFAULT_RENDERER_CLASSES:
self.renderer_classes += [renderers.BrowsableAPIRenderer]
def get(self, request, *args, **kwargs):
schema = self.schema_generator.get_schema(request, self.public)