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

PyPI再デビューを果たすため、あしたを求めてウロウロしていたら、あっという間に十日が過ぎていました。

とりあえず、手持ちのPython本の中から、パッケージ作成とPyPIへのアップロードへの解説があるものピックアップ。

何度も読み直した後、試行錯誤を重ねてはググり、ググっては試行錯誤を重ねた結果、ようやくPyPI再デビューを果たすことができました(しかし、ほとんどのPythonプログラマーは私が再デビューしたことは知りません。というか、そもそも、そんな奴元からおったんかいな?というレベルだと思います)。

Pythonのパッケージを作成する際、ディレクトリ構成をどのようにするかについては色々なやり方があるのですが、この記事ではPyPIへのパッケージアップロードに焦点を絞るため、最も簡単な構成で説明したいと思います。

すなわち、プロジェクトディレクトリに1つのプログラムファイルと__init__.py、setup.pyだけがあるというものです。

仮想環境の構築〜コーディング

■仮想環境の構築
このプロジェクト専用の開発環境を構築します。

$ mkdir myux
$ cd myux
$ python3 -m venv venv
$ source venb/bin/activate

■パッケージ作成およびアップロードに必要なパッケージのインストール

$ pip install twine wheel

■プログラム作成
myuxの下にプロジェクト用ディレクトリを作成します。

$ mkdir myux_pkg

そして、このディレクトリの中に以下のようなコードでsay.pyというPythonスクリプトを作成しました。

def hello(name):
    print('{}さん、こんにちは。'.format(name))

def bye(name):
    print('{}さん、さようなら。'.format(name))

パッケージ名.関数の形(例.myux.hello())で呼び出せるように、以下の内容で__init__.pyを作成します。

from .say import *

■setup.pyの作成
myux_pkgの下に以下のようなコードでsetup.pyを作成しました。

from setuptools import setup

setup(
    name='myux2', # PyPIでの名前。間違えてmyuxというパッケージ名をPyPIの管理画面上で削除してしまったため、やむなくmyux2にしています。
    version='0.0.1',
    author='ux68k',
    author_email='hogehoge@ooub.net',
    url='https://www.ooyub.net',
    packages=['myux'],  # Pythonプログラムからimportする時のパッケージ名
    package_dir={'myux':''}, # myuxパッケージのトップディレクトリはsetup.pyと同じディレクトリ
)

パッケージのコンパイル

カレントディレクトリをmyux_pkgに変更し、以下のコマンドを入力する。

$ python setup.py bdist_wheel

カレントディレクトリにdistというディレクトリが作成され、その中に
myux-0.0.1-py3-none-any.whlというファイルが作成される。

PyPIへアップロードする

以下のコマンドを入力します。

$ twine upload --repository-url https://upload.pypi.org/legacy/ dist/myux-0.0.1-py3-none-any.whl
Enter your username: ux68k                  
Enter your password:                                    
Uploading distributions to https://upload.pypi.org/legacy/
Uploading myux-0.0.1-py3-none-any.whl              
100%|████████████████████████████████████████████| 3.85k/3.85k [00:02<00:00, 1.42kB/s]

pypi.orgで私のプロジェクトページを見ると、今アップロードしたばかりのパッケージが表示されました。

こんな嬉しいことはない!(T_T)

メモ
『エキスパートPythonプログラミング改訂2版』によれば、repository-urlに指定するURLはhttps://upload.pypi.org/とあるが、実際にやってみると以下のようなエラーが出た。

HTTPError: 405 Client Error: Method Not Allowed for url: https://upload.pypi.org/

こちらの記事に『https://upload.pypi.org/legacy/』とあったのでやってみたところ、うまく行った。

パッケージのダウンロードテスト

今作ったばかりのパッケージを別の仮想環境でダウンロードし、ちゃんと使えるかテストします。
まずは、インストール。

$ pip install myux2

Pythonの対話モードで実験。

$ python
>>> import myux
>>> myux.hello('太郎')
太郎さん、こんにちは。
>>> myux.bye('次郎')
次郎さん、さようなら。

よし、成功。

メモ

PyPIにアップロードしたパッケージを削除しても、同じパッケージ名は使うことが出来ない。

参考文献

『Pythonプロフェッショナルプログラミング第2版』P.50〜P.90
『テスト駆動Python』P.205〜P.213
『エキスパートPythonプログラミング改訂2版』P.194〜P.200