CUBE SUGAR CONTAINER

技術系のこと書きます。

Python: Twine を使って PyPI にパッケージをアップロードする

Python のサードパーティ製パッケージは、一般に PyPI (Python Package Index) というリポジトリに登録されている。 このリポジトリはユーザ登録さえすれば誰でも自分で作ったパッケージをアップロードできる。 今回は Twine というツールを使って PyPI にパッケージをアップロードしてみる。

PyPI - the Python Package Index : Python Package Index

使った環境は次の通り。

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.12.6
BuildVersion:   16G1114
$ python --version
Python 3.6.3
$ twine --version
twine version 1.9.1 (pkginfo: 1.4.1, requests: 2.18.4, setuptools: 38.2.5,
requests-toolbelt: 0.8.0, tqdm: 4.19.5)

どうして Twine を使うのか

以前は PyPI にパッケージをアップロードするときにはセットアップスクリプト (setup.py) の upload コマンドを使うのが一般的だった。 ただ、このやり方だと古い Python ではプロトコルに HTTP が使われるためユーザ名やパスワードが平文でネットワークに流れてしまう。 また、プロトコルに HTTP over SSL/TLS を使っていても、証明書を検証していないと中間者攻撃のリスクがある。

Issue 12226: use HTTPS by default for uploading packages to pypi - Python tracker

そのため、プロトコルが HTTP over SSL/TLS でちゃんと証明書の検証までやってくれる Twine を使うことがセキュリティ的に望ましい。 また、ファイルをアップロードするときの使い勝手という点でも Twine の方が優れている点がある。

ちなみに Twine は PyPA (Python Packaging Authority) というワーキンググループがメンテナンスしている。 これは setuptoolspipvirtualenv といったパッケージ関連でデファクトなツールのメンテナンスをしているコミュニティ。

Python Packaging Authority — PyPA documentation

インストール

前置きが長くなったけど、ここからは Twine を実際に使っていく。

まずは Twine を pip を使ってインストールする。

$ pip install twine

PyPI にユーザ登録する

続いて PyPI にユーザ登録をする。 以下の Web サイトの「Register」からユーザ登録を完了しよう。

PyPI - the Python Package Index : Python Package Index

あるいは、新しい Web サイトの以下からでも良い。

PyPI - the Python Package Index · Warehouse (PyPI)

同時にテスト用の PyPI にも別途ユーザ登録しておこう。 こちらにも登録しておくとリリース作業の予行演習ができる。

PyPI - the Python Package Index : Python Package Index

テスト用の PyPI についても新しい Web サイトがある。

PyPI - the Python Package Index · Warehouse (TestPyPI)

設定ファイルを用意する (オプション)

必須ではないんだけど、設定ファイルを用意しておくとこれからの作業が捗る。 ホームディレクトリに .pypirc という名前でファイルを作っておくと Twine がデフォルトで読み込んでくれる。

書式はこんな感じ。 <your_username><your_password> の部分は、先ほど自分で登録したユーザ名とパスワードに置き換える。

$ cat << 'EOF' > ~/.pypirc 
[distutils]
index-servers =
  pypi
  pypitest

[pypi]
repository=https://upload.pypi.org/legacy/
username=<your_username>
password=<your_password>

[pypitest]
repository=https://test.pypi.org/legacy/
username=<your_username>
password=<your_password>
EOF

アップロードしたいパッケージを用意する

次は PyPI にアップロードしたいパッケージを用意する。 今回は自作パッケージの diagram-autobuild を例にして説明する。

github.com

パッケージをビルドする

用意ができたら、まずはアップロードしたいパッケージの成果物をビルドする。

例えばソースコード配布物をビルドするなら、次のようにセットアップスクリプトに sdist を指定する。

$ python setup.py sdist

Wheel パッケージなら bdist_wheel を指定する。

$ python setup.py bdist_wheel

するとプロジェクトの dist ディレクトリ以下に成果物ができる。

$ ls dist
diagram-autobuild-0.1.0.tar.gz               diagram_autobuild-0.1.0-py2.py3-none-any.whl

パッケージをアップロードする

あとは twine upload コマンドを使って dist ディレクトリ以下のアップロードしたいファイルを指定するだけ。 アップロード先は --repository オプションで指定する。 まずはテスト用の PyPI にアップロードして内容を確認しよう。

$ twine upload \
  --repository pypitest \
  dist/*

ちなみに、先ほどの設定ファイルを作っていない状態でテスト用の PyPI にアップロードしたいときは --repository-url を使えば良い。

$ twine upload \
  --repository-url https://test.pypi.org/legacy/ \
  dist/*

テスト用の PyPI に意図通りパッケージがアップロードできていることを確認しておこう。

diagram-autobuild · Warehouse (TestPyPI)

問題がなければ本番の PyPI にもリリースする。

$ twine upload \
  --repository pypi \
  dist/*

本番の PyPI にパッケージがアップロードできていることを確認しよう。

diagram-autobuild · Warehouse (PyPI)

最後に、ちゃんとアップロードしたパッケージを pip 経由でインストールできることを確認できたら作業はおわり。

$ pip install diagram-autobuild
$ pip list --format=columns | grep diagram-autobuild
diagram-autobuild 0.1.0  

めでたしめでたし。