SphinxでスタイリッシュなAPIリファレンスを作る
SphinxでスタイリッシュなAPIリファレンスを作る
1. この記事の目的
Sphinx はPythonパッケージの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 モジュールを参照できるようにパスを通します。
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent.resolve()))
次に、APIリファレンスの自動生成に必要なSphinx拡張を追加します。最初の時点では、extensions = []となっていますが、次のように変更します。
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を以下のように修正します。
.. 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リファレンスを生成するための最低限の設定です。
この時点でのドキュメントは こちら で閲覧できます。
3. HTMLテーマを変更する
まずは、HTMLテーマを変更してみましょう。
Sphinxでは、HTMLテーマを変更することで、その見た目を大きく変えることができます。
Sphinx Themes Garalley では、Sphinxのテーマを一覧で確認することができるので、ここから好みのテーマを探してみるとよいでしょう。
ちなみに、デフォルトの場合には、Alabaster と呼ばれるテーマが使われています。
ここでは、Furo というテーマを使ってみます。
(1) Furoのインストール
$ pip install furo
(2) conf.pyの編集
docs/conf.py の html_theme = 'alabaster' の部分を次のように修正します。
html_theme = 'furo'
(3) ドキュメントのビルド
$ make clean
$ make html
ビルドしたドキュメントをブラウザで確認してみると、下の画像のように、大きく見た目がかわっていることがわかります。

この時点でのドキュメントは こちら で閲覧できます。
4. autosummaryを利用する(前編)
autosummaryという便利なSphinxの拡張機能があります。
autosummaryの主な機能は以下の二つです。
- 各クラスの説明文などをまとめて、一覧表示することができる。
- 自分で定義したテンプレートに従って、
.rstファイルを生成することができる。
これら二つの機能は性質が異なるため、この節では、1. の機能だけを取り上げ、次節で、2. の機能について説明します。
(1) conf.pyを編集
まず、autosummaryを利用するために、extensions に autosummary を追加します。
extensions = ['sphinx.ext.autodoc',
'sphinx.ext.napoleon',
'sphinx.ext.autosummary']
次に、以下の1行をconf.pyに追記します。
autosummary_generate = True
(2) .rstファイルの編集
autosummary ディレクティブを用いて、一覧表示したいクラスやモジュールを列挙していきます。
.. currentmodule:: は、以降に登場するクラス名や関数名が、このモジュールの中にあるものであることを宣言しています。
:toctree: stubs/ の部分は、autosummaryによって自動生成される各クラスや関数のソースファイルを、stubs/ ディレクトリの下に格納するように指示しています。
food.fruit
=====================
.. currentmodule:: food.fruit
Fruit classes
-----------------------
.. autosummary::
:toctree: stubs/
Apple
Fuji
Banana
food.meat
=====================
.. currentmodule:: food.meat
Meat classes
-----------------------
.. autosummary::
:toctree: stubs/
Beef
Pork
Wagyu
(3) ドキュメントのビルド
$ make clean
$ make html
ビルドしたドキュメントのfood.fruitやfood.meatのページを確認してみると、下の画像のように、各クラスが一覧表示されるようになっています。

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

この時点でのドキュメントは こちら で閲覧できます。
5. autosummaryを利用する(後編)
前節で、autosummaryを利用してドキュメントをビルドした際に、stubs/の中にfood.fruit.apple.rstなどのソースファイルが生成されていることに気づいたでしょうか?
この節では、これらの autosummaryによって自動生成されるソースファイルのフォーマットをカスタマイズしていこうと思います。
この節の目標は、以下の通りです。
-
タイトルの
food.fruit.Appleから親モジュールの部分を抜いてAppleというクラス名のみを表記する。 -
一覧表示されているメソッドを同じページの中に展開して表示する。

(1) テンプレートファイルの作成
docs/_templates/にclass.rstというファイルを新規作成します。
class.rstは、autosummaryが自動生成するクラスのページに適用されるフォーマットです。他にも、モジュールのページなら、module.rst、関数のページなら、function.rstです。
1行目の{{ objname }}がタイトルに相当する部分です。ここが {{ fullname }} であれば親モジュールを含んだオブジェクト名が表示されますが、{{ objname }} のときは単にオブジェクト名が表示されます。
また、.. autoclass:: {{ fullname }} を使って、メソッドをページ内に表示します。
{{ objname }}
{{ underline }}
.. currentmodule:: {{ module }}
.. autoclass:: {{ fullname }}
:members:
:undoc-members:
:inherited-members:
(2) 参照するテンプレートを指定
food.fruit.rstとfood.meat.rstを、class.rstを参照するように :template: class.rstの一行を追加します。
food.fruit
=====================
.. currentmodule:: food.fruit
Fruit classes
-----------------------
.. autosummary::
:toctree: stubs/
:template: class.rst
Apple
Fuji
Banana
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.pyの extensionsにsphinx_designを追加する。
extensions = ['sphinx.ext.autodoc',
'sphinx.ext.napoleon',
'sphinx.ext.autosummary',
'sphinx_design',
]
(3) sphinx-designの機能を使って、ソースファイルを作成
今回は、food.rstのページをカード形式にしてみます。
使用する画像はあらかじめ_static/以下にコピーしておきます。
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
以下のように少し凝ったデザインのページを作成することができました。

この時点でのドキュメントは こちら で閲覧できます。
7. ロゴを追加する
この節では、左のサイドメニューの上部にロゴを表示します。
(1) conf.pyの編集
_static/ 配下にロゴの画像ファイルを保存し、画像ファイルへのパスをconf.pyに記入します。
html_logo = "_static/logo.png"
ついでに、左のサイドバーの上にあるタイトルも修正しておきます。
html_title = "My Food Library"
(2) ドキュメントのビルド
$ make clean
$ make html
以下のようにサイドバーにロゴを表示することができました。

この時点でのドキュメントは こちら で閲覧できます。
8. 最後に
いかがでしょうか?
個人的にはだいぶスタイリッシュにAPIリファレンスになったかなと思います。
Sphinx は最初はとっつきにくいですが、カスタマイズの自由度が高いので、自分の好みに合ったスタイリッシュなAPIリファレンスを作ってみてください。
Discussion