Skip to content

Commit

Permalink
Added url and schema_url arguments (#4321)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomchristie authored Jul 28, 2016
1 parent 6a7d34e commit 061e0ed
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 11 deletions.
20 changes: 17 additions & 3 deletions docs/api-guide/schemas.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,11 @@ that include the Core JSON media type in their `Accept` header.
This is a great zero-configuration option for when you want to get up and
running really quickly.

The only other available option to `DefaultRouter` is `schema_renderers`, which
may be used to pass the set of renderer classes that can be used to render
schema output.
The other available options to `DefaultRouter` are:

#### schema_renderers

May be used to pass the set of renderer classes that can be used to render schema output.

from rest_framework.renderers import CoreJSONRenderer
from my_custom_package import APIBlueprintRenderer
Expand All @@ -139,6 +141,17 @@ schema output.
CoreJSONRenderer, APIBlueprintRenderer
])

#### schema_url

May be used to pass the root URL for the schema. This can either be used to ensure that
the schema URLs include a canonical hostname and schema, or to ensure that all the
schema URLs include a path prefix.

router = DefaultRouter(
schema_title='Server Monitoring API',
schema_url='https://www.example.org/api/'
)

If you want more flexibility over the schema output then you'll need to consider
using `SchemaGenerator` instead.

Expand Down Expand Up @@ -264,6 +277,7 @@ Typically you'll instantiate `SchemaGenerator` with a single argument, like so:
Arguments:

* `title` - The name of the API. **required**
* `url` - The root URL of the API schema. This option is not required unless the schema is included under path prefix.
* `patterns` - A list of URLs to inspect when generating the schema. Defaults to the project's URL conf.
* `urlconf` - A URL conf module name to use when generating the schema. Defaults to `settings.ROOT_URLCONF`.

Expand Down
6 changes: 6 additions & 0 deletions rest_framework/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
from django.utils import importlib # Will be removed in Django 1.9


try:
import urlparse # Python 2.x
except ImportError:
import urllib.parse as urlparse


def unicode_repr(instance):
# Get the repr of an instance, but ensure it is a unicode string
# on both python 3 (already the case) and 2 (not the case).
Expand Down
12 changes: 8 additions & 4 deletions rest_framework/routers.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,11 +278,14 @@ class DefaultRouter(SimpleRouter):
def __init__(self, *args, **kwargs):
if 'schema_renderers' in kwargs:
assert 'schema_title' in kwargs, 'Missing "schema_title" argument.'
if 'schema_url' in kwargs:
assert 'schema_title' in kwargs, 'Missing "schema_title" argument.'
self.schema_title = kwargs.pop('schema_title', None)
self.schema_url = kwargs.pop('schema_url', None)
self.schema_renderers = kwargs.pop('schema_renderers', self.default_schema_renderers)
super(DefaultRouter, self).__init__(*args, **kwargs)

def get_api_root_view(self, schema_urls=None):
def get_api_root_view(self, api_urls=None):
"""
Return a view to use as the API root.
"""
Expand All @@ -294,11 +297,12 @@ def get_api_root_view(self, schema_urls=None):
view_renderers = list(api_settings.DEFAULT_RENDERER_CLASSES)
schema_media_types = []

if schema_urls and self.schema_title:
if api_urls and self.schema_title:
view_renderers += list(self.schema_renderers)
schema_generator = SchemaGenerator(
title=self.schema_title,
patterns=schema_urls
url=self.schema_url,
patterns=api_urls
)
schema_media_types = [
renderer.media_type
Expand Down Expand Up @@ -347,7 +351,7 @@ def get_urls(self):
urls = super(DefaultRouter, self).get_urls()

if self.include_root_view:
view = self.get_api_root_view(schema_urls=urls)
view = self.get_api_root_view(api_urls=urls)
root_url = url(r'^$', view, name=self.root_view_name)
urls.append(root_url)

Expand Down
12 changes: 8 additions & 4 deletions rest_framework/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from django.utils import six

from rest_framework import exceptions, serializers
from rest_framework.compat import coreapi, uritemplate
from rest_framework.compat import coreapi, uritemplate, urlparse
from rest_framework.request import clone_request
from rest_framework.views import APIView

Expand Down Expand Up @@ -57,7 +57,7 @@ class SchemaGenerator(object):
'delete': 'destroy',
}

def __init__(self, title=None, patterns=None, urlconf=None):
def __init__(self, title=None, url=None, patterns=None, urlconf=None):
assert coreapi, '`coreapi` must be installed for schema support.'

if patterns is None and urlconf is not None:
Expand All @@ -70,7 +70,11 @@ def __init__(self, title=None, patterns=None, urlconf=None):
urls = import_module(settings.ROOT_URLCONF)
patterns = urls.urlpatterns

if url and not url.endswith('/'):
url += '/'

self.title = title
self.url = url
self.endpoints = self.get_api_endpoints(patterns)

def get_schema(self, request=None):
Expand Down Expand Up @@ -102,7 +106,7 @@ def get_schema(self, request=None):
insert_into(content, key, link)

# Return the schema document.
return coreapi.Document(title=self.title, content=content)
return coreapi.Document(title=self.title, content=content, url=self.url)

def get_api_endpoints(self, patterns, prefix=''):
"""
Expand Down Expand Up @@ -203,7 +207,7 @@ def get_link(self, path, method, callback):
encoding = None

return coreapi.Link(
url=path,
url=urlparse.urljoin(self.url, path),
action=method.lower(),
encoding=encoding,
fields=fields
Expand Down

0 comments on commit 061e0ed

Please sign in to comment.