sphinxcontrib.httpdomain で RESTful API のドキュメントを作る

この記事は CAMPHOR- Advent Calendar 2014 15日目の記事です.

Python 製のドキュメント作成ツールであるSphinx (公式, 日本) と, その拡張機能である sphinxcontrib.httpdomain を組み合わせると RESTful API のドキュメントを簡単に作成することができます.

sphinxcontrib.httpdomain Web サイトスクリーンショット

Sphinx とは

Sphinx は Python 製のドキュメンテーションビルダーです. reStructuredText という形式でマークアップしたものをビルドして, HTML や PDF, ePub など様々な形式で出力することができます.
Sphinx ロゴ

Sphinx は Python の公式ドキュメントや様々な Python のライブラリ (Django, NumPy, SciPy, etc…) で利用されているほか, Python 以外の言語のプロジェクト (CakePHP, Chef, etc…) でもドキュメントの作成に利用されています.

Python のコードから直接ドキュメントを生成するといった便利な機能もありますが, Sphinx 自体は Python の知識がなくても使い始めることができます.

sphinxcontrib.httpdomain とは

sphinxcontrib.httpdomain は Sphinx の拡張機能で, Sphinx で RESTful HTTP API のドキュメントを作成しやすくするツールです.
Flask, Bottle, Tornado のフレームワークで作成されたアプリケーションからは自動的にドキュメントを生成することもできますが, ここでは手動で作成する方法について説明します.

Sphinx と sphinxcontrib.httpdomain のインストール

現時点での最新の安定版である Sphinx 1.2.3 を利用することにします. Sphinx は Python 2 と 3 のどちらでも動作しますが, 現在は Python 2.7 の利用が推奨されています.

ここではすでに Python 2.7 と pip 等のインストールが済んでいるものとして進めます. Python と Sphinx のインストールについての詳細は公式ドキュメントも参照してください.

  1. 必要に応じて virtualenv や pyenv で仮想環境を作成します.
  2. Sphinx と sphinxcontrib.httpdomain をインストールします.
pip install Sphinx
pip install sphinxcontrib-httpdomain

Sphinx ドキュメントの作成

Sphinx のドキュメントの作成に必要なファイル一式を準備してくれる sphinx-quickstart というコマンドがあるため, これを用いて必要なファイルを作成します. 基本的にデフォルトの設定で問題ないですが, Project name, Author name(s), Project version などは設定が必要です.

$ sphinx-quickstart
Welcome to the Sphinx 1.2.3 quickstart utility.

Please enter values for the following settings (just press Enter to
accept a default value, if one is given in brackets).

Enter the root path for documentation.
> Root path for the documentation [.]:

You have two options for placing the build directory for Sphinx output.
Either, you use a directory "_build" within the root path, or you separate
"source" and "build" directories within the root path.
> Separate source and build directories (y/n) [n]:

Inside the root directory, two more directories will be created; "_templates"
for custom HTML templates and "_static" for custom stylesheets and other static
files. You can enter another prefix (such as ".") to replace the underscore.
> Name prefix for templates and static dir [_]:

The project name will occur in several places in the built documentation.
> Project name: RESTful HTTP APIs
> Author name(s): Yusuke Miyazaki

Sphinx has the notion of a "version" and a "release" for the
software. Each version can have multiple releases. For example, for
Python the version is something like 2.5 or 3.0, while the release is
something like 2.5.1 or 3.0a1.  If you don't need this dual structure,
just set both to the same value.
> Project version: 1.0.0
> Project release [1.0.0]:

The file name suffix for source files. Commonly, this is either ".txt"
or ".rst".  Only files with this suffix are considered documents.
> Source file suffix [.rst]:

One document is special in that it is considered the top node of the
"contents tree", that is, it is the root of the hierarchical structure
of the documents. Normally, this is "index", but if your "index"
document is a custom template, you can also set this to another filename.
> Name of your master document (without suffix) [index]:

Sphinx can also add configuration for epub output:
> Do you want to use the epub builder (y/n) [n]:

Please indicate if you want to use one of the following Sphinx extensions:
> autodoc: automatically insert docstrings from modules (y/n) [n]:
> doctest: automatically test code snippets in doctest blocks (y/n) [n]:
> intersphinx: link between Sphinx documentation of different projects (y/n) [n]:
> todo: write "todo" entries that can be shown or hidden on build (y/n) [n]:
> coverage: checks for documentation coverage (y/n) [n]:
> pngmath: include math, rendered as PNG images (y/n) [n]:
> mathjax: include math, rendered in the browser by MathJax (y/n) [n]:
> ifconfig: conditional inclusion of content based on config values (y/n) [n]:
> viewcode: include links to the source code of documented Python objects (y/n) [n]:

A Makefile and a Windows command file can be generated for you so that you
only have to run e.g. `make html' instead of invoking sphinx-build
directly.
> Create Makefile? (y/n) [y]:
> Create Windows command file? (y/n) [y]:

Creating file ./conf.py.
Creating file ./index.rst.
Creating file ./Makefile.
Creating file ./make.bat.

Finished: An initial directory structure has been created.

You should now populate your master file ./index.rst and create other documentation
source files. Use the Makefile to build the docs, like so:
   make builder
where "builder" is one of the supported builders, e.g. html, latex or linkcheck.

これで必要なファイルが生成されました.

make html

を実行すると, _build/html/index.html にHTML ファイルが生成されるのでブラウザで確認しましょう.
Sphinx ドキュメント

sphinxcontrib.httpdomain の設定

sphinxcontrib.httpdomain を利用するために Sphinx ドキュメントの設定ファイルを修正します. プロジェクトのディレクトリの conf.py の extensions を以下のように設定します.

# -*- coding: utf-8 -*-
#
# RESTful HTTP APIs documentation build configuration file, created by
# sphinx-quickstart on Fri Dec 12 15:43:58 2014.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.

import sys
import os

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))

# -- 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 = ['sphinxcontrib.httpdomain']

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

ページの追加

API という名前でページを追加してそこにドキュメントを記述します. プロジェクトのディレクトリに api.rst というファイルを作成して, 以下のような内容を記述します.

API
===

RESTful API のドキュメント.

次に index.rst の toctree を編集して, api.rst との関係を追加します.

.. RESTful HTTP APIs documentation master file, created by
   sphinx-quickstart on Fri Dec 12 15:43:58 2014.
   You can adapt this file completely to your liking, but it should at least
   contain the root `toctree` directive.

Welcome to RESTful HTTP APIs's documentation!
=============================================

Contents:

.. toctree::
   :maxdepth: 2

   api


Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

API のドキュメントを作成する

api.rst を編集してドキュメントを作成します. ここでは特定のユーザー (user_id) の書籍のリストを取得する API (/users/(int:user_id)/books) のドキュメントを作成することを考えます. api.rst は以下のようになります:

API
===

RESTful API のドキュメント.

.. http:get:: /users/(int:user_id)/books

   ユーザー (`user_id`) の書籍のリストを取得する API.

   **リクエスト例**

   .. sourcecode:: http

      GET /users/123/books HTTP/1.1
      Host: example.com
      Accept: application/json

   **レスポンス例**

   .. sourcecode:: http

      HTTP/1.1 200 OK
      Vary: Accept
      Content-Type: application/json

      [
        {
          "book_id": 123,
          "author_id": 35,
          "title": "Sphinx Book"
        },
        {
          "book_id": 125,
          "author_id": 13,
          "title": "Python Book"
        }
      ]

   :query sort: ``created_at`` または ``title``
   :query limit: 取得件数 (デフォルト: 10)
   :reqheader Authorization: OAuth のトークン (オプション)
   :statuscode 200: 成功
   :statuscode 404: ユーザーが見つからなかった

make html でコンパイルすると以下のようになります.

Sphinx ドキュメント

GET メソッドについてのドキュメントを作成するには, 以下のディレクティブを用います. 他にも POST, PUT, DELETE などがもちろん使えます.

http:get:: /users/(int:user_id)/books

API のパラメーターやステータスコードについては以下のように記述すると, 綺麗に整形されて出力されます.

    :query sort: ``created_at`` または ``title``
    :query limit: 取得件数 (デフォルト: 10)
    :reqheader Authorization: OAuth のトークン (オプション)
    :statuscode 200: 成功
    :statuscode 404: ユーザーが見つからなかった

このほかにも様々な情報を記述することができます.

  • param, parameter, arg, argument: URL のパラメータの説明
  • queryparameter, queryparam, qparam, query: リクエストのクエリ文字列で渡されるパラメータ
  • formparameter, formparam, fparam, form: リクエストのボディで application/x-www-form-urlencoded や multipart/form-data の形式で渡されるパラメータ
  • jsonparameter, jsonparam, json: リクエストのボディで application/json の形式で渡されるパラメータ
  • resjsonobj, resjson, >jsonobj, >json: レスポンスの JSON のフィールド
  • requestheader, reqheader, >header: リクエストヘッダーのフィールド
  • responseheader, resheader,
  • statuscode, status, code: ステータスコード

まとめ

sphinxcontrib.httpdomain によって, 統一感のある RESTful API のドキュメントを簡単に作成することができます. 専用のツールではなく Sphinx を用いることで, Web アプリケーションのドキュメントとその API のドキュメントを1つのドキュメントとしてまとめておくこと出来ます.

今回作成したコードは GitHub で公開しています.

明日の CAMPHOR- Advent Calendar 2014 の担当は @cotton_ori です.

参考