Add dcumentation (#12)

* added sphinx documentation
* filled in most missing docstrings
* updated README and setup.py, added CONTRIBUTING
* added docs build target
This commit is contained in:
Cristi Vîjdea
2017-12-12 11:14:33 +01:00
committed by GitHub
parent bfced82ae4
commit 53ac55a24b
41 changed files with 1821 additions and 447 deletions
+20
View File
@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXPROJ = drf-swagger
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+1
View File
@@ -0,0 +1 @@
# force directory to show up in git
+1
View File
@@ -0,0 +1 @@
# force directory to show up in git
+204
View File
@@ -0,0 +1,204 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# drf-swagger documentation build configuration file, created by
# sphinx-quickstart on Sun Dec 10 15:20:34 2017.
import os
import sys
import sphinx_rtd_theme
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = 'drf-swagger'
copyright = '2017, Cristi V.'
author = 'Cristi V.'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '1.0'
# The full version, including alpha/beta/rc tags.
release = '1.0.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
modindex_common_prefix = ['drf_swagger.']
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
# html_theme = 'default'
html_theme = "sphinx_rtd_theme"
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# This is required for the alabaster theme
# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
html_sidebars = {
'**': [
'relations.html', # needs 'show_related': True theme option to display
'searchbox.html',
]
}
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'drf-swaggerdoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'drf-swagger.tex', 'drf-swagger Documentation',
'Cristi V.', 'manual'),
]
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'drf-swagger', 'drf-swagger Documentation',
[author], 1)
]
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'drf-swagger', 'drf-swagger Documentation',
author, 'drf-swagger', 'One line description of project.',
'Miscellaneous'),
]
autodoc_default_flags = ['private-members']
autodoc_member_order = 'bysource'
autoclass_content = 'both'
autodoc_mock_imports = []
nitpick_ignore = [
('py:class', 'object'),
('py:class', 'Exception'),
('py:class', 'collections.OrderedDict'),
('py:class', 'ruamel.yaml.dumper.SafeDumper'),
('py:class', 'rest_framework.renderers.BaseRenderer'),
('py:class', 'rest_framework.views.APIView'),
('py:class', 'OpenAPICodecYaml'),
('py:class', 'OpenAPICodecJson'),
('py:class', 'OpenAPISchemaGenerator'),
('py:obj', 'bool'),
('py:obj', 'dict'),
('py:obj', 'list'),
('py:obj', 'str'),
('py:obj', 'int'),
('py:obj', 'bytes'),
('py:obj', 'tuple'),
('py:obj', 'callable'),
('py:obj', 'type'),
('py:obj', 'OrderedDict'),
('py:obj', 'coreapi.Field'),
('py:obj', 'BaseFilterBackend'),
('py:obj', 'BasePagination'),
('py:obj', 'rest_framework.request.Request'),
('py:obj', 'rest_framework.serializers.Field'),
('py:obj', 'serializers.Field'),
('py:obj', 'serializers.BaseSerializer'),
('py:obj', 'Serializer'),
('py:obj', 'APIView'),
]
sys.path.insert(0, os.path.abspath('../testproj'))
os.putenv('DJANGO_SETTINGS_MODULE', 'testproj.settings')
from django.conf import settings
settings.configure()
import drf_swagger.views
# instantiate a SchemaView in the views module to make it available to autodoc
drf_swagger.views.SchemaView = drf_swagger.views.get_schema_view(None)
+1
View File
@@ -0,0 +1 @@
.. include:: ../CONTRIBUTING.rst
+148
View File
@@ -0,0 +1,148 @@
.. |br| raw:: html
<br />
########################
Custom schema generation
########################
If the default spec generation does not quite match what you were hoping to achieve, ``drf-swagger`` provides some
custom behavior hooks by default.
*********************
Swagger spec overview
*********************
This library generates OpenAPI 2.0 documents. The authoritative specification for this document's structure will always
be the official documentation over at `swagger.io <https://swagger.io/>`__ and the `OpenAPI 2.0 specification
page <https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md>`__.
Beause the above specifications are a bit heavy and convoluted, here is a general overview of how the specification
is structured, starting from the root ``Swagger`` object.
* :class:`.Swagger` object
+ ``info``, ``schemes``, ``securityDefinitions`` and other informative attributes
+ ``paths``: :class:`.Paths` object
A list of all the paths in the API in the form of a mapping
- ``{path}``: :class:`.PathItem` - each :class:`.PathItem` has multiple operations keyed by method
* ``{http_method}``: :class:`.Operation`
Each operation is thus uniquely identified by its ``(path, http_method)`` combination,
e.g. ``GET /articles/``, ``POST /articles/``, etc.
* ``parameters``: [:class:`.Parameter`] - and a list of path parameters
+ ``definitions``: named Models
A list of all the named models in the API in the form of a mapping
- ``{ModelName}``: :class:`.Schema`
* :class:`.Operation` contains the following information about each operation:
+ ``parameters``: [:class:`.Parameter`]
A list of all the *query*, *header* and *form* parameters accepted by the operation.
- there can also be **at most one** body parameter whose structure is represented by a
:class:`.Schema` or a reference to one (:class:`.SchemaRef`)
+ ``responses``: :class:`.Responses`
A list of all the possible responses the operation is expected to return. Each response can optionally have a
:class:`.Schema` which describes the structure of its body.
- ``{status_code}``: :class:`.Response` - mapping of status code to response definition
+ ``operationId`` - should be unique across all operations
+ ``tags`` - used to group operations in the listing
It is interesting to note that the main difference between ``Parameter`` and ``Schema`` is that Schemas can nest other
Schemas, while Parameters are "primitives" and cannot contain other Parameters. The only exception are ``body``
Parameters, which can contain a Schema.
**************************************
The ``@swagger_auto_schema`` decorator
**************************************
You can use the :func:`@swagger_auto_schema <.swagger_auto_schema>` decorator on view functions to override
some properties of the generated :class:`.Operation`. For example, in a ``ViewSet``,
.. code:: python
@swagger_auto_schema(operation_description="partial_update description override", responses={404: 'slug not found'})
def partial_update(self, request, *args, **kwargs):
"""partial_update method docstring"""
...
will override the description of the ``PATCH /article/{id}/`` operation, and document a 404 response with no body and
the given description.
Where you can use the :func:`@swagger_auto_schema <.swagger_auto_schema>` decorator depends on the type of your view:
* for function based ``@api_view``\ s, because the same view can handle multiple methods, and thus represent multiple
operations, you have to add the decorator multiple times if you want to override different operations:
.. code:: python
test_param = openapi.Parameter('test', openapi.IN_QUERY, description="test manual param", type=openapi.TYPE_BOOLEAN)
user_response = openapi.Response('response description', UserSerializer)
@swagger_auto_schema(method='get', manual_parameters=[test_param], responses={200: user_response})
@swagger_auto_schema(methods=['put', 'post'], request_body=UserSerializer)
@api_view(['GET', 'PUT', 'POST'])
def user_detail(request, pk):
...
* for class based ``APIView``, ``GenericAPIView`` and non-``ViewSet`` derivatives, you have to decorate the respective
method of each operation:
.. code:: python
class UserList(APIView):
@swagger_auto_schema(responses={200: UserSerializer(many=True)})
def get(self, request):
...
@swagger_auto_schema(operation_description="description")
def post(self, request):
...
* for ``ViewSet``, ``GenericViewSet``, ``ModelViewSet``, because each viewset corresponds to multiple **paths**, you have
to decorate the *action methods*, i.e. ``list``, ``create``, ``retrieve``, etc. |br|
Additionally, ``@list_route``\ s or ``@detail_route``\ s defined on the viewset, like function based api views, can
respond to multiple HTTP methods and thus have multiple operations that must be decorated separately:
.. code:: python
class ArticleViewSet(viewsets.ModelViewSet):
@swagger_auto_schema(operation_description='GET /articles/today/')
@list_route(methods=['get'])
def today(self, request):
...
@swagger_auto_schema(method='get', operation_description="GET /articles/{id}/image/")
@swagger_auto_schema(method='post', operation_description="POST /articles/{id}/image/")
@detail_route(methods=['get', 'post'], parser_classes=(MultiPartParser,))
def image(self, request, id=None):
...
@swagger_auto_schema(operation_description="PUT /articles/{id}/")
def update(self, request, *args, **kwargs):
...
@swagger_auto_schema(operation_description="PATCH /articles/{id}/")
def partial_update(self, request, *args, **kwargs):
...
*************************
Subclassing and extending
*************************
For more advanced control you can subclass :class:`.SwaggerAutoSchema` - see the documentation page for a list of
methods you can override.
You can put your custom subclass to use by setting it on a view method using the
:func:`@swagger_auto_schema <.swagger_auto_schema>` decorator described above.
If you need to control things at a higher level than :class:`.Operation` objects (e.g. overall document structure,
vendor extensions in metadata) you can also subclass :class:`.OpenAPISchemaGenerator` - again, see the documentation
page for a list of its methods.
This custom generator can be put to use by setting it as the :attr:`.generator_class` of a :class:`.SchemaView` using
:func:`.get_schema_view`.
+7
View File
@@ -0,0 +1,7 @@
######################
Customizing the web UI
######################
There is currently no pluggable way of customizing the web UI apart from the settings available in
:ref:`swagger-ui-settings` and :ref:`redoc-ui-settings`. If you really need to, you can override one of the
``drf-swagger/swagger-ui.html`` or ``drf-swagger/redoc.html`` templates that are used for rendering.
+87
View File
@@ -0,0 +1,87 @@
drf\_swagger package
====================
drf\_swagger\.app\_settings
----------------------------------
.. automodule:: drf_swagger.app_settings
:members:
:undoc-members:
:show-inheritance:
drf\_swagger\.codecs
---------------------------
.. automodule:: drf_swagger.codecs
:members:
:undoc-members:
:show-inheritance:
:exclude-members: SaneYamlDumper
drf\_swagger\.errors
---------------------------
.. automodule:: drf_swagger.errors
:members:
:undoc-members:
:show-inheritance:
drf\_swagger\.generators
-------------------------------
.. automodule:: drf_swagger.generators
:members:
:undoc-members:
:show-inheritance:
drf\_swagger\.inspectors
-------------------------------
.. automodule:: drf_swagger.inspectors
:members:
:undoc-members:
:show-inheritance:
drf\_swagger\.middleware
-------------------------------
.. automodule:: drf_swagger.middleware
:members:
:undoc-members:
:show-inheritance:
drf\_swagger\.openapi
----------------------------
.. automodule:: drf_swagger.openapi
:members:
:undoc-members:
:show-inheritance:
drf\_swagger\.renderers
------------------------------
.. automodule:: drf_swagger.renderers
:members:
:undoc-members:
:show-inheritance:
drf\_swagger\.utils
--------------------------
.. automodule:: drf_swagger.utils
:members:
:undoc-members:
:show-inheritance:
drf\_swagger\.views
--------------------------
.. automodule:: drf_swagger.views
:members:
:undoc-members:
:show-inheritance:
.. |br| raw:: html
<br />
+31
View File
@@ -0,0 +1,31 @@
.. drf-swagger documentation master file, created by
sphinx-quickstart on Sun Dec 10 15:20:34 2017.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
drf-swagger
===========
.. toctree::
:maxdepth: 2
:caption: Table of contents:
readme.rst
rendering.rst
custom_spec.rst
custom_ui.rst
settings.rst
contributing.rst
license.rst
Source code documentation
=========================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
.. toctree::
:maxdepth: 2
drf_swagger.rst
+1
View File
@@ -0,0 +1 @@
.. include:: ../LICENSE.rst
+36
View File
@@ -0,0 +1,36 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
set SPHINXPROJ=drf-swagger
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
:end
popd
+1
View File
@@ -0,0 +1 @@
.. include:: ../README.rst
+35
View File
@@ -0,0 +1,35 @@
##################
Serving the schema
##################
************************************************
``get_schema_view`` and the ``SchemaView`` class
************************************************
The :func:`.get_schema_view` function and the :class:`.SchemaView` class it returns (click links for documentation)
are intended to cover the majority of use cases one might want to configure. The class returned by
:func:`.get_schema_view` can be used to obtain view instances via :meth:`.SchemaView.with_ui`,
:meth:`.SchemaView.without_ui` and :meth:`.SchemaView.as_cached_view` - see :ref:`readme-quickstart`
in the README for a usage example.
You can also subclass :class:`.SchemaView` by extending the return value of :func:`.get_schema_view`, e.g.:
.. code:: python
SchemaView = get_schema_view(info, ...)
class CustomSchemaView(SchemaView):
generator_class = CustomSchemaGenerator
renderer_classes = (CustomRenderer1, CustomRenderer2,)
********************
Renderers and codecs
********************
If you need to modify how your Swagger spec is presented in views, you might want to override one of the renderers in
:mod:`.renderers` or one of the codecs in :mod:`.codecs`. The codec is the last stage where the Swagger object
arrives before being transformed into bytes, while the renderer is the stage responsible for tying toghether the
codec and the view.
You can use your custom renderer classes as kwargs to :meth:`.SchemaView.as_cached_view` or by subclassing
:class:`.SchemaView`.
+201
View File
@@ -0,0 +1,201 @@
.. role:: python(code)
:language: python
.. |br| raw:: html
<br />
########
Settings
########
Settings are configurable in ``settings.py`` by defining ``SWAGGER_SETTINGS`` or ``REDOC_SETTINGS``.
Example:
**settings.py**
.. code:: python
SWAGGER_SETTINGS = {
'SECURITY_DEFINITIONS': {
'basic': {
'type': 'basic'
}
},
...
}
REDOC_SETTINGS = {
'LAZY_RENDERING': True,
...
}
The possible settings and their default values are as follows:
********************
``SWAGGER_SETTINGS``
********************
Authorization
=============
USE_SESSION_AUTH
----------------
Enable/disable Django login as an authentication/authorization mechanism. If True, a login/logout button will be
displayed in Swagger UI.
**Default**: :python:`True`
LOGIN_URL
---------
URL for the Django Login action when using `USE_SESSION_AUTH`_.
**Default**: :python:`django.conf.settings.LOGIN_URL`
LOGOUT_URL
----------
URL for the Django Logout action when using `USE_SESSION_AUTH`_.
**Default**: :python:`django.conf.settings.LOGOUT_URL`
SECURITY_DEFINITIONS
--------------------
Swagger security definitions to be included in the specification. |br|
See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#security-definitions-object.
**Default**:
.. code:: python
'basic': {
'type': 'basic'
}
.. _swagger-ui-settings:
Swagger UI settings
===================
Swagger UI configuration settings. |br|
See https://github.com/swagger-api/swagger-ui/blob/112bca906553a937ac67adc2e500bdeed96d067b/docs/usage/configuration.md#parameters.
VALIDATOR_URL
-------------
URL pointing to a swagger-validator instance; used for the validation badge shown in swagger-ui. Can be modified to
point to a local install of `swagger-validator <https://hub.docker.com/r/swaggerapi/swagger-validator/>`_ or
set to ``None`` to remove the badge.
**Default**: :python:`'http://online.swagger.io/validator/'` |br|
*Maps to parameter*: ``validatorUrl``
OPERATIONS_SORTER
-----------------
Sorting order for the operation list of each tag.
* :python:`None`: show in the order returned by the server
* :python:`alpha`: sort alphabetically by path
* :python:`method`: sort by HTTP method
**Default**: :python:`None` |br|
*Maps to parameter*: ``operationsSorter``
TAGS_SORTER
-----------
Sorting order for tagged operation groups.
* :python:`None`: Swagger UI default ordering
* :python:`alpha`: sort alphabetically
**Default**: :python:`None` |br|
*Maps to parameter*: ``tagsSorter``
DOC_EXPANSION
-------------
Controls the default expansion setting for the operations and tags.
* :python:`None`: everything is collapsed
* :python:`list`: only tags are expanded
* :python:`full`: all operations are expanded
**Default**: :python:`'list'` |br|
*Maps to parameter*: ``docExpansion``
DEEP_LINKING
------------
Automatically update the fragment part of the URL with permalinks to the currently selected operation.
**Default**: :python:`False` |br|
*Maps to parameter*: ``deepLinking``
SHOW_EXTENSIONS
---------------
Show vendor extension (``x-..``) fields.
**Default**: :python:`True` |br|
*Maps to parameter*: ``showExtensions``
DEFAULT_MODEL_RENDERING
-----------------------
Controls whether operations show the model structure or the example value by default.
* :python:`model`: show the model fields by default
* :python:`example`: show the example value by default
**Default**: :python:`'model'` |br|
*Maps to parameter*: ``defaultModelRendering``
DEFAULT_MODEL_DEPTH
-------------------
Controls how many levels are expaned by default when showing nested models.
**Default**: :python:`2` |br|
*Maps to parameter*: ``defaultModelExpandDepth``
******************
``REDOC_SETTINGS``
******************
.. _redoc-ui-settings:
ReDoc UI settings
=================
ReDoc UI configuration settings. |br|
See https://github.com/Rebilly/ReDoc#redoc-tag-attributes.
LAZY_RENDERING
--------------
**Default**: :python:`True` |br|
*Maps to attribute*: ``lazy-rendering``
HIDE_HOSTNAME
-------------
**Default**: :python:`False` |br|
*Maps to attribute*: ``hide-hostname``
EXPAND_RESPONSES
----------------
**Default**: :python:`'all'` |br|
*Maps to attribute*: ``expand-responses``
PATH_IN_MIDDLE
--------------
**Default**: :python:`False` |br|
*Maps to attribute*: ``path-in-middle-panel``