加具留矢流余

かぐるやるよ

パッケージを作成してpypiにアップロード(2020/06)

作成したライブラリをpypiに公開しようとしたが情報過多で迷子になった。
やるべきことをトップダウンに書き出せば後世の人々が救われる気がしたのでメモを残す。
困ったことがあれば公式のチュートリアルを見るのが一番。

docs.python.org

  1. ライブラリの準備
  2. 必要なファイルの準備

    • setup.pyを作成
    • setup.cfgの作成
    • LICENCEファイルの準備
    • READMEの準備
  3. 配布物の作成

    • sdistの準備
    • bdist, wheelの準備
  4. 公開の準備

    • pypiに登録
    • 配布物のアップロード

ライブラリの準備

以下3つのライブラリが最低限必要 * setuptools * wheel * twine 脳死で以下のコマンドを実行すればOK。

python -m pip install setuptools wheel twine

必要なファイルの準備

LICENCEやREADMEなどは正直用意して配置するだけなので取り立てての説明は必要に無いと思うが、setup.pyとsetup.cfgに関しては歴史的な経緯で見るサイトによって様々な方法が書いてあるように思う。2020年6月の時点ではsetup.pyは最低限にして、setup.cfgに必要な情報を記載していくのがいいようだ。

setup.py

かつてのdistutilやsetuptoolsではsetup.py内に必要なメタデータをすべて記載しなければならなかったが、setuptoolsのバージョン30あたりを皮切りに自動でsetup.cfgに記載されているデータを読み込んでくれるようになったようだ。なのでsetup.pyは以下のように最低限必要な内容(3行)にして、静的な情報はsetup.cfgに記載するのが管理しやすいように思う。素人なのでよくわからないがインストール時に動的に変更したい内容などがある場合にはsetup.pyに記載するのがいいのだろうか。

#!/usr/bin/env python
from setuptools import setup
setup()

setup.cfg

[metadata]
name = project name
version = 0.0.1
author = Taro Tanaka
author_email = example@example.com
description = project short description
long_description = file:README.md
long_description_content_type = text/markdown
url = https://mikebird28.hatenablog.jp/
licence = file: LICENCE
python_requires = >=3.5
classifiers = 
  Development Status :: 2 - Pre-Alpha
  License :: OSI Approved :: MIT License
  Programming Language :: Python :: 3.5
  Programming Language :: Python :: 3.6
  Programming Language :: Python :: 3.7
  Programming Language :: Python :: 3.8
  Programming Language :: Python :: 3.9

上みたいな感じで必要な情報を記載していけばいい。long_descriptionやlicenceなど情報量が多くなりそうなところは、file: という表記を使って外部ファイルを読み込むことができる。分かりづらいのはclasifiersとlong_descriptionだろうか。

classifiersに指定した情報はユーザーがpypi内で検索するときなどに使われる。Classifiers · PyPIに使用可能なclassifier一覧があるのでここからコピーして貼り付けて行けばいい。種類がありすぎてざっとしか目を通せなかったが、開発状況(アルファ、ベータなど)、自然言語(日本語、英語など)、プログラミング言語pythonのバージョンだけでなく、CやRなどの他の言語も指定できる)、ライセンス、その他トピックなどが指定できるようだ。

long_descriptionには直接setup.cfgに記載してもfile:でREADMEを読み込んでもどちらでも大丈夫だが、MARKDOWNファイルの場合にはlong_description_content_typeでファイルの形式を明示的に指定する必要がある。

README.md

README。気合入れて書く。この記事参考にして頑張った。 deeeet.com

LICENCE

ライセンスを選ぶ。GPLBSD、MIT等々好きなやつを選んでLICENCE.txtに記載する。

配布物の準備

これまでの作業で必要なファイルの準備が整ったので、公開に向けてパッケージを配布可能な形式に変換する。pypiでライブラリを公開するには以下2種類のアーカイブを用意する必要がある

これらのファイルをpypiにアップロードすると現在のpipではwheel形式を優先的にインストールする。

sdist

python setup.py sdist

bdist

python3 setup.py bdist_wheel

dist/以下にアーカイブされた配布用ファイルが配置されている。

  • dist/package_name.whl
  • dist/package_name.tar.gz

最悪sdistのみで配布して、ユーザー側でインストールするときにビルドしてもらえば最悪大丈夫?
ただwheel形式で配布することで不利益を被ることは無さそうなので、作成しない選択肢は無さそう。

pypiへの登録

pypiは本番環境とテスト環境の2つがあるので、それぞれアカウントを作成する。

アカウントの準備が整ったらtwineを使ってテスト環境にパッケージをアップロードする

テスト環境へのアップロード

python -m twine upload --repository testpypi dist/*

本番環境へのアップロード

python3 -m twine upload --repository pypi dist/*

最後にpypiにログインして正しくアップロードができているかを確認すれば終了。 ちなみに今回自分が作成したパッケージは↓なので興味があれば見てみてください。現時点では使い物にならないです。 pypi.org

参考文献

Python パッケージングの標準を知ろう - Tech Blog - Recruit Lifestyle Engineer