Slack の Slash Commands をササっとできるやつをパッケージにして配布しました。 なんだかんだPyPIにばらまくのは初めでして、 いろいろ古い方法も出回っていていい感じのやり方に到達するのに手を焼いたので、 これを機にパッケージ配布に必要なものをメモしておきます。
出てくる人たち
- setup.py
- PyPI
- twine
- wheel
setup.py
Pythonのサードパーティーパッケージのインストールを行うための標準モジュールが、
setuptoolsと言う形で提供されています。
これでインストールしたパッケージはPythonのランタイムに配置され、
どこからでもimportできるようになります。
setuptoolsを利用し、独自パッケージをインストールするためのスクリプトは
setup.py
というファイル名を推奨されており、一般にも setup.py
と呼ばれます。
まず、独自パッケージは大体以下のような形になっていると思います。
.
|__ your_package/
| |__ __init__.py
| |__ foo.py
|
|__ tests/
| |__ __init__.py
| |__ test_foo.py
|
|__ LICENSE
|__ README.md
|__ requirements.txt
|__ .travis.yml
これにsetuptoolsのためのファイルなどを追加していきます。
MANIFEST.in
配布パッケージには、以下のような要素があります。
- パッケージ情報を含んだメタ情報ファイル
- パッケージモジュール本体
- ドライバやバイナリなど、追加ファイル
このうち、2と3については後述するsetup.py
で指定することになりますが、
1についてはMANIFEST.in
に指定します。
上に書いたファイル構造だと、MANIFEST.in
の内容は以下のようになると思います。
include README.md LICENSE requirements.txt
MANIFEST.in
に記述しなくても README
, README.txt
などは
自動的にパッケージに含まれますが、
基本的にパッケージに含まれるメタ情報ファイルは明示しておくことを推奨します。
setup.py
パッケージをインストールするため、また配布するために用意するファイルが
setup.py
です。
このスクリプト内ではsetuptools
というモジュールの機能を使い、
パッケージの情報を与えてセットアップを実行します。
setup.py
の基本的な形は以下のようになります。
from setuptools import setup, find_packages
setup(
name='your_package',
version='0.1',
description='Your awesome package.',
url='https://github.com/you/your_package',
license='MIT',
author='your name',
author_email='your.name@example.com',
# include all packages
packages=find_packages(exclude=['tests', '.travis.yml']),
install_requires=[
'Flask==0.11.1',
],
classifiers=[
'Development Status :: 2 - Pre-Alpha',
'Intended Audience :: Developers',
'Environment :: Web Environment',
'License :: OSI Approved :: MIT License',
'Operating System :: POSIX :: Linux',
'Programming Language :: Python :: 3.6',
'Topic :: Internet :: WWW/HTTP'
],
)
注意する情報としては、
argument | value |
---|---|
name |
パッケージの名前になります |
version |
ビルドの際必要になります |
packages |
パッケージに含まれるファイルの一覧です |
install_requires |
依存サードパーティーパッケージです |
packages
が指定されなかった場合、distutilの仕様
に従って、PythonスクリプトやCライブラリなどが自動的に含まれます。
ただ、明示することを推奨します。
また、setuptools.find_packages
のような便利なモジュールも提供されています。
setuptoolsのTipsについては、setuptoolsのドキュメンテーションが豊富です。
Building and Distributing Packages with Setuptools
Classifiers
そのパッケージがどんなものなのか、 どんな人に向けたものなのかを教えるための標準的な仕様として、
classifiers
が提供されています。 classifiersの一覧は以下にあります。
List trove classifiers - PyPI - Python
メタ情報について
パッケージのバージョンなどは、 モジュールが持つ値としてPythonスクリプト内で参照 できることを望まれる場合があります。 そのため、慣習的にパッケージのメタ情報をモジュール内に埋め込む文化があります。 これは使っているVCSの理念などにもよるものと思いますので、好みの内容です。
具体的に説明します。
パッケージのメタ情報をyour_package.__meta__
と言う形で取得したいので、
your_package/__init__.py
にその情報を書き込みます。
# your_package/__init__.py
__author__ = 'your name'
__version__ = '0.1'
__license__ = 'MIT'
こんな感じに情報を書き加えた上で、
setup.py
に
import your_package
setup(
...,
author=your_package.__author__,
version=your_package.__version__,
license=your_package.__license__,
...
)
などとすると、バージョンを切るときに setup.py
のリビジョンの変更ができなくて綺麗になると思います。
また、__init__.py
にdocstringを記述した場合your_package.__doc__
で参照できるため、
long_description
にdocstringを入れるといい感じになると思います。
配布手順
PyPI の登録
まずはpip install
できるパッケージをホストするレジストリ、
PyPIを利用するためにPyPIにユーザー登録をします。
PyPI - the Python Package Index
Registerからユーザー名とパスワード、メールアドレスを設定して登録申請します。 すると設定したメールアドレス宛に確認メールがきますので、 そのURLを踏んで最終確認事項を読み、 了承して確定するとユーザー名とパスワードでログインできるようになります。 URL踏んだだけじゃ登録完了にならないよ!
これでPython開発者として登録されます。
.pypirc 設定
PyPIをはじめとするpipレジストリへアクセスするためにはユーザー情報が必要ですが、
これらの情報をまとめた ~/.pypirc
を用意すると便利です。
.pypirc
では、pipのレジストリ(正しくはdistutilsのですが)の一覧、
それらへアクセスするための情報を記述することができます。
setup.py
は自動的にホームディレクトリに置かれた .pypirc
を読み、
レジストリへ読み書きします。
[distutils]
index-servers=
pypi
testpypi
[testpypi]
repository = https://testpypi.python.org/pypi
username = your_username
password = your_password
[pypi]
repository = https://pypi.python.org/pypi
username = matsub
password = your_password
password
項目は省略することができ、
省略した場合はsetuptoolsの実行時にパスワードを問われます。
testpypi
setuptoolsのテストを行うために、 同様の挙動を行ってくれるtestpypiというホスティングがあります。 こちらを利用したい場合は別にユーザー登録が必要となりますので、 PyPIと同様の手順でユーザー登録をしてください。
ビルド、アップロード
setup.py
が用意できたら、以下の4つの行程を済ませれば配布完了です。
もう pip install
できます。
python setup.py sdist bdist_wheel
twine register dist/project_name-x.y.z.tar.gz
twine register dist/mypkg-0.1-py2.py3-none-any.whl
twine upload dist/*
それぞれ説明していきます。
setuptools
まず最初のコマンドについて、setuptools関連です。
最初のコマンド python setup.py sdist bdist_wheel
は配布するパッケージのディストリビューションをビルドするコマンドです。
パッケージ配布には2種類の要素があり、
それぞれ sdist(source distribution), bdist(binary distribution)です。
ソースコードの配布はシンプルになりますが、
バイナリの配布は環境依存が発生するので、統一されたフォーマットが必要になります。
そのフォーマットのひとつがwheelです。
昔はeggとかあったらしいけど今はwheelが推奨されています。
setuptools は setup.py
で記述されたバージョンをラベルにビルドします。
新しいバージョンを作成した場合は新たにビルドする必要があります。
wheel形式のbdistをビルドするためには、パッケージ wheel
が必要になります。
$ pip install wheel
twine
twineはPyPIへの一連のメタ情報をあらかじめ含んだ、PyPIへのインターフェースです。
現在、パッケージ配布にはこれが推奨されています。
以前は python setup.py register -r wtf
などの一連のコマンドを打ち込み、
- PyPIへのパッケージ登録
- パッケージ情報設定
- 各パッケージアップロード
をそれぞれ行う必要がありましたが、 twineはその一連の作業を簡略化したものです。多分。 手順は、setuptoolsでビルドして、ソースを登録して、wheelオブジェクトを登録して、 アップロードするだけ。まあそらそうだって感じで覚えやすいですね。
なお、register
は初回のみ必要で、
それ以降は upload
ごとに最新版が書き込まれていきます。
twineを使用するためには、パッケージ twine
が必要になります。
$ pip install twine
おまけ
今回作ったやつはこれです
自分で作ったやつがpipで落とせると興奮するね。