Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added url and schema_url arguments. #4321

Merged
merged 1 commit into from Jul 28, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 17 additions & 3 deletions docs/api-guide/schemas.md
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
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
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
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