LoginSignup
117
99

【PyPI 】Pythonの自作ライブラリをpipに公開する方法

Last updated at Posted at 2021-08-14

自作Pythonライブラリを全世界に公開

Pythonでライブラリをインストールする際は

pip install [ライブラリ名]

というコマンドを使うことが多いですが、
多くの人は以下のようなイメージを持っているかと思います。

「pipで公開してるライブラリってシリコンバレーのランチ無料のオフィスで働いてる凄いエンジニアが作ったんでしょ?」

image.png

このように敷居が高そうに見えるpipですが、実は一般人でもライブラリを公開することができます

何を隠そう、一般人の味方!す○家で牛丼ランチ(500円)を食べている僕でもアップロードできました。
一般ピープルでも全世界にライブラリを公開できるのは感慨深いです。

公開方法を紹介している記事はいくつかありますが、どこかしらの必要工程が抜けているものが多いように感じたので、本記事では一般的に必要とされている公開内容を網羅することを心がけて紹介したいと思います。

pipの仕組み

pipでインストール可能なライブラリは、PyPI(パイピーアイと読むらしいです)というディストリビューションサービスにアップロードされています。

つまるところ、一般人でもPyPIにユーザ登録してライブラリをアップロードすれば、pipでインストールできてしまうわけです。

自作ライブラリ公開手順

公開するライブラリが既にGitHubリポジトリ上に存在するという前提で、以下の手順でPyPIに公開します。

1. _init_.pyを作成
2. ライセンスの追加
3. README.rstまたはREADME.mdを作成
4. setup.pyの追加
5. Twineを使ってPyPIに登録
6. APIドキュメントをSphinxで作成
7. APIドキュメントをGithub Pagesにアップロード

本記事では、私が作成した自作ライブラリ「seaborn-analyzer」を例に、pipへのライブラリ公開手順を紹介します

全体の注意点として、ローカルで行う作業とリモート(GitHub)で行う作業があるので、両者の整合性がとれるよう適宜PushとPullを実施してください

1. _init_.pyを作成

モジュールのディレクトリ構造を定義する、__init__.pyを作成します。
これにより、

import seaborn_analyzer
seaborn_analyzer.custom_hist_plot.fit_dist()

というように階層構造を全て把握して記載する必要があったのが、

import seaborn_analyzer
seaborn_analyzer.fit_dist()

のように記載を短くすることができ、ユーザ側から見て使いやすくなります。
(ディレクトリ構造の定義以外にも用途はありますが、詳しくはこちらをご参照ください

・ディレクトリ構成の適正化

__init__.pyが機能するためには、適正なディレクトリ構成でモジュールを設置する必要があります。
シンプルに管理するのであれば、以下のようなディレクトリ構成が一般的です。

./ ... ルートディレクトリ
├─ LICENSE ... ライセンス定義ファイル(2章で作成)
├─ README.md ... READMEファイル(3章で作成)
├─ setup.py ... PyPIアップロード時の設定ファイル(4章で作成)
└─ seaborn_analyzer/ ... モジュールを設置するディレクトリ
    ├─ custom_hist_plot.py ...モジュールを構成する.pyファイルの一つ
    : ... ここにモジュールを構成する.pyファイルをまとめて設置
    :
    └─ __init__.py ... 本章で作成

ここで注意すべきが、モジュールを設置するディレクトリの名称です。
ここで設定したディレクトリ名が、そのまま
import seaborn_analyzer
のように、importする際のモジュール名となります

その他、モジュールを設定するディレクトリ名の制約条件として、
・ハイフン(-)は使用できない
・setup.pyのpackages引数(4章参照)には、このディレクトリ名を指定
にご注意ください。

・実際に作成したコード

上記ディレクトリ構成でseabornライブラリの記載を参考に、以下のような__init__.pyを作成しました

__init__.py
from .custom_pair_plot import *
from .custom_hist_plot import *
from .custom_class_plot import *
from .custom_reg_plot import *

__version__ = '0.1.2'

階層構造の定義だけでなく、リリースのバージョン(5章での指定と統一)もここで管理します。

2. ライセンスの追加

GitHubリポジトリにオープンソースのライセンスを追加します。
これがあると、どの程度の流用が許されるライブラリなのか、ユーザが判断することができます。
(ライセンスが定義されていないと、制限を警戒されて使ってもらえない可能性もあります)

・ライセンスの種類

以下を参考に、ライセンスを選択してください。

個人開発なら、迷ったらMIT、BSD3あたりでいいかと思います。

業務で使うのであれば、テキトーに選ぶと後でとんでもない事態に発展する事もあるので、責任者に必ず相談してください。

※余談ですが、GNU GPL v2, v3ライセンスのソフトウェアを業務で使う例が散見されますが、ソースコード開示義務が生じるので商品開発等では細心の注意を払って利用する必要があります(特に組込み系では要注意)

・GitHubリポジトリへのライセンス追加方法

リポジトリ作成時に追加する方法と、既に存在するリポジトリに追加する方法があります。

リポジトリ作成時に追加したい時

以下のリンクを参照ください

既に存在するリポジトリにライセンス追加したい時

以下のリンクを参照ください

3. README.rstまたはREADME.mdを作成

GitHubのリポジトリや後述のPyPIのトップ画面に表示されるREADMEファイルを作成します。
これがないとユーザがライブラリが何物なのかを判断する事ができないので、
下記リンクを参考に必ず作成してください。

GitHubで認識可能なREADMEの形式には、**マークダウン形式(README.md)reStructuredText形式(README.rst)**があります。
Qiitaを読んでいる時点でマークダウンに慣れている方が多いと思うので、手軽に作るならmd形式の方がお薦めです

rst形式のメリットには、後述のSphinxドキュメントとフォーマットを統一できることがあります。
rst形式の文法は以下を参照ください

私の作ったライブラリのリポジトリにも、README.md(日本語)とREADME.rst(英語)があるので、両者を比較すると分かりやすいかと思います。
image.png
(この記事やライブラリが役に立てば、右上のStarボタンも押して頂けると有難いです!)

4. setup.pyの追加

パッケージの様々な内容(パッケージ名、依存パッケージ、バージョン、作者名など)を定義する、setup.pyを作成します。
PyPIに公開するためには、このsetup.pyを正しい構文で記載する事が必須となります。

・実際に作成したコード

今回は、seabornライブラリの記載およびshapelyライブラリの記載(Readme.rstの読込部分)を参考に、以下のようなsetup.pyを作成しました。

setup.py
# Author: Kenta Nakamura <c60evaporator@gmail.com>
# Copyright (c) 2020-2021 Kenta Nakamura
# License: BSD 3 clause

from setuptools import setup
import seaborn_analyzer

DESCRIPTION = "seaborn-analyzer: data visualization of regression, classification and distribution"
NAME = 'seaborn-analyzer'
AUTHOR = 'Kenta Nakamura'
AUTHOR_EMAIL = 'c60evaporator@gmail.com'
URL = 'https://github.com/c60evaporator/seaborn-analyzer'
LICENSE = 'BSD 3-Clause'
DOWNLOAD_URL = 'https://github.com/c60evaporator/seaborn-analyzer'
VERSION = seaborn_analyzer.__version__
PYTHON_REQUIRES = ">=3.6"

INSTALL_REQUIRES = [
    'matplotlib>=3.3.4',
    'seaborn>=0.11.0',
    'numpy >=1.20.3',
    'pandas>=1.2.4',
    'matplotlib>=3.3.4',
    'scipy>=1.6.3',
    'scikit-learn>=0.24.2',
]

EXTRAS_REQUIRE = {
    'tutorial': [
        'mlxtend>=0.18.0',
        'xgboost>=1.4.2',
    ]
}

PACKAGES = [
    'seaborn_analyzer'
]

CLASSIFIERS = [
    'Intended Audience :: Science/Research',
    'License :: OSI Approved :: BSD License',
    'Programming Language :: Python :: 3',
    'Programming Language :: Python :: 3.6',
    'Programming Language :: Python :: 3.7',
    'Programming Language :: Python :: 3.8',
    'Programming Language :: Python :: 3.9',
    'Programming Language :: Python :: 3 :: Only',
    'Topic :: Scientific/Engineering',
    'Topic :: Scientific/Engineering :: Visualization',
    'Topic :: Scientific/Engineering :: Artificial Intelligence',
    'Topic :: Multimedia :: Graphics',
    'Framework :: Matplotlib',
]

with open('README.rst', 'r') as fp:
    readme = fp.read()
with open('CONTACT.txt', 'r') as fp:
    contacts = fp.read()
long_description = readme + '\n\n' + contacts

setup(name=NAME,
      author=AUTHOR,
      author_email=AUTHOR_EMAIL,
      maintainer=AUTHOR,
      maintainer_email=AUTHOR_EMAIL,
      description=DESCRIPTION,
      long_description=long_description,
      license=LICENSE,
      url=URL,
      version=VERSION,
      download_url=DOWNLOAD_URL,
      python_requires=PYTHON_REQUIRES,
      install_requires=INSTALL_REQUIRES,
      extras_require=EXTRAS_REQUIRE,
      packages=PACKAGES,
      classifiers=CLASSIFIERS
    )

・setup.pyの作成手順

上記のようなsetup.pyは、以下の手順で作成します
・setuptoolsのインストール
from setuptools import setupでsetupメソッドをインポート
・setupメソッドに各種情報を入力

setuptoolsのインストール

pip install setuptools

setupメソッドに各種情報を入力

setupメソッドの引数に各種情報を入力します。
主な引数は以下のようになります

引数名 入力する情報
name ライブラリの名前(PyPIにこの名前で登録される)
author 作者名
author_email 作者のEメールアドレス
maintainer 管理者(個人開発なら作者と同じ)
maintainer_email 管理者のEメールアドレス
description ライブラリの簡単な説明
long_description ライブラリの詳細説明。READMEを登録するとPyPIのトップ画面に表示される
license 手順2で作成したライセンス
url URL(GitHubのURLを登録することが多い)
version バージョン(二重管理防止のため_init_.pyから読込む事が望ましい)
download_url ダウンロードURL(GitHubのURLを登録することが多い)
python_requires Pythonのバージョン要件
install_requires 必須パッケージ
extras_require 推奨パッケージ
packages パッケージ構成(複数登録することも可能)
classifiers 各種分類情報

必須パッケージに何を書けばいいか分からない!」
という方も多いかと思いますが、最低限、Importしているパッケージを記載しておけばよいかと思います。
バージョン制約も全て調べるときりがないので、最低限、自分が動作確認したときのバージョンを記載しておけばよいかと思います。

※READMEとPyPIのトップ画面

long_description引数に手順3で作成したREADME.rstまたはREADME.mdを登録すると、PyPIサイトのライブラリトップ画面に登録したREADMEが表示されます。
ユーザがググった結果PyPIサイトに誘導されることもあるので、この方法でREADMEを登録しておくと、ユーザに親切かと思います。

上のsetup.pyの例ではREADME.rstを登録していますが、同じ手順でREADME.mdを登録する事も可能です(例:optunaのget_long_description()メソッド

5. Twineを使ってPyPIに登録

ここでついにPyPIにライブラリを登録し、全世界に公開します。
PyPIにライブラリを登録するためのツールはいくつかありますが、今回はTwineを使います(セキュリティ面でメリットがあるそうです

・TwineとWheelのインストール

ソースコードのビルドに必要なツールである、TwineとWheelをインストールします

pip install twine
pip install wheel

・ライブラリのビルド

PyPIへの公開に必要なソースコード配布物およびWheelパッケージをビルドします。

ソースコード配布物のビルド

ライブラリのルートフォルダ(setup.pyがあるフォルダ)で以下のコマンドを実施し、ソースコード配布物をビルドします

python setup.py sdist

以下のように、「dist」フォルダおよび「パッケージ名.egg-info」フォルダができれば成功です
image.png

Wheelパッケージのビルド

ライブラリのルートフォルダ(setup.pyがあるフォルダ)で以下のコマンドを実施し、Wheelパッケージをビルドします

 python setup.py bdist_wheel

以下のように、「build」フォルダができれば成功です
image.png

・PyPIへのユーザ登録

PyPIへのライブラリアップロードには、ユーザ登録が必要となります。

テスト用PyPIと本番用PyPI

ここで注意すべきが、PyPIにはテスト用と本番用のサイトが存在することです。

PyPIは一度アップロードすると同じバージョンで再アップロードできない(再アップロードにはバージョンを上げる必要がある)ので、本番用PyPIでミスをして無駄にバージョンが上がることを防ぐため、事前にテスト用PyPIで問題なくアップロードできることを確認することが望ましいです。

テスト用PyPIのユーザ登録

以下のサイトに名前、メールアドレス、ユーザ名、パスワードを入力し、「Create acount」を押して届いたメールの指示に従うと、登録が完了します

本番用PyPIのユーザ登録

以下のサイトに名前、メールアドレス、ユーザ名、パスワードを入力し、「Create acount」を押して届いたメールの指示に従うと、登録が完了します

2段階認証の有効化

 2024/1より、PyPIの2段階認証が必須化されました。これに伴い、2段階認証を有効化しないとパッケージのアップロードができなくなりました。テスト用PyPI、本番用PyPI共に、以下操作で2段階認証を有効化してください

2段階認証はPyPIにログイン後、以下の"アカウント設定"タブより有効化できます(リカバリコードを事前にダウンロードしていなかった場合、ダウンロードしてくださいとのメッセージが出てくるので、ダウンロードしたのちにコードの1つを入力欄に記載することでこの画面に進めます)

スクリーンショット 2024-01-27 19.08.20.png

 2段階認証の認証方法にはスマホ等のAuthenticatorアプリとUSBキーの2種類がありますが、今回はAuthenticatorアプリを使用します。上記「Add 2FA with authentication application」をクリックして表示されるQRコードを、Google AuthenticatorアプリScan a QR codeボタンから読み込んで追加します。
 するとGoogle AuthenticatorにPyPIのワンタイムパスワードが表示されるようになるので、これをPyPIのサイトの「認証コード」欄に入力します(60秒ごとに更新されるのでご注意ください)

APIトークンの追加

 2024/1より、PyPIのユーザー/パスワード認証によるパッケージアップロードが無効になりました。これに伴い、APIトークンを追加して.pypircに記載しないとパッケージのアップロードができなくなりました。テスト用PyPI、本番用PyPI共に、以下操作でAPIトークンを追加してください。

2段階認証と同様、"アカウント設定"タブにある以下の"APIトークンの追加"をクリックします。

スクリーンショット 2024-01-27 19.19.32.png

 トークン名、スコープ(全パッケージを対象とするか、特定のパッケージのみを対象とするか)を指定します。

スクリーンショット 2024-01-27 19.24.00.png

 "Create token"をクリックするとトークンが表示されます。一度しか表示されないので必ずどこかにコピーを控えてください(ただし忘れてしまっても再生成すればOKです)

・.pypircを作成

TwineによるPyPIアップロード時の設定ファイルである.pypircを作成します。
以下のように、セクションを分けてテスト用と本番用のPyPI登録情報を記載します

2024年1月以降(APIトークン認証)

以下のように.pypircにAPIトークン記載してください(2023年以前は使用できたユーザ名/パスワードの記述は現在は使用できません)

.pypirc
[distutils]
index-servers =
  pypi
  testpypi

[pypi]
repository: https://upload.pypi.org/legacy/
username: __token__
password: 先ほど生成した本番用PyPIのAPIトークン

[testpypi]
repository: https://test.pypi.org/legacy/
username: __token__
password: 先ほど生成したテスト用PyPIのAPIトークン

.pypircの作成先ですがLinuxの場合はホームディレクトリに、
Windowsの場合はPowerShellで$HOMEと打って出てきたフォルダに作成します。
$HOMEが登録されていないときは、$env:HOME = 'HOMEに登録したいフォルダ名'と打つことで登録可能です(参考

参考: パスワード認証の場合の.pypirc(2023年以前)

2023年以前は以下のユーザ名/パスワードの記述でもOKでしたが、2024/1以降は使用できなくなりました

.pypirc
[distutils]
index-servers =
  pypi
  testpypi

[pypi]
repository: https://upload.pypi.org/legacy/
username: 本番用PyPIのユーザ名
password: 本番用PyPIのパスワード

[testpypi]
repository: https://test.pypi.org/legacy/
username: テスト用PyPIのユーザ名
password: テスト用PyPIのパスワード

・テスト用PyPIへのライブラリアップロード

以下のコマンドで、テスト用PyPIへライブラリをアップロードします。

twine upload --repository testpypi dist/*

以下のようにテスト用PyPIにアップロードしたライブラリのURLが表示されれば成功です。
README.rst(またはREADME.md)がリンク先のトップ画面に表示されている事も確認しましょう。

View at:
https://test.pypi.org/project/seaborn-analyzer/0.1.3/

※The description failed to render in the default format of reStructuredText.とエラーが出た時

README.rstをlong_descriptionに指定している場合、高確率でこのエラーが発生するかと思います。
これは、README.rstのフォーマット違反により、レンダリングが失敗することによって発生します。

厄介なのが、GitHubeで正常に表示できているように見えても、このエラーが発生しうることです。
PyPIで.rstファイルをレンダリングする際と同様のreadme-rendererが、pipで提供されているので、
これを使って原因箇所を特定するのが便利です。

pip install readme-renderer

でreadme-rendererをインストールし、

python -m readme_renderer README.rst -o README.html

でレンダリングを実行できます。
失敗した時は、以下のようにエラー箇所と内容が表示されます。

<string>:1: (WARNING/2) Title overline too short.

=======
seaborn-analyzer
=======

上の例では、タイトルの===がタイトル名に比べて短すぎることが原因だと分かります。
このようなエラーメッセージに応じてsetup.pyを修正し、エラーが出なくなるまで繰り返す事で、正しいREADME.rstを作成することができます。
setup.py修正後は前述のソースコード配布物およびWheelパッケージのビルドもやり直しましょう。

また、README.mdをlong_descriptionに指定しているとき、setup.pyにdescription-content-type引数を指定しないと、同様のエラーが出るようです(参考

上記以外にも、当該ライブラリをローカルにpipでインストール済の場合、インストールされた古いバージョンのライブラリがアップロード対象となって失敗することもあるので、注意してください。この場合は古いバージョンのライブラリをアンインストールすればOKです。

・テスト用PyPIからpipでライブラリインストールを確認

以下のコマンドでテスト用PyPIからライブラリがインストールできることを確認します。
このタイミングでライブラリの動作確認も行う事が望ましいです。

pip install --index-url https://test.pypi.org/simple/ [パッケージ名]

動作確認が完了したら、下記コマンドでいったんライブラリをアンインストールします

pip uninstall [パッケージ名]

・本番用PyPIへのライブラリアップロード

テスト用PyPIで問題がないことを確認したら、以下のコマンドで、本番用PyPIへライブラリをアップロードします。

twine upload --repository pypi dist/*

以下のようにテスト用PyPIにアップロードしたライブラリのURLが表示されれば成功です。
README.rst(またはREADME.md)がリンク先のトップ画面に表示されている事も確認しましょう。

View at:
https://test.pypi.org/project/seaborn-analyzer/0.1.3/

・本番用PyPIからpipでインストール確認

以下のコマンドで、ライブラリがインストールできることを確認します。
ライブラリの簡単な動作確認も一緒に行いましょう

pip install [ライブラリ名]

・GitHubにバージョンタグをつける

以下の手順で、GitHubに_init_.pyと同じバージョンのタグをつけます
image.png
下記赤枠の内容を記載し、「Publish release」を押します
image.png
これでライブラリの公開自体は完了です。
以降の作業で、ドキュメントを充実させていきます。

6. SphinxでAPIドキュメントを作成

ある程度Pythonを使っている人であれば、公式のAPIドキュメントに助けられた経験が何度もあるかと思います。
そして使おうと思ったライブラリにまともなAPIドキュメントがなかったときの絶望感も‥

というわけで、せっかく作ったライブラリを使ってくれるユーザに同じ絶望感を味合わせないよう、APIドキュメントを整備しましょう
Pythonではコード内で説明コメント(Docstring)を適切に記載しておけば、自動でAPIドキュメントを作ってくれるSphinxという素晴らしいライブラリがあります。
image.png
Sphinxに関しての詳細は、以下のページが分かりやすいです

・Docstringでメソッドやクラスの仕様を記載

docstringとは、Pythonのメソッドやクラスに対する説明文を記載するためのコメントのフォーマットで。
決められたフォーマットで記載することで、SphinxによりAPIドキュメントとして出力する事ができます。

具体的にはreStructuredText、Google style、Numpy styleの3種類のフォーマットがあります。
詳しくは以下のサイトを参照ください

私はNumpy Styleが好きなので、外部から呼び出すメソッド(先頭にアンダースコアのないメソッド)全てに対して、以下のようにNumpy StyleでDocstringを記載しました

hist.fit_distメソッドのdocstring記載例
    def fit_dist(cls, data: pd.DataFrame, x: str=None, hue=None, dist='norm', ax=None, binwidth=None, bins='auto', norm_hist=True,
                  floc=None, sigmarange=4, linecolor='red', linesplit=200, hist_kws={}):
        """
        `ここにメソッドの処理概要を記載`
        Fit distributions by maximum likelihood estimation, and calculate fitting scores.

        `ここに引数一覧を記載`
        Parameters
        ----------
        data : pd.DataFrame, pd.Series, or pd.ndarray
            Input data structure. Either a long-form collection of vectors that can be assigned to named variables or a wide-form dataset that will be internally reshaped.
        x : str, optional
            Variables that specify positions on the x. Available only if data is pd.DataFrame.
        hue : str, pd.Series, or pd.ndarray, optional
            Semantic variable that is mapped to determine the color of plot elements. If data is pd.DataFrame, the argument must be key in data.
        dist : {'norm', 'lognorm', 'gamma', 't', 'expon', 'uniform', 'chi2', 'weibull'} or list, optional
            Type of fitting distribution or list of distrbutions.
        ax : matplotlib.axes.Axes, optional
            Pre-existing axes for the plot. Otherwise, call matplotlib.pyplot.gca() internally.
        binwidth : float, optional
            Width of each bin, overrides bins.
        bins : int, optional
            Generic bin parameter that can be the name of a reference rule, the number of bins, or the breaks of the bins. Passed to numpy.histogram_bin_edges().
        norm_hist : bool, optional
            If True, the histogram height shows a density rather than a count.
        floc : float, optional
            Hold location parameter fixed to specified value. If None, location parameter is fitted by maximum likelihood estimation except when dist is 'weibull' or expon'. See https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit
        sigmarange : float, optional
            Set the x-axis view limits. The lower limit is -sigmarange * std(data) + mean(data). The higher limit is sigmarange * std(data) + mean(data).
        linecolor : str or List[str], optional
            Color of fitting line or colors of fitting lines. See https://matplotlib.org/stable/gallery/color/named_colors.html
        linesplit : int, optional
            Number of fitting line divisions.
        hist_kws : dict, optional
            Additional parameters passed to seaborn.histplot() other than the above arguments.
        
        `ここに戻り値一覧を記載`
        Returns
        ----------
        all_params : dict
            Parameters estimated by maximum likelihood estimation.
        all_scores : dict
            Fitting scores, which consist of RSS, AIC, and BIC.
        """

・Sphinx作業用フォルダを作成

Git管理対象のルートフォルダに、以下の2フォルダを作成します

フォルダ名 用途
docs_src Sphinxのプロジェクト用フォルダ(.rstファイルやconf.pyなどのソースを保持)
docs 作成したAPIドキュメントのhtmlファイル格納用(あとでgithub.ioで公開)

・Sphinxのインストール

以下のコマンドでSphinxをインストールします。

pip install sphinx

Sphinxのページデザインはデフォルトだと味気ないので、人気のデザインテーマ「Read The Docs」も以下コマンドでインストールします

pip install sphinx_rtd_theme

・Sphinxプロジェクトを作成

以下コマンドでSphinxプロジェクト(Sphinxで作業をするためのディレクトリと設定ファイル)を作成します。

sphinx-quickstart docs_src

※docs_srcの部分は作業ディレクトリ名に合わせて変えてOKです

以下の質問が表示されたら、そのままEnterします

> ソースディレクトリとビルドディレクトリを分ける(y / n) [n]: 

以下の質問でにライブラリの情報を記載します

> プロジェクト名: [ライブラリ名を記載(例:seaborn_analyzer)]
> 著者名(複数可): [著者名を記載]
> プロジェクトのリリース []: 0.1.3

以下の質問が表示されたら、そのままEnterします

> プロジェクトの言語 [en]: 

docs_srcというフォルダが作成され、その中にconf.py(Sphinxでのビルド時の設定ファイル)やindex.rst(ドキュメントのトップページのベースとなるrstファイル)が生成されれば成功です。

・sphinx-apidocでAPIドキュメントのrstファイルを作成

sphinx-apidocというSphinxのコマンドを使うことで、PythonのAPIドキュメントのベースとなるrstファイルを自動作成します。

sphinx-apidoc -o [出力先フォルダ] [仕様書対象コードのあるフォルダ]
実行例
sphinx-apidoc -f -o ./docs_src ./seaborn_analyzer

※-fオプションは、元々出力先のドキュメントが存在するときも、強制的に上書きする事を意味します

このコマンドにより、新たに対象ライブラリのモジュール構成が記載されたrstファイル(上のコマンドでの例:seaborn_analyzer.rst)が生成されます。

・conf.pyを編集してAPIドキュメントの自動作成を可能とする

conf.pyのうち、以下の部分を書き換えてDocstringによるAPIドキュメントのビルド設定を

プロジェクトのルートフォルダを指定

下記部分のコメントアウトを解除してパスを書き換えます

conf.pyの一部
import os
import sys
sys.path.insert(0, os.path.abspath('..'))

バージョンを自動読込できるよう修正

release='*.*.*'となっている部分を以下のように書き換えます

conf.pyの一部
import seaborn_analyzer
release = seaborn_analyzer.__version__

docstringを自動読込できる拡張機能を追加

以下を追記します

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

sphinx.ext.autodocはdocstringの自動読込、
sphinx.ext.napoleonはNumpyスタイルおよびGoogleスタイルのdocstringをパースするための拡張機能です

デザインテーマをRead The Docsテーマに変更

Sphinxデフォルトのデザインテーマ'alabaster'は味気なく感じる人が多いかと思うので、他のテーマに変更することをお勧めします。

今回は定番の人気テーマRead The Docsを使用します。

事前にpip install sphinx_rtd_themeしておき、
conf.pyのhtml_theme = 'alabaster'となっている部分を以下のように書き換えます

conf.pyの一部
import sphinx_rtd_theme
html_theme = "sphinx_rtd_theme"
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]

・ビルドしてhtmlファイルを生成

docs_srcフォルダに存在するconf.py(ビルド設定)や.rstファイル(sphinx-apidocで生成済)に基づいてSphinxによるビルドを実行し、docsフォルダにAPIドキュメントのhtmlファイルを生成します。

sphinx-build [conf.py等のあるフォルダ] [出力先フォルダ]
実行例
sphinx-build ./docs_src ./docs

なお出力先フォルダ名は次節でGitHub Pagesに仕様書をアップロードしたい場合、「docs」という名前にする必要があります。

ビルドによりSphinxが自動でDocstringをパースし、いい感じにドキュメントのWebページを生成してくれます。

アンダースコアのついたメソッド、プロパティは自動で無視されるなど、かなり芸が細かい解釈をしてくれます。

また、生成したドキュメントのスタイルシートやjavascriptファイルは、_staticフォルダ内に格納されます。

デザインをいじりたいときは、基本的にsphinx-apidocで生成したrstファイルを変更して再ビルドすれば良いです。
好みのデザインは人により異なるので、色々と試してみると良いかと思います。

7. APIドキュメントをGithub Pagesにアップロード

Docstringで生成したAPIドキュメントですが、そのままだとローカルでしか閲覧できません。

インターネット上で全世界に公開したい場合は、GitHubが提供しているウェブホスティングサービスである**Github Pages(github.io)**を使用すると便利です。

・.nojekyllを作成

Github Pagesでは、Jekyllの動作によりうまくスタイルシートを読み込んでくれないので、
ビルドしたhtmlファイルのあるフォルダ(上の例ではdocsフォルダ)に.nojekyllを作成します。
例えばLinuxでは、以下のコマンド

touch .nojekyll .docs

Windowsでは、VScodeなどのエディタやエクスプローラで右クリックし、空のファイルを作成すればよいかと思います。

・APIドキュメントをGitHubにPush

恐らくSphinxによるAPIドキュメントのビルド作業はローカルで行ったかと思うので、生成したファイル一式をGitHub上にPushします。

_staticフォルダ内のCSSやJavaScriptファイルも含め、docsフォルダ内のファイルは全てPushしてGitHub上にアップロードしましょう。

・GitHub PagesにAPIドキュメントをアップロード

以下の手順で、docsフォルダ内のWebページをGitHub Pagesに登録します。
反映までに数分かかることもあるので、気長に待ちましょう
image.png
image.png
うまくいけば、下のリンクのようなドキュメントのWebページが公開されるはずです

自動で体裁が整ったドキュメントが生成するので、なかなか感動的です

おわりに

以上で、pipへの自作ライブラリアップロードは完了となります。

有名どころのライブラリでも意外とドキュメントが整備されていなかったりするので、
ここまでやればシリコンバレーのつよつよエンジニアが見ても

「個人開発にしては真面目にやってるな」

と思ってもらえるのではと思います。
(外面を整えてもライブラリの内容自体がショボいと悲しいですが‥笑)

117
99
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
117
99