mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-05 04:50:12 +03:00
API docs tweaks
This commit is contained in:
parent
c412de920e
commit
5c99e7e01e
63
docs/topics/3.6-announcement.md
Normal file
63
docs/topics/3.6-announcement.md
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
<style>
|
||||||
|
.promo li a {
|
||||||
|
float: left;
|
||||||
|
width: 130px;
|
||||||
|
height: 20px;
|
||||||
|
text-align: center;
|
||||||
|
margin: 10px 30px;
|
||||||
|
padding: 150px 0 0 0;
|
||||||
|
background-position: 0 50%;
|
||||||
|
background-size: 130px auto;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
font-size: 120%;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
.promo li {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
# Django REST framework 3.6
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Funding
|
||||||
|
|
||||||
|
The 3.6 release would not have been possible without our [collaborative funding model][funding].
|
||||||
|
If you use REST framework commercially and would like to see this work continue,
|
||||||
|
we strongly encourage you to invest in its continued development by
|
||||||
|
**[signing up for a paid plan][funding]**.
|
||||||
|
|
||||||
|
<ul class="premium-promo promo">
|
||||||
|
<li><a href="http://jobs.rover.com/" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/rover_130x130.png)">Rover.com</a></li>
|
||||||
|
<li><a href="https://getsentry.com/welcome/" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/sentry130.png)">Sentry</a></li>
|
||||||
|
<li><a href="https://getstream.io/try-the-api/?utm_source=drf&utm_medium=banner&utm_campaign=drf" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/stream-130.png)">Stream</a></li>
|
||||||
|
<li><a href="https://hello.machinalis.co.uk/" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/Machinalis130.png)">Machinalis</a></li>
|
||||||
|
<li><a href="https://rollbar.com" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/rollbar.png)">Rollbar</a></li>
|
||||||
|
<li><a href="https://micropyramid.com/django-rest-framework-development-services/" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/mp-text-logo.png)">MicroPyramid</a></li>
|
||||||
|
</ul>
|
||||||
|
<div style="clear: both; padding-bottom: 20px;"></div>
|
||||||
|
|
||||||
|
*Many thanks to all our [sponsors][sponsors], and in particular to our premium backers, [Rover](http://jobs.rover.com/), [Sentry](https://getsentry.com/welcome/), [Stream](https://getstream.io/?utm_source=drf&utm_medium=banner&utm_campaign=drf), [Machinalis](https://hello.machinalis.co.uk/), [Rollbar](https://rollbar.com), and [MicroPyramid](https://micropyramid.com/django-rest-framework-development-services/).*
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## API documentation
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
## JavaScript Client
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Deprecations
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
[sponsors]: https://fund.django-rest-framework.org/topics/funding/#our-sponsors
|
||||||
|
[funding]: funding.md
|
|
@ -6,9 +6,13 @@
|
||||||
|
|
||||||
There are a variety of approaches to API documentation. This document introduces a few of the various tools and options you might choose from. The approaches should not be considered exclusive - you may want to provide more than one documentation style for you API, such as a self describing API that also includes static documentation of the various API endpoints.
|
There are a variety of approaches to API documentation. This document introduces a few of the various tools and options you might choose from. The approaches should not be considered exclusive - you may want to provide more than one documentation style for you API, such as a self describing API that also includes static documentation of the various API endpoints.
|
||||||
|
|
||||||
## Endpoint documentation
|
##
|
||||||
|
|
||||||
The most common way to document Web APIs today is to produce documentation that lists the API endpoints verbatim, and describes the allowable operations on each. There are various tools that allow you to do this in an automated or semi-automated way.
|
... TODO ...
|
||||||
|
|
||||||
|
## Third party packages
|
||||||
|
|
||||||
|
There are a number of mature third-party packages for providing API documentation.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Looking for a new Django REST Framework related role? On this site we provide a list of job resources that may be helpful. It's also worth checking out if any of [our sponsors are hiring][drf-funding].
|
Looking for a new Django REST Framework related role? On this site we provide a list of job resources that may be helpful. It's also worth checking out if any of [our sponsors are hiring][drf-funding].
|
||||||
|
|
||||||
|
|
||||||
## Places to Look for Django REST Framework Jobs
|
## Places to look for Django REST Framework Jobs
|
||||||
|
|
||||||
* [https://www.djangoproject.com/community/jobs/][djangoproject-website]
|
* [https://www.djangoproject.com/community/jobs/][djangoproject-website]
|
||||||
* [https://www.python.org/jobs/][python-org-jobs]
|
* [https://www.python.org/jobs/][python-org-jobs]
|
||||||
|
|
|
@ -62,14 +62,15 @@ pages:
|
||||||
- 'Tutorials and Resources': 'topics/tutorials-and-resources.md'
|
- 'Tutorials and Resources': 'topics/tutorials-and-resources.md'
|
||||||
- 'Contributing to REST framework': 'topics/contributing.md'
|
- 'Contributing to REST framework': 'topics/contributing.md'
|
||||||
- 'Project management': 'topics/project-management.md'
|
- 'Project management': 'topics/project-management.md'
|
||||||
|
- 'Jobs': 'topics/jobs.md'
|
||||||
- '3.0 Announcement': 'topics/3.0-announcement.md'
|
- '3.0 Announcement': 'topics/3.0-announcement.md'
|
||||||
- '3.1 Announcement': 'topics/3.1-announcement.md'
|
- '3.1 Announcement': 'topics/3.1-announcement.md'
|
||||||
- '3.2 Announcement': 'topics/3.2-announcement.md'
|
- '3.2 Announcement': 'topics/3.2-announcement.md'
|
||||||
- '3.3 Announcement': 'topics/3.3-announcement.md'
|
- '3.3 Announcement': 'topics/3.3-announcement.md'
|
||||||
- '3.4 Announcement': 'topics/3.4-announcement.md'
|
- '3.4 Announcement': 'topics/3.4-announcement.md'
|
||||||
- '3.5 Announcement': 'topics/3.5-announcement.md'
|
- '3.5 Announcement': 'topics/3.5-announcement.md'
|
||||||
|
- '3.6 Announcement': 'topics/3.6-announcement.md'
|
||||||
- 'Kickstarter Announcement': 'topics/kickstarter-announcement.md'
|
- 'Kickstarter Announcement': 'topics/kickstarter-announcement.md'
|
||||||
- 'Mozilla Grant': 'topics/mozilla-grant.md'
|
- 'Mozilla Grant': 'topics/mozilla-grant.md'
|
||||||
- 'Funding': 'topics/funding.md'
|
- 'Funding': 'topics/funding.md'
|
||||||
- 'Release Notes': 'topics/release-notes.md'
|
- 'Release Notes': 'topics/release-notes.md'
|
||||||
- 'Jobs': 'topics/jobs.md'
|
|
||||||
|
|
|
@ -1,13 +1,36 @@
|
||||||
from rest_framework.renderers import CoreJSONRenderer, DocumentationRenderer
|
from rest_framework.renderers import CoreJSONRenderer, DocumentationRenderer, SchemaJSRenderer
|
||||||
from rest_framework.schemas import get_schema_view
|
from rest_framework.schemas import get_schema_view
|
||||||
|
from django.conf.urls import url, include
|
||||||
|
|
||||||
|
|
||||||
def get_docs_view(title=None, url=None, renderer_classes=None):
|
def get_docs_view(title=None, url=None, renderer_classes=None, public=True):
|
||||||
if renderer_classes is None:
|
if renderer_classes is None:
|
||||||
renderer_classes = [DocumentationRenderer, CoreJSONRenderer]
|
renderer_classes = [DocumentationRenderer, CoreJSONRenderer]
|
||||||
|
|
||||||
return get_schema_view(
|
return get_schema_view(
|
||||||
title=title,
|
title=title,
|
||||||
url=url,
|
url=url,
|
||||||
renderer_classes=renderer_classes
|
renderer_classes=renderer_classes,
|
||||||
|
public=public
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_schemajs_view(title=None, url=None, public=True):
|
||||||
|
renderer_classes = [SchemaJSRenderer]
|
||||||
|
|
||||||
|
return get_schema_view(
|
||||||
|
title=title,
|
||||||
|
url=url,
|
||||||
|
renderer_classes=renderer_classes,
|
||||||
|
public=public
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def include_docs_urls(title=None, schema_url=None, public=True):
|
||||||
|
docs_view = get_docs_view(title, schema_url, public=public)
|
||||||
|
schema_js_view = get_schemajs_view(title, schema_url, public=public)
|
||||||
|
urls = [
|
||||||
|
url(r'^$', docs_view, name='docs-index'),
|
||||||
|
url(r'^schema.js$', schema_js_view, name='schema-js')
|
||||||
|
]
|
||||||
|
return include(urls, namespace='api-docs')
|
||||||
|
|
|
@ -8,6 +8,7 @@ REST framework also provides an HTML renderer that renders the browsable API.
|
||||||
"""
|
"""
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import base64
|
||||||
import json
|
import json
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
@ -19,6 +20,7 @@ from django.http.multipartparser import parse_header
|
||||||
from django.template import Template, loader
|
from django.template import Template, loader
|
||||||
from django.test.client import encode_multipart
|
from django.test.client import encode_multipart
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
|
from django.utils.html import mark_safe
|
||||||
|
|
||||||
from rest_framework import VERSION, exceptions, serializers, status
|
from rest_framework import VERSION, exceptions, serializers, status
|
||||||
from rest_framework.compat import (
|
from rest_framework.compat import (
|
||||||
|
@ -803,17 +805,14 @@ class DocumentationRenderer(BaseRenderer):
|
||||||
|
|
||||||
def get_context(self, data, request):
|
def get_context(self, data, request):
|
||||||
from pygments.formatters import HtmlFormatter
|
from pygments.formatters import HtmlFormatter
|
||||||
from django.utils.html import mark_safe
|
|
||||||
formatter = HtmlFormatter(style=self.code_style)
|
formatter = HtmlFormatter(style=self.code_style)
|
||||||
code_style = formatter.get_style_defs('.highlight')
|
code_style = formatter.get_style_defs('.highlight')
|
||||||
langs = ['shell', 'javascript', 'python']
|
langs = ['shell', 'javascript', 'python']
|
||||||
codec = coreapi.codecs.CoreJSONCodec()
|
codec = coreapi.codecs.CoreJSONCodec()
|
||||||
schema = mark_safe(json.dumps(codec.encode(data)))
|
|
||||||
return {
|
return {
|
||||||
'document': data,
|
'document': data,
|
||||||
'langs': langs,
|
'langs': langs,
|
||||||
'code_style': code_style,
|
'code_style': code_style,
|
||||||
'schema': schema,
|
|
||||||
'request': request
|
'request': request
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -823,6 +822,22 @@ class DocumentationRenderer(BaseRenderer):
|
||||||
return template_render(template, context, request=renderer_context['request'])
|
return template_render(template, context, request=renderer_context['request'])
|
||||||
|
|
||||||
|
|
||||||
|
class SchemaJSRenderer(BaseRenderer):
|
||||||
|
media_type = 'script/javascript'
|
||||||
|
format = 'javascript'
|
||||||
|
charset = 'utf-8'
|
||||||
|
template = 'rest_framework/schema.js'
|
||||||
|
|
||||||
|
def render(self, data, accepted_media_type=None, renderer_context=None):
|
||||||
|
codec = coreapi.codecs.CoreJSONCodec()
|
||||||
|
schema = base64.b64encode(codec.encode(data))
|
||||||
|
|
||||||
|
template = loader.get_template(self.template)
|
||||||
|
context = {'schema': mark_safe(schema)}
|
||||||
|
request = renderer_context['request']
|
||||||
|
return template_render(template, context, request=request)
|
||||||
|
|
||||||
|
|
||||||
class MultiPartRenderer(BaseRenderer):
|
class MultiPartRenderer(BaseRenderer):
|
||||||
media_type = 'multipart/form-data; boundary=BoUnDaRyStRiNg'
|
media_type = 'multipart/form-data; boundary=BoUnDaRyStRiNg'
|
||||||
format = 'multipart'
|
format = 'multipart'
|
||||||
|
|
|
@ -291,7 +291,7 @@ class SchemaGenerator(object):
|
||||||
self.url = url
|
self.url = url
|
||||||
self.endpoints = None
|
self.endpoints = None
|
||||||
|
|
||||||
def get_schema(self, request=None):
|
def get_schema(self, request=None, public=False):
|
||||||
"""
|
"""
|
||||||
Generate a `coreapi.Document` representing the API schema.
|
Generate a `coreapi.Document` representing the API schema.
|
||||||
"""
|
"""
|
||||||
|
@ -299,7 +299,7 @@ class SchemaGenerator(object):
|
||||||
inspector = self.endpoint_inspector_cls(self.patterns, self.urlconf)
|
inspector = self.endpoint_inspector_cls(self.patterns, self.urlconf)
|
||||||
self.endpoints = inspector.get_api_endpoints()
|
self.endpoints = inspector.get_api_endpoints()
|
||||||
|
|
||||||
links = self.get_links(request)
|
links = self.get_links(None if public else request)
|
||||||
if not links:
|
if not links:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -661,7 +661,7 @@ class SchemaGenerator(object):
|
||||||
return named_path_components + [action]
|
return named_path_components + [action]
|
||||||
|
|
||||||
|
|
||||||
def get_schema_view(title=None, url=None, urlconf=None, renderer_classes=None):
|
def get_schema_view(title=None, url=None, urlconf=None, renderer_classes=None, public=False):
|
||||||
"""
|
"""
|
||||||
Return a schema view.
|
Return a schema view.
|
||||||
"""
|
"""
|
||||||
|
@ -680,7 +680,7 @@ def get_schema_view(title=None, url=None, urlconf=None, renderer_classes=None):
|
||||||
renderer_classes = rclasses
|
renderer_classes = rclasses
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
schema = generator.get_schema(request)
|
schema = generator.get_schema(request, public)
|
||||||
if schema is None:
|
if schema is None:
|
||||||
raise exceptions.PermissionDenied()
|
raise exceptions.PermissionDenied()
|
||||||
return Response(schema)
|
return Response(schema)
|
||||||
|
|
|
@ -1,3 +1,23 @@
|
||||||
|
h1 {
|
||||||
|
font-size: 45px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-code {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.highlight code * {
|
||||||
|
white-space: nowrap; // this sets all children inside to nowrap
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.highlight {
|
||||||
|
overflow-x: auto; // this sets the scrolling in x
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.highlight code {
|
||||||
|
white-space: pre; // forces <code> to respect <pre> formatting
|
||||||
|
}
|
||||||
|
|
||||||
.main-container {
|
.main-container {
|
||||||
padding-left: 30px;
|
padding-left: 30px;
|
||||||
padding-right: 30px;
|
padding-right: 30px;
|
||||||
|
@ -301,9 +321,23 @@ body {
|
||||||
.api-modal .modal-content .toggle-view {
|
.api-modal .modal-content .toggle-view {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.api-modal .modal-content .response .well {
|
.api-modal .modal-content .response .well {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
max-height: 550px;
|
max-height: 550px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.highlight {
|
||||||
|
background-color: #f7f7f9
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox label.control-label {
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.navbar-nav.navbar-right:last-child {
|
||||||
|
margin-right: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
1906
rest_framework/static/rest_framework/js/coreapi-0.0.20.js
Normal file
1906
rest_framework/static/rest_framework/js/coreapi-0.0.20.js
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,16 @@
|
||||||
{% load rest_framework %}
|
{% load rest_framework %}
|
||||||
|
|
||||||
|
<div class="row intro">
|
||||||
|
<div class="col-md-6 intro-title">
|
||||||
|
<h1>{{ document.title }}</h1>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 intro-code">
|
||||||
|
{% if 'shell' in langs %}{% include "rest_framework/docs/langs/shell-intro.html" %}{% endif %}
|
||||||
|
{% if 'python' in langs %}{% include "rest_framework/docs/langs/python-intro.html" %}{% endif %}
|
||||||
|
{% if 'javascript' in langs %}{% include "rest_framework/docs/langs/javascript-intro.html" %}{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% for section_key, section in document.data.items %}
|
{% for section_key, section in document.data.items %}
|
||||||
<h2 id="{{ section_key }}" class="coredocs-section-title">{{ section_key }} <a href="#{{ section_key }}"><i class="fa fa-link" aria-hidden="true"></i>
|
<h2 id="{{ section_key }}" class="coredocs-section-title">{{ section_key }} <a href="#{{ section_key }}"><i class="fa fa-link" aria-hidden="true"></i>
|
||||||
</a></h2>
|
</a></h2>
|
||||||
|
|
|
@ -17,16 +17,8 @@
|
||||||
<link href="{% static 'rest_framework/docs/img/favicon.ico' %}" rel="shortcut icon">
|
<link href="{% static 'rest_framework/docs/img/favicon.ico' %}" rel="shortcut icon">
|
||||||
|
|
||||||
<style>{{ code_style }}</style>
|
<style>{{ code_style }}</style>
|
||||||
<style>
|
<script src="{% static 'rest_framework/js/coreapi-0.0.20.js' %}"></script>
|
||||||
.highlight {background-color: #f7f7f9}
|
<script src="{% url 'api-docs:schema-js' %}"></script>
|
||||||
.checkbox label.control-label {font-weight: bold}
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
.navbar-nav.navbar-right:last-child {
|
|
||||||
margin-right: 0 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script src="https://unpkg.com/coreapi@0.0.20/dist/coreapi.js"></script>
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
@ -76,9 +68,7 @@
|
||||||
|
|
||||||
let responseDisplay = 'data';
|
let responseDisplay = 'data';
|
||||||
const coreapi = window.coreapi
|
const coreapi = window.coreapi
|
||||||
const codec = new coreapi.codecs.CoreJSONCodec()
|
const schema = window.schema
|
||||||
const schema = {{ schema }}
|
|
||||||
const doc = codec.decode(schema)
|
|
||||||
|
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
window.auth = {
|
window.auth = {
|
||||||
|
@ -147,71 +137,70 @@
|
||||||
})
|
})
|
||||||
|
|
||||||
function requestCallback(request) {
|
function requestCallback(request) {
|
||||||
|
// Fill in the "GET /foo/" display.
|
||||||
let parser = document.createElement('a');
|
let parser = document.createElement('a');
|
||||||
parser.href = request.url;
|
parser.href = request.url;
|
||||||
const method = request.options.method
|
const method = request.options.method
|
||||||
const path = parser.pathname + parser.hash + parser.search
|
const path = parser.pathname + parser.hash + parser.search
|
||||||
|
|
||||||
// Filling the main response meta
|
|
||||||
form.closest(".modal-content").find(".toggle-view").removeClass("hide")
|
|
||||||
form.find(".request-method").text(method)
|
form.find(".request-method").text(method)
|
||||||
form.find(".request-url").text(path)
|
form.find(".request-url").text(path)
|
||||||
|
|
||||||
// Filling the raw panel
|
|
||||||
// form.find(".response-raw-request").text(method + ' ' + path + '\n\n')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function responseCallback(response, responseText) {
|
function responseCallback(response, responseText) {
|
||||||
|
// Display the 'Data'/'Raw' control.
|
||||||
|
form.closest(".modal-content").find(".toggle-view").removeClass("hide")
|
||||||
|
|
||||||
|
// Fill in the "200 OK" display.
|
||||||
form.find(".response-status-code").removeClass("label-success").removeClass("label-danger")
|
form.find(".response-status-code").removeClass("label-success").removeClass("label-danger")
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
form.find(".response-status-code").addClass("label-success")
|
form.find(".response-status-code").addClass("label-success")
|
||||||
} else {
|
} else {
|
||||||
form.find(".response-status-code").addClass("label-danger")
|
form.find(".response-status-code").addClass("label-danger")
|
||||||
}
|
}
|
||||||
|
|
||||||
form.find(".response-status-code").text(response.status)
|
form.find(".response-status-code").text(response.status)
|
||||||
|
|
||||||
form.find(".meta").removeClass("hide")
|
form.find(".meta").removeClass("hide")
|
||||||
|
|
||||||
// Filling the raw panel
|
|
||||||
var panelText = 'HTTP/1.1 ' + response.status + ' ' + response.statusText + '\n';
|
|
||||||
|
|
||||||
|
// Fill in the Raw HTTP response display.
|
||||||
|
var panelText = 'HTTP/1.1 ' + response.status + ' ' + response.statusText + '\n';
|
||||||
response.headers.forEach((header, key) => {
|
response.headers.forEach((header, key) => {
|
||||||
panelText += normalizeHTTPHeader(key) + ': ' + header + '\n'
|
panelText += normalizeHTTPHeader(key) + ': ' + header + '\n'
|
||||||
})
|
})
|
||||||
|
|
||||||
if (responseText) {
|
if (responseText) {
|
||||||
panelText += '\n' + responseText
|
panelText += '\n' + responseText
|
||||||
}
|
}
|
||||||
|
|
||||||
form.find(".response-raw-response").text(panelText)
|
form.find(".response-raw-response").text(panelText)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Instantiate a client to make the outgoing request.
|
||||||
let options = {
|
let options = {
|
||||||
requestCallback: requestCallback,
|
requestCallback: requestCallback,
|
||||||
responseCallback: responseCallback,
|
responseCallback: responseCallback,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup authentication options.
|
||||||
if (window.auth && window.auth.type === 'token') {
|
if (window.auth && window.auth.type === 'token') {
|
||||||
|
// Header authentication
|
||||||
options.headers = {
|
options.headers = {
|
||||||
'Authorization': window.auth.value
|
'Authorization': window.auth.value
|
||||||
}
|
}
|
||||||
} else if (window.auth && window.auth.type === 'basic') {
|
} else if (window.auth && window.auth.type === 'basic') {
|
||||||
|
// Basic authentication
|
||||||
const token = window.auth.username + ':' + window.auth.password
|
const token = window.auth.username + ':' + window.auth.password
|
||||||
const hash = window.btoa(token)
|
const hash = window.btoa(token)
|
||||||
options.headers = {
|
options.headers = {
|
||||||
'Authorization': 'Basic ' + hash
|
'Authorization': 'Basic ' + hash
|
||||||
}
|
}
|
||||||
} else if (window.auth && window.auth.type === 'session') {
|
} else if (window.auth && window.auth.type === 'session') {
|
||||||
|
// Session authentication
|
||||||
options.csrf = {
|
options.csrf = {
|
||||||
'X-CSRFToken': getCookie('csrftoken')
|
'X-CSRFToken': getCookie('csrftoken')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const client = new coreapi.Client(options)
|
const client = new coreapi.Client(options)
|
||||||
|
|
||||||
client.action(doc, key, params).then(function (data) {
|
client.action(schema, key, params).then(function (data) {
|
||||||
var response = JSON.stringify(data, null, 2);
|
var response = JSON.stringify(data, null, 2);
|
||||||
form.find(".request-awaiting").addClass("hide")
|
form.find(".request-awaiting").addClass("hide")
|
||||||
form.find(".response-raw").addClass("hide")
|
form.find(".response-raw").addClass("hide")
|
||||||
|
@ -240,6 +229,7 @@
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 'Data'/'Raw' control
|
||||||
$('.toggle-view button').click(function() {
|
$('.toggle-view button').click(function() {
|
||||||
responseDisplay = $(this).data("display-toggle");
|
responseDisplay = $(this).data("display-toggle");
|
||||||
$(this).removeClass("btn-default").addClass('btn-info').siblings().removeClass('btn-info');
|
$(this).removeClass("btn-default").addClass('btn-info').siblings().removeClass('btn-info');
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
{% load rest_framework %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
<pre class="highlight javascript hide" data-language="javascript"><code>{% code html %}<!-- Load the JavaScript client library -->
|
||||||
|
<script src="{% static 'rest_framework/js/coreapi-0.0.20.js' %}"></script>
|
||||||
|
<script src="{% url 'api-docs:schema-js' %}"></script>{% endcode %}</code></pre>
|
|
@ -1,18 +1,15 @@
|
||||||
{% load rest_framework %}
|
{% load rest_framework %}
|
||||||
<pre class="highlight javascript hide" data-language="javascript"><code>{% code javascript %}var coreapi = window.coreapi
|
<pre class="highlight javascript hide" data-language="javascript"><code>{% code javascript %}var coreapi = window.coreapi // Loaded by `coreapi.js`
|
||||||
|
var schema = window.schema // Loaded by `schema.js`
|
||||||
|
|
||||||
// Initialize a client & load the schema document
|
// Initialize a client
|
||||||
var client = new coreapi.Client()
|
var client = new coreapi.Client()
|
||||||
var document = null
|
|
||||||
client.get("{{ document.url }}").then(function(result) {
|
|
||||||
document = result
|
|
||||||
})
|
|
||||||
|
|
||||||
// Interact with the API endpoint
|
// Interact with the API endpoint
|
||||||
var action = [{% if section_key %}"{{ section_key }}", {% endif %}"{{ link_key }}"]
|
var action = [{% if section_key %}"{{ section_key }}", {% endif %}"{{ link_key }}"]
|
||||||
{% if link.fields %}var params = {
|
{% if link.fields %}var params = {
|
||||||
{% for field in link.fields %} {{ field.name }}: ...{% if not loop.last %},{% endif %}
|
{% for field in link.fields %} {{ field.name }}: ...{% if not loop.last %},{% endif %}
|
||||||
{% endfor %}}
|
{% endfor %}}
|
||||||
{% endif %}client.action(document, action, params=params).then(function(result) {
|
{% endif %}client.action(schema, action{% if link.fields %}, params{% endif %}).then(function(result) {
|
||||||
// Return value is in 'result'
|
// Return value is in 'result'
|
||||||
}){% endcode %}</code></pre>
|
}){% endcode %}</code></pre>
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
{% load rest_framework %}
|
||||||
|
<pre class="highlight python hide" data-language="python"><code>{% code bash %}# Install the Python client library
|
||||||
|
$ pip install coreapi{% endcode %}</code></pre>
|
|
@ -3,11 +3,11 @@
|
||||||
|
|
||||||
# Initialize a client & load the schema document
|
# Initialize a client & load the schema document
|
||||||
client = coreapi.Client()
|
client = coreapi.Client()
|
||||||
document = client.get("{{ document.url }}"{% if schema_format %}, format="{{ schema_format }}"{% endif %})
|
schema = client.get("{{ document.url }}"{% if schema_format %}, format="{{ schema_format }}"{% endif %})
|
||||||
|
|
||||||
# Interact with the API endpoint
|
# Interact with the API endpoint
|
||||||
action = [{% if section_key %}"{{ section_key }}", {% endif %}"{{ link_key }}"]
|
action = [{% if section_key %}"{{ section_key }}", {% endif %}"{{ link_key }}"]
|
||||||
{% if link.fields %}params = {
|
{% if link.fields %}params = {
|
||||||
{% for field in link.fields %} "{{ field.name }}": ...{% if not loop.last %},{% endif %}
|
{% for field in link.fields %} "{{ field.name }}": ...{% if not loop.last %},{% endif %}
|
||||||
{% endfor %}}
|
{% endfor %}}
|
||||||
{% endif %}result = client.action(document, action{% if link.fields %}, params=params{% endif %}){% endcode %}</code></pre>
|
{% endif %}result = client.action(schema, action{% if link.fields %}, params=params{% endif %}){% endcode %}</code></pre>
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
{% load rest_framework %}
|
||||||
|
<pre class="highlight shell" data-language="shell"><code>{% code bash %}# Install the command line client
|
||||||
|
$ pip install coreapi-cli{% endcode %}</code></pre>
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
<h3 class="brand"><a href=".">{{ document.title }}</a></h3>
|
<h3 class="brand"><a href="#">{{ document.title }}</a></h3>
|
||||||
|
|
||||||
<i class="fa fa-bars fa-2x toggle-btn" data-toggle="collapse" data-target="#menu-content"></i>
|
<i class="fa fa-bars fa-2x toggle-btn" data-toggle="collapse" data-target="#menu-content"></i>
|
||||||
<div class="menu-list">
|
<div class="menu-list">
|
||||||
|
|
3
rest_framework/templates/rest_framework/schema.js
Normal file
3
rest_framework/templates/rest_framework/schema.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
let codec = new window.coreapi.codecs.CoreJSONCodec()
|
||||||
|
let coreJSON = window.atob('{{ schema }}')
|
||||||
|
window.schema = codec.decode(coreJSON)
|
Loading…
Reference in New Issue
Block a user