SphinxでスタイリッシュなAPIリファレンスを作る

に公開

SphinxでスタイリッシュなAPIリファレンスを作る

1. この記事の目的

Sphinx はPythonパッケージのAPIリファレンスを作成するうえで、非常に便利なツールです。

その一方で、最低限の設定だけでAPIリファレンスを生成すると、(個人の感想ですが)少しだけ見づらいドキュメントになってしまいます。

最低限の設定だけで生成したAPIリファレンスの例が、こちらです。

デフォルトのAPIリファレンス

この記事では、Sphinxの設定をもうちょっとだけカスタマイズして、スタイリッシュなAPIリファレンスを作成していきます。

この記事の最後に完成するAPIリファレンスが、こちらです。

2. 最低限の設定でAPIリファレンスを作る

まずは、最低限の設定でAPIリファレンスを生成してみます。

この記事では、以下のようなシンプルな構成のPythonパッケージを題材にします。

本記事で用いたソースコードはこちらのGitHubにアップロードしてあります。

food/
├── __init__.py
├── fruit
│   ├── __init__.py
│   ├── apple.py
│   ├── banana.py
│   └── base_fruit.py
└── meat
    ├── __init__.py
    ├── base_meat.py
    ├── beef.py
    └── pork.py

(1) Sphinxのインストール

$ pip install -U sphinx

(2) ドキュメント生成の設定ファイルを作成

ドキュメント用のディレクトリを作成します。ここでは、foodと同じ階層にdocsというディレクトリを作成します。

$ mkdir docs/
.
├── docs
└── food

ドキュメント用のディレクトリに移動してから、sphinx-quickstart コマンドを実行します。これは、Sphinx用のドキュメントディレクトリを初期化するコマンドです。

$ cd docs/
$ sphinx-quickstart

いろいろ聞かれるので、適当に答えておきます。

Welcome to the Sphinx 8.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).

Selected root path: .

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]: n

The project name will occur in several places in the built documentation.
> Project name: My Food Library
> Author name(s): My Name
> Project release []: 0.1

If the documents are to be written in a language other than English,
you can select a language here by its language code. Sphinx will then
translate text that it generates into that language.

For a list of supported codes, see
https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language.
> Project language [en]: en

Creating file /home/tabae/zenn/sphinx-my-extension/docs/conf.py.
Creating file /home/tabae/zenn/sphinx-my-extension/docs/index.rst.
Creating file /home/tabae/zenn/sphinx-my-extension/docs/Makefile.
Creating file /home/tabae/zenn/sphinx-my-extension/docs/make.bat.

Finished: An initial directory structure has been created.

You should now populate your master file /home/tabae/zenn/sphinx-my-extension/docs/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.

docs/ に以下のようなファイルとディレクトリが生成されました。

.
├── Makefile
├── _build
├── _static
├── _templates
├── conf.py
├── index.rst
└── make.bat

(3) conf.py の編集

APIリファレンスの自動生成するために、conf.pyを編集します。

まず、Python モジュールを参照できるようにパスを通します。

conf.py
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent.resolve()))

次に、APIリファレンスの自動生成に必要なSphinx拡張を追加します。最初の時点では、extensions = []となっていますが、次のように変更します。

conf.py
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon']

(4) ソースファイルの生成

sphinx-apidocコマンドを実行して、APIリファレンスのソースファイルを自動生成します。

$ sphinx-apidoc -f -o <ドキュメントディレクトリへのPATH> <対象PythonパッケージのROOTへのPATH>

今回の例では以下のようにコマンドを実行します。

$ sphinx-apidoc -f -o ./ ../

food.rst, food.fruit.rst, food.meat.rst, modules.rst などのソースファイルファイルが生成されました。

Sphinxでは基本的に.rst形式でソースファイルを作成します。なお、Sphinx拡張を使うことで、Markdownでソースファイルを作成することも可能です。

(5) index.rstの編集

index.rst はドキュメントのトップページに相当するものですが、ここにfood.rstへのリンクを作成しておきます。

index.rstを以下のように修正します。

index.rst
.. toctree::
   :maxdepth: 2
   :caption: Contents:

   food

(6) ドキュメントのビルド

以下のコマンドを実行して、HTML形式のドキュメントを生成します。

checking consistency... /home/tabae/zenn/sphinx-my-extension/docs/modules.rst: WARNING: document isn't included in any toctree [toc.not_included] という警告が出ますが、これは無視して問題ありません。

$ make html

実行すると、docs/_build/ 以下にHTMLファイルが生成されます。
ブラウザで docs/_build/index.html を開いてみると、以下のようにドキュメントが表示されました。

デフォルトのAPIリファレンスの例

ここまでがAPIリファレンスを生成するための最低限の設定です。
この時点でのドキュメントは こちら で閲覧できます。

3. HTMLテーマを変更する

まずは、HTMLテーマを変更してみましょう。
Sphinxでは、HTMLテーマを変更することで、その見た目を大きく変えることができます。

Sphinx Themes Garalley では、Sphinxのテーマを一覧で確認することができるので、ここから好みのテーマを探してみるとよいでしょう。
ちなみに、デフォルトの場合には、Alabaster と呼ばれるテーマが使われています。

ここでは、Furo というテーマを使ってみます。

(1) Furoのインストール

$ pip install furo

(2) conf.pyの編集

docs/conf.pyhtml_theme = 'alabaster' の部分を次のように修正します。

conf.py
html_theme = 'furo'

(3) ドキュメントのビルド

$ make clean
$ make html

ビルドしたドキュメントをブラウザで確認してみると、下の画像のように、大きく見た目がかわっていることがわかります。

Furoテーマを適用したAPIリファレンスの例

この時点でのドキュメントは こちら で閲覧できます。

4. autosummaryを利用する(前編)

autosummaryという便利なSphinxの拡張機能があります。

autosummaryの主な機能は以下の二つです。

  1. 各クラスの説明文などをまとめて、一覧表示することができる。
  2. 自分で定義したテンプレートに従って、.rstファイルを生成することができる。

これら二つの機能は性質が異なるため、この節では、1. の機能だけを取り上げ、次節で、2. の機能について説明します。

(1) conf.pyを編集

まず、autosummaryを利用するために、extensionsautosummary を追加します。

conf.py
extensions = ['sphinx.ext.autodoc',
              'sphinx.ext.napoleon',
              'sphinx.ext.autosummary']

次に、以下の1行をconf.pyに追記します。

conf.py
autosummary_generate = True

(2) .rstファイルの編集

autosummary ディレクティブを用いて、一覧表示したいクラスやモジュールを列挙していきます。

.. currentmodule:: は、以降に登場するクラス名や関数名が、このモジュールの中にあるものであることを宣言しています。

:toctree: stubs/ の部分は、autosummaryによって自動生成される各クラスや関数のソースファイルを、stubs/ ディレクトリの下に格納するように指示しています。

food.fruit.rst
food.fruit
=====================

.. currentmodule:: food.fruit

Fruit classes
-----------------------

.. autosummary::
   :toctree: stubs/

   Apple
   Fuji
   Banana
food.meat.rst
food.meat
=====================

.. currentmodule:: food.meat

Meat classes
-----------------------

.. autosummary::
   :toctree: stubs/

   Beef
   Pork
   Wagyu

(3) ドキュメントのビルド

$ make clean
$ make html

ビルドしたドキュメントのfood.fruitfood.meatのページを確認してみると、下の画像のように、各クラスが一覧表示されるようになっています。

autosummaryでクラス一覧を表示した例

また、food.fruitの下に、Apple, Fuji, Banana のクラスごとのページも作成されています。
個人的には、サブパッケージのすべてのモジュールが1ページにまとまっているデフォルトの構成よりは、このようにクラスごとに分割されたページ構成のほうが見やすいです。

クラスごとの詳細ページの例

この時点でのドキュメントは こちら で閲覧できます。

5. autosummaryを利用する(後編)

前節で、autosummaryを利用してドキュメントをビルドした際に、stubs/の中にfood.fruit.apple.rstなどのソースファイルが生成されていることに気づいたでしょうか?

この節では、これらの autosummaryによって自動生成されるソースファイルのフォーマットをカスタマイズしていこうと思います。

この節の目標は、以下の通りです。

  1. タイトルのfood.fruit.Appleから親モジュールの部分を抜いてAppleというクラス名のみを表記する。

  2. 一覧表示されているメソッドを同じページの中に展開して表示する。

クラスごとの詳細ページの例

(1) テンプレートファイルの作成

docs/_templates/class.rstというファイルを新規作成します。

class.rstは、autosummaryが自動生成するクラスのページに適用されるフォーマットです。他にも、モジュールのページなら、module.rst、関数のページなら、function.rstです。

1行目の{{ objname }}がタイトルに相当する部分です。ここが {{ fullname }} であれば親モジュールを含んだオブジェクト名が表示されますが、{{ objname }} のときは単にオブジェクト名が表示されます。

また、.. autoclass:: {{ fullname }} を使って、メソッドをページ内に表示します。

docs/_templates/class.rst
{{ objname }}
{{ underline }}

.. currentmodule:: {{ module }}

.. autoclass:: {{ fullname }}
   :members:
   :undoc-members:
   :inherited-members:

(2) 参照するテンプレートを指定

food.fruit.rstfood.meat.rstを、class.rstを参照するように :template: class.rstの一行を追加します。

food.fruit.rst
food.fruit
=====================

.. currentmodule:: food.fruit

Fruit classes
-----------------------

.. autosummary::
   :toctree: stubs/
   :template: class.rst

   Apple
   Fuji
   Banana

food.meat.rst
food.meat
=====================

.. currentmodule:: food.meat

Meat classes
-----------------------

.. autosummary::
   :toctree: stubs/
   :template: class.rst

   Beef
   Pork
   Wagyu

(3) ドキュメントのビルド

必要がないと思いますが、stubs/下にあるファイルも一応消しておきます。

$ rm -f stubs/*

ビルドします。

$ make clean
$ make html

以下のように、class.rstに基づいてページが生成されていることが確認できました。

更新後のクラスごとの詳細ページの例

この時点でのドキュメントは こちら で閲覧できます。

6. sphinx-designを使ってみる

sphinx-design は、Sphinxの拡張機能でグリッドやカードなどの便利な機能を利用することができます。

今回はsphinx-designのグリッドとカードを使って、APIリファレンスの見出しページを作成してみようと思います。

(1) sphinx-design をインストールする

$ pip install sphinx-design

(2) conf.pyを編集する

conf.pyextensionssphinx_designを追加する。

conf.py
extensions = ['sphinx.ext.autodoc',
              'sphinx.ext.napoleon',
              'sphinx.ext.autosummary',
              'sphinx_design',
            ]

(3) sphinx-designの機能を使って、ソースファイルを作成

今回は、food.rstのページをカード形式にしてみます。
使用する画像はあらかじめ_static/以下にコピーしておきます。

food.rst
API Reference
======================

.. grid:: 2
    :gutter: 5

    .. grid-item-card:: Fruit

        .. image:: _static/fruit.png
            :target: food.fruit

        +++

        .. button-ref:: food.fruit
            :expand:
            :color: secondary

            View Fruit Classes

    .. grid-item-card:: Meat

        .. image:: _static/meat.png
            :target: food.meat

        +++

        .. button-ref:: food.meat
            :expand:
            :color: secondary

            View Meat Classes

.. toctree::
   :hidden:
   :maxdepth: 2

   food.fruit
   food.meat

(4) ドキュメントのビルド

$ make clean
$ make html

以下のように少し凝ったデザインのページを作成することができました。

sphinx-designで作ったfood.rst

この時点でのドキュメントは こちら で閲覧できます。

7. ロゴを追加する

この節では、左のサイドメニューの上部にロゴを表示します。

(1) conf.pyの編集

_static/ 配下にロゴの画像ファイルを保存し、画像ファイルへのパスをconf.pyに記入します。

conf.py
html_logo = "_static/logo.png"

ついでに、左のサイドバーの上にあるタイトルも修正しておきます。

conf.py
html_title = "My Food Library"

(2) ドキュメントのビルド

$ make clean
$ make html

以下のようにサイドバーにロゴを表示することができました。

ロゴを追加

この時点でのドキュメントは こちら で閲覧できます。

8. 最後に

いかがでしょうか?
個人的にはだいぶスタイリッシュにAPIリファレンスになったかなと思います。

Sphinx は最初はとっつきにくいですが、カスタマイズの自由度が高いので、自分の好みに合ったスタイリッシュなAPIリファレンスを作ってみてください。

GitHubで編集を提案

Discussion