Sphinxの使い方．docstringを読み込んで仕様書を生成

## Sphinxによる美しいドキュメント生成 🌟📚

#### 更新履歴

- 2020年7月19日: Sphinx v3.1.2 を基準とした記述に更新。
- **2024年6月30日**: Sphinx v7.0.0 を基準とした記述に変更。Pythonのバージョンアップ、モジュールの自動検出、Markdownのサポート、テーマのカスタマイズ、自動ビルドとデプロイ、その他について追記しました

## 1. Sphinxとは？ 🤔

Sphinxは**知的で美しいドキュメント**を簡単に作れるPython製のドキュメント生成ツールです。
（[公式](http://www.sphinx-doc.org/ja/master/)が自称しています）

例えば、下のようなドキュメントが、**pythonのソースコードから**生成できます。

![2018-09-02_23h31_08.png](https://qiita-image-store.s3.amazonaws.com/0/193401/673a06ae-18e6-6c29-0b55-59c6ee76e425.png)

### Sphinxのメリット ✨

- **美しいドキュメントを簡単に作成できる:** Sphinxには、読みやすく美しいドキュメントを生成するための機能が豊富に用意されています。
- **Pythonプロジェクトとの親和性が高い:** SphinxはPythonで記述されており、Pythonプロジェクトのドキュメント作成に最適です。 docstring からドキュメントを自動生成する機能も備わっています。
- **テーマや拡張機能が豊富:** Sphinxには、ドキュメントの外観を変更したり、機能を拡張したりするためのテーマや拡張機能が数多く存在します。
- **様々な出力形式に対応:** HTML, PDF, ePub など、様々な形式のドキュメントを生成できます。
- **バージョン管理システムとの連携:** Gitなどのバージョン管理システムと連携して、ドキュメントの変更履歴を管理できます。

## 2. 環境構築 💻

まずは、Sphinxを使用するための環境を構築しましょう。

### 2.1. Pythonのインストール 🐍

SphinxはPythonで動作するため、Pythonがインストールされている必要があります。 まだインストールしていない場合は、Pythonの公式サイトから最新バージョン（3.11以降推奨ですが古くてもいいです）をインストールしてください。

[https://www.python.org/](https://www.python.org/)

### 2.2. Sphinxのインストール 📦

`pip`を使ってSphinxをインストールします。

```bash
$ pip install sphinx
```

`conda`を使ってインストールすることもできます。

```bash
$ conda install sphinx
```

これで、[いくつかのsphinxコマンド](http://www.sphinx-doc.org/ja/master/man/index.html)（`sphinx-apidoc`, `sphinx-autogen`, `sphinx-build`, `sphinx-quickstart`）が使えるようになります。

## 3. プロジェクトの作成 📁

Sphinxのインストールが完了したら、ドキュメントを作成するプロジェクトを準備します。

作業ディレクトリを作成し、以下のようにディレクトリを構成します。

```
.
├── docs/
└── main.py
```

- `docs`ディレクトリ: Sphinxプロジェクトのルートディレクトリになります。
- `main.py`: ドキュメントを生成したいPythonファイルです。

### 3.1. Sphinxプロジェクトの作成

`sphinx-quickstart`コマンドを使って、Sphinxプロジェクトの雛形を作成します。

```bash
$ sphinx-quickstart docs
```

対話形式でいくつか質問されますので、必要に応じて設定を変更してください。

```
> Separate source and build directories (y/n) [n]: y
> Project name: MyProject
> Author name(s): Your Name
> Project release []: 1.0.0
> Project language [en]: en
```

- `Separate source and build directories (y/n) [n]:` ソースファイルとビルドファイルを別のディレクトリに分けるかどうかを聞かれます。ここでは、`y`を入力してEnterを押します。
- `Project name:` プロジェクト名を入力します。
- `Author name(s):` 作者名を入力します。
- `Project release:` プロジェクトのバージョンを入力します。
- `Project language:` プロジェクトの言語を選択します。ここでは、`en`を入力してEnterを押します。

### 3.2  プロジェクトのディレクトリ構成

上記のコマンドを実行すると、`docs`ディレクトリ内に以下のようなファイルとディレクトリが生成されます。

```
docs/
├── _build/
├── _static/
└── source/
    └── conf.py
```

- `_build`: ビルドされたHTMLなどのファイルが格納されるディレクトリ
- `_static`: 静的ファイル（画像など）を格納するディレクトリ
- `source`: Sphinxのソースファイル（reStructuredText, Markdown）を格納するディレクトリ
- `conf.py`: Sphinxの設定ファイル

### 3.3. conf.pyの編集 📝

`conf.py`は、Sphinxプロジェクトの設定ファイルです。 

#### 3.3.1. 読み込むPythonファイルの設定

`docs/conf.py`を開き、以下のコードをアンコメントし、`../`に変更します。

```python
import os
import sys
sys.path.insert(0, os.path.abspath('../'))
```

これにより、`conf.py`から見て１つ上のディレクトリ内のPythonファイルを読み込むようになります。

#### 3.3.2. 拡張機能の設定

Pythonコードのdocstringを読み込む設定や、Markdownを有効にする設定などを行います。
`conf.py`内の`extensions`を以下のように変更します。

```python
extensions = [
    'sphinx.ext.autodoc',
    'sphinx.ext.napoleon',
    'myst_parser'
]
```

- `sphinx.ext.autodoc`: docstringを自動的に読み込むための拡張機能
- `sphinx.ext.napoleon`: NumpyスタイルやGoogleスタイルのdocstringをパースするための拡張機能
-  `myst_parser`: Markdownファイルからドキュメントを生成するための拡張機能

### 3.4. index.rstの編集 📝

`index.rst`はドキュメントのトップページを生成するためのファイルです。
トップページで表示したいモジュール（今回は`main`）を`index.rst`内に追加します。

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

   main
```

- `.. toctree::`: ドキュメントの目次を作成するためのディレクティブです。
- `:maxdepth:`: 目次の階層の深さを指定します。
- `:caption:`: 目次のタイトルを指定します。

インデントに注意してください。
インデントが１つずれるだけでエラーになることがあります。

## 4. ドキュメントを抽出したいPythonファイルの準備 🐍

ドキュメントを自動生成したいPythonファイル（今回は`main.py`）を作成します。
`"""`で囲まれた部分が**docstring**と呼ばれる部分で、クラスやメソッドの注釈を入れることができます。

[docstringの記法](https://www.sphinx-doc.org/ja/1.3/ext/napoleon.html)にはReStructuredTextスタイル、Numpyスタイル、Googleスタイルなどがありますが、今回は**[Googleスタイル](https://qiita.com/11ohina017/items/118b3b42b612e527dc1d)**で書きます。

```python
class TestClass:
    """Summary line.
    """

    def testfunc(self, x, y):
        """sum

        Args:
            x (int): 1st argument
            y (int): 2nd argument

        Returns:
            int: sum result

        Examples:
            >>> print(testfunc(2,5))
            7
        """
        return x + y
```

Googleスタイルのdocstringでは、以下のセクションを記述できます:

- `Args`: 引数の説明。型ヒントも記述可能。
- `Returns`: 返り値の説明。型ヒントも記述可能。
- `Examples`: 使用例。doctestとして自動テストも可能。

記法に関しては下記を参照。

- [GoogleスタイルのPython Docstringの入門](https://qiita.com/11ohina017/items/118b3b42b612e527dc1d)
- [docstringのstyle3種の例](https://qiita.com/yokoc1322/items/ebf25c9cb779ff5ebc9c)

## 5. ドキュメントを生成する 🚀

### 5.1. Pythonファイルからrstファイルを生成

コマンドラインで次のコマンドを入力します。

```bash
sphinx-apidoc -f -o ./docs/source ../
```

- `-f`: 既存のファイルを上書きする
- `-o`: 出力先ディレクトリを指定する（今回は`./docs/source`）
- `../`: ドキュメントを生成する対象のPythonファイルがあるディレクトリを指定する

詳細は[公式マニュアル](http://www.sphinx-doc.org/ja/stable/man/sphinx-apidoc.html)を参照してください。

### 5.2. rstファイルからhtmlファイルを生成

コマンドラインで、`docs`ディレクトリに移動し、以下のコマンドを入力します。

```bash
make html
```

詳細は[公式マニュアル](http://www.sphinx-doc.org/ja/stable/man/sphinx-build.html)を参照してください。

`docs/_build/html`内に`index.html`が生成されますので、ブラウザで開きます。

![2018-09-02_23h30_07.png](https://qiita-image-store.s3.amazonaws.com/0/193401/a0c79c42-1f8a-34f0-ea52-a0fba7cc327e.png)

これで最低限の文書ができました。 🎉

## 6. テーマを変更する 🎨

### 6.1. sphinx_rtd_theme を使う

`sphinx_rtd_theme`は、読みやすく、美しいドキュメントを生成できる人気のテーマです。

`sphinx_rtd_theme` をインストールします。

```bash
pip install sphinx_rtd_theme
```

`conf.py` を開き、 `html_theme` を修正します。

```python
html_theme = 'sphinx_rtd_theme'
```

再度 `make html` すると、以下のようなHTMLファイルが生成されます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/193401/673a06ae-18e6-6c29-0b55-59c6ee76e425.png" width=50%>

### 6.2. その他のテーマ

他にも以下のようなテーマがあります:

- `sphinx-material`: マテリアルデザインのテーマ
- `sphinx-book-theme`: 書籍風のデザインのテーマ
- `pydata-sphinx-theme`: Pandas等のデータ分析ライブラリのドキュメントで使われているテーマ

プロジェクトの要件に合わせて適切なテーマを選択しましょう。

## 7. 発展的な話題 🌈

### 7.1. reStructuredText と Markdown 📝

Sphinxでは、reStructuredText（rst）とMarkdownの両方を使用してドキュメントを記述できます。

#### 7.1.1. reStructuredText

reStructuredTextは、読みやすく、書きやすいマークアップ言語です。 Sphinxのデフォルトのマークアップ言語であり、多くの機能が用意されています。

##### 見出し

```rst
=====
Title
=====

Section
-------

Subsection
~~~~~~~~~~
```

##### リスト

```rst
- 項目1
- 項目2
    - 項目2-1
    - 項目2-2
- 項目3
```

##### リンク

```rst
`Sphinxの公式サイト`_

.. _Sphinxの公式サイト: https://www.sphinx-doc.org/
```

#### 7.1.2. Markdown

Markdownは、シンプルで直感的なマークアップ言語です。 多くの開発者に親しまれており、簡単に記述できます。

SphinxでMarkdownを使用するには、`conf.py`でMarkdownサポートを有効にする必要があります。

1.  `conf.py` を開き、 `extensions`  リストに  `'myst_parser'`  を追加します。

```python
extensions = [
    # ... other extensions
    'myst_parser',
]
```

##### 見出し

```markdown
# Title

## Section

### Subsection
```

##### リスト

```markdown
- 項目1
- 項目2
    - 項目2-1
    - 項目2-2
- 項目3
```

##### リンク

```markdown
[Sphinxの公式サイト](https://www.sphinx-doc.org/)
```

### 7.2. 自動ビルドとデプロイ 🚀

ドキュメントを効率的に管理するためには、自動ビルドとデプロイの仕組みを導入することが重要です。 GitHub ActionsやGitLab CIなどのCIツールを使用することで、コードの変更をトリガーにドキュメントを自動的にビルドし、Webサーバーなどにデプロイできます。

#### 7.2.1. GitHub Actionsを使った自動ビルドとデプロイ

GitHub Actionsを使った自動ビルドとデプロイの例を以下に示します。

1.  GitHubリポジトリに`.github/workflows/sphinx.yml`というファイルを作成し、以下の内容を記述します。

```yaml
name: Sphinx build and deploy

on:
  push:
    branches:
      - main

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.11'

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: Build Sphinx documentation
        run: sphinx-build -b html ./docs ./docs/_build

      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./docs/_build
```

2.  `requirements.txt`にSphinxと必要なテーマなどのパッケージを記述します。

```
sphinx
sphinx-rtd-theme
```

3.  GitHubリポジトリにプッシュすると、GitHub Actionsが実行され、ドキュメントがビルドされてGitHub Pagesにデプロイされます。

### 7.3. docstring の活用 📚

docstring は、Python のコード内にドキュメントを埋め込むための仕組みです。 Sphinx は、docstring を自動的に読み込んでドキュメントを生成する機能を備えています。

`sphinx.ext.autodoc` 拡張機能を使用することで、docstring からドキュメントを自動生成できます。

```python
extensions = [
    'sphinx.ext.autodoc',
    # ... other extensions
]
```

また、 `sphinx.ext.napoleon` 拡張機能を使用することで、Google スタイルや Numpy スタイルの docstring を解析できます。

```python
extensions = [
    'sphinx.ext.autodoc',
    'sphinx.ext.napoleon',
    # ... other extensions
]
```

docstring を活用することで、コードとドキュメントを一箇所で管理でき、ドキュメントの保守性が向上します。

### 7.4. Sphinx の拡張機能 🔧

Sphinx には、多くの拡張機能が用意されています。 拡張機能を使用することで、ドキュメントの機能を拡張したり、ドキュメント生成の自動化を行ったりできます。

#### 7.4.1. よく使われる拡張機能

- `sphinx.ext.autosummary`: モジュールやクラスのサマリーを自動生成する
- `sphinx.ext.doctest`: docstring のコード例をテストする
- `sphinx.ext.intersphinx`: 他の Sphinx プロジェクトへのリンクを張る
- `sphinx.ext.mathjax`: 数式を表示する
- `sphinx.ext.viewcode`: ドキュメントからソースコードへのリンクを張る

拡張機能の一覧は、[Sphinx公式ドキュメント](https://www.sphinx-doc.org/en/master/usage/extensions/index.html)を参照してください。

## 8. 参考資料 📖

- [Sphinx公式ドキュメント](https://www.sphinx-doc.org/en/master/)
- [Sphinx日本ユーザー会](https://sphinx-users.jp/)
- [Sphinxをはじめよう](https://www.oreilly.co.jp/books/9784873116488/)
- [Sphinxによるドキュメント作成入門](https://www.amazon.co.jp/dp/4802094993)

## 9. まとめ 🎉

本記事では、Sphinxを使って技術ドキュメントを作成する方法について解説しました。 Sphinxを使用することで、Pythonプロジェクトのドキュメントを効率的に作成し、開発効率の向上、保守性の向上に貢献できます。

ぜひ、Sphinxを活用して、質の高い技術ドキュメントを作成してみてください！ 📖✨

Happy documenting! 😄