Pythonで書いたプログラムをエンドユーザーに配布することになった。
カウンターパートの希望で、PyPIのようなpip経由でインストール可能な形式と、圧縮ファイル形式の2種が必要となった。
前者はプライベートネットワーク内のArtifactoryの中に構築してあるPyPIのレジストリへ、後者はそこへアクセスできない人へ。
検索してみるとsetup.pyを使用した配布が多い。とりあえず今回は巷にあるPythonのパッケージをExecutableなファイルにするツールは使わずこの正攻法を使用する。
そもそも開発環境ではpipenvを使用していて、依存性管理もそれで実施している。
が、pipenvでの実現方法が残念ながらストレートに理解できそうな方法では見当たらなかったので、Pipfileとsetup.pyで依存性をそれぞれ書きながらの対処となる。
まず、pipenv向けに作っていた修正前のsetup.py。
from setuptools import setup
setup()
これを例えば次のようにする。(値の一部はサニタイズのため適当)
from setuptools import setup, find_packages
setup(
name='mypycli',
version='1.0.0',
packages=find_packages(include=["config*", "src*"]),
scripts=["src/mypycli.py"],
entry_points={
"setuptools.installation": [
"eggsecutable = src.mypycli:main",
]
},
include_package_data=True,
description='',
install_requires=[
'tqdm',
],
url='https://github.com/x/x',
author='tkhm',
author_email='no-reply@example.com'
)
これを作成後、setup.pyを呼び出す。
pipenv環境では依存管理をしている環境に潜るために pipenv shellを使うので pipenv shell実施後に次のようにすれば、distディレクトリ以下にtar.gzのファイルとzipのファイルが出来上がる。
python setup.py sdist --formats="gztar,zip"
ちなみに、install_requiresは手書きでPipfileの[packages]から写した。この方法は、誰もが思うだろうけど、あまりスマートではないのでできることならpipenvらしいやり方を知りたいところだけど、今時点ではクリアではない。
次の内容は読んで参考にした。
今回自分はこの圧縮ファイルを直接PyPIに置いてアップロードしたけど、ガイドにある通り、次のようなコマンドでもいけそう。(というかコマンドであげる方が多分一般的)
python3 -m pip install --user --upgrade twine
python3 -m twine upload --repository testpypi dist/*
出典:https://packaging.python.org/tutorials/packaging-projects/#uploading-the-distribution-archives より抜粋
インストールについては、pipの方は単純だった。例えばこんな感じ。(リポジトリのアドレスはダミー)
python3 -m pip install https://private.artifactory.example.com/pypi/myuser/myrepo/1.0.0/mypycli-1.0.0.tar.gz
ただ、これでインストールしたらentry_pointsに指定した mypycli.py が実行コマンドとしてパスが通ったので、もう少し洗練させないといけないと思ったが、まだわかっていない。
また、圧縮ファイルの方は、展開後に次のコマンドでインストールできた。
# インストール
python3 setup.py build
python3 setup.py install
# 実行
python3 build/scripts-3.7/mypycli.py
基本的にこれでうまくいったのだけど、ユーザーからはsetup.pyにzip_safe=Falseを入れないとエラーでsetupうまくいかなかったとの報告も受けたが、チーム内では再現しないのでこれも継続調査。
Pythonの配布はまだまだ知らないことが多くて難しい......。