Pythonのパッケージ管理といえばpipが一般的ですが、pipでインストールできるパッケージは PyPIで管理されています。 ここには誰でもパッケージを登録することができますが、実際にアップロードするには 色々と体裁を整える必要があります。 特にコマンドラインツールを作ろうと思うと一工夫必要です。
その点、Poetryを使うと設定項目を自分でほとんど書くことなくPyPI用 パッケージを作りアップロードすることができます。
Poetry
Poetry - Python dependency management and packaging made easy.
PoetryはPythonのプロジェクトの依存関係などを管理するためのツール。
PyPIなどにパッケージを登録する際にはsetup.pyとかrequirements.txtとか 色々と用意しないといけないものがあります。
それらを自分で用意するのはとても大変で、大概はどこかにある例をとりあえずコピーして、 みたいに始めると思いますがそれでも調整するのが大変だったりします。
Poetryではpyproject.tomlというファイルでパッケージ管理を行いますが、 まずディレクトリ構造を含め雛形を用意してくれて pyproject.tomlの雛形も用意されます。 また、依存関係のあるパッケージ等の追加がコマンドから自動でできる様になっていたりして ほとんど自分で設定ファイルを書くことなく進めていくことができます。
また、パッケージを管理するとともに、そこにvirtualenvの環境を自動で作ります。 これによりその場で依存関係のパッケージをインストールして 必要な環境下でのテストが可能になります。
インストール
スクリプトget-poetry.py
インストールはGitHubにあるスクリプトを使って
$ curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python
もしcurlで直接やるのが憚れる場合はスクリプトをダウンロードして ももちろんできます。
$ wget https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py
$ cat get-poetry.py
....
$ python get-poetry.py
この方法でインストールすると$HOMEディレクトリに~/.poetry/というディレクトリができ、 ~/.poetry/bin/poetryという実行ファイルがインストールされます。
また、UNIX系の場合には
export PATH="$HOME/.poetry/bin:$PATH"
という行が自動で~/.bash_profileまたは~/.profileなどに追加される様になっています。
これに関して、最初に
Before we start, please answer the following questions.
You may simply press the Enter key to leave unchanged.
Modify PATH variable? ([y]/n)
と聞かれるのですが、ここでn
またはno
とか入れても
メッセージが変わるだけで(PATHに入れてください、というのが出るようになる)
~/.bash_profile等への書き込みは行われてしまいます。
バグですが、簡単に治るところだと思ってPull Requestしようとしたら すでにありました。
IssuesもPull Requestsも大量に貯まっていてさばききれてない感が。。。
ともあれ、.bash_profileとかに余計なものを入れたくない人はちょっと注意が必要です。
自分の環境では.bash_profileに追加されたものを消して
if [ -f $HOME/.poetry/env ];then
source $HOME/.poetry/env
fi
といった行を.bashrcに書いています。
アンインストールする場合には
$ wget https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py
とかでget-poetry.py
を取ってきて
$ python get-poetry.py --uninstall
とします。これをすると~/.poetryを削除し、~/.bash_profileなどにpoetryのexport行があると それを削除します。
これも勝手に.bash_profileをいじるのでちょっと注意が必要です。
pip
pip
を使ってもインストールできます。
$ pip install poetry
またはユーザーレベルで
$ pip install --user poetry
後者の場合は~/Library/Python/2.7/bin(Mac)や~/.local/binなどに インストールsれるのでそれらをPATHに入れておく必要があります。
ただし、これで入れるとpipでpoetryが依存するパッケージを入れることになり それが余計なことをする可能性があるのでスクリプトでインストールする方がおすすめされています。
こちらのアンインストールは
$ pip uninstall poetry
補完
poetry
コマンドではサブコマンドを与えていろいろと実行しますが、それを補完するためのファイルの内容を
poetry completion
で吐き出すことが出来ます。
$ poetry completion bash # for bash
$ poetry completion zsh # for zsh
$ poetry completion fish # for fish
これをシステムにそのまま入れたい場合には
$ poetry completions bash > /etc/bash_completion.d/poetry.bash-completion (Linux)
$ poetry completions bash > $(brew --prefix)/etc/bash_completion.d/poetry.bash-completion (Mac)
$ poetry completions fish > ~/.config/fish/completions/poetry.fish
$ poetry completions zsh > ~/.zfunc/_poetry
とかしてシステムの補完ファイルディレクトリに入れれれば良いですが、 自分用に
$ poetry completions bash >> ~/.bashrc
とかでも大丈夫です。(ただし結構長いので別ファイルにしたほうが良いかも。)
使い方
雛形作成
poetry new <package>
で新たにパッケージの雛形を作れます。
$ poetry new --src rcmdnk-package
Created package rcmdnk-package in rcmdnk-package
$ ls
rcmdnk-package
$ cd rcmdnk-package/
$ tree
|-- README.rst
|-- pyproject.toml
|-- src
| |-- rcmdnk_package
| | |-- __init__.py
|-- tests
| |-- __init__.py
| |-- test_rcmdnk_package.py
$ cat pyproject.toml
[tool.poetry]
name = "rcmdnk-package"
version = "0.1.0"
description = ""
authors = ["rcmdnk <[email protected]>"]
[tool.poetry.dependencies]
python = "^2.7"
[tool.poetry.dev-dependencies]
pytest = "^3.0"
[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"
ここで--src
オプションはパッケージ直下にrcmdnk_packageディレクトリを置かず
srcを挟んで置くようにするためのオプション。
これがないとrcmdnk-package/rcmdnk_package/__init__.pyのような構造になります。
pytestなどを使う際などにこのsrcが入った構造が勧められていて 特に理由がない限り*src**入にしておいたほうが良いです。
pyproject.tomlの中にあるメールアドレス等はデフォルトでは~/.gitconfigのユーザー名、メールアドレスを取ってきているようで それがなければ[“Your Name [email protected]”]みたいになります。
このパッケージでは__init__.pyに
__version__ = '0.1.0'
というバージョン情報が入っていて、testの中では
1 2 3 4 5 |
|
というpytest用のテストが用意されています。
install
雛形を作ったら、まず
$ poetry install
Creating virtualenv test-py2.7 in .../Library/Caches/pypoetry/virtualenvs
Updating dependencies
Resolving dependencies... (0.2s)
...
を実行してみます。 これでこのディレクトリ用のvirtualenv環境が作られ、 poetryを動かす上で最低限必要なパッケージ(pytestなど)がインストールされます。
pytest
テストは
$ poetry run pytest
で実行することが出来ます。これでtestsフォルダにある全てのtest_*.pyファイルの中身を実行します。
特定のファイルだけ実行したい場合には
$ poetry run pytest ./tests/test_rcmdnk_package.py
依存パッケージの追加/削除
依存パッケージを追加したい場合には
$ poetry add fire
の様にします。 これでvirtualenvの環境にパッケージが追加され、 また以下のように
[tool.poetry.dependencies]
python = "^2.7"
fire = "^0.1.3"
pyproject.tomlの
dependencies
のセクションに追加されます。
このpyproject.tomlがあれば、別の環境でpoetry install
をした時に
ここにあるパッケージも同時にインストールされます。(python
以外)
逆にここにパッケージを自分で書いてからpoetry install
をしても
同じ状態になります。
逆に削除したい場合は
$ poetry remove fire
で出来ます。
現在インストールされているパッケージについては
$ poetry show
で見ることが出来ます。
コマンドラインツール(CLI)の作成
次の様なファイルを作ります。
1 2 3 4 5 6 |
|
これを直接呼ぶにはpoetry run
を使って
$ poetry run python src/rcmdnk_package/cli.py
rcmdnk package test
といった感じに呼べます。
これがパッケージとしてインストールされたとき、rcmdnk_cli
という名前で呼ばれるようにするには
pyproject.tomlに
[tool.poetry.scripts]
rcmdnk_cli = "rcmdnk_package.cli:main"
という行を追加します。
これで
$ poetry run rcmdnk_cli
rcmdnk package test
と同じ様にrcmdnk_cli
だけで呼べる様になります。
poetry shell
poetry shel
とするとvirtualenv環境に入って直接コマンドを使ったり出来るようになります。
$ poetry install # rcmdnk_cliなどもちゃんとインストールしておく
...
$ poetry shell
Virtual environment already activated: /Users/user/Library/Caches/pypoetry/virtualenvs/rcmdnk-package-py2.7
$ rcmdnk_cli
rcmdnk package test
パッケージのビルド
PyPIなどに登録するにはこの他色々と設定ファイルが必要ですが、 これは
$ poetry build
で作成することが出来ます。
これでdist/rcmdnk-package-0.1.0.tar.gz、dist/rcmdnk_package-0.1.0-py2.py3-none-any.whlというファイルが作成されます。 rcmdnk-package-0.1.0.tar.gzを展開して中身を見てみるとPKG-INFO、setup.pyができてるのが分かります。
パッケージの登録
TestPyPIへの登録
これですでにパッケージを登録する準備が出来ましたが、 TestPyPI1というテスト用のレポジトリがあるので まずはそちらに上げてテストしてみます。
まずはTestPyPIのページにあるRegisterリンクからアカウント登録を行っておきます。
次に、poetryにレポジトリ情報を渡します。
$ poetry config repositories.testpypi https://test.pypi.org/legacy/
これでtestpypi
という名前で登録が出来ました。
登録はpoetry publish -r testpypi
で行います。
$ poetry publish -r testpypi
Publishing rcmdnk-package (0.1.0) to testpypi
Username: rcmdnk
Password:
- Uploading rcmdnk-package-0.1.0.tar.gz 100%
- Uploading rcmdnk_package-0.1.0-py2.py3-none-any.whl 100%
UsernameとPasswordを入力して rcmdnk-package · TestPyPI にアップロードできました。
これをインストールするには
$ pip install --index-url https://test.pypi.org/simple/ rcmdnk-package
の様に--index-url
でhttps://test.pypi.org/simple/
を指定します。
(最後のところが登録の部分ではlegacy
なのに対してこちらではsimple
なことに注意)。
この登録のところで
$ poetry config http-basic.testpypi <username> <password>
と事前にユーザー名とパスワードを登録しておくと毎回それらを打たずに済みますが、 これらのファイルは平文で保存されるので人が見る可能性のあるシステムではできれば避けた方が良いです。
また、
$ poetry publish -r testpypi --username <username> --password <password>
とpublish
コマンドに引数として渡すことも出来ます。
PyPIへの登録
PyPIのレポジトリはデフォルトとして登録されているので PyPIの方でアカウントを登録し(TestPyPIとは別)、
$ poetry publish
とすればPyPIの方へアップロードされます。
ビルドと登録を同時に行う
$ poetry publish --build
の様に--build
オプションを使うことでアップロード時にbuildを同時に行うことも出来ます。
設定ファイル
poetry config
で加えた設定は以下のディレクトリに保存されています。
- Linux: ~/.config/pypoetry
- macOS: ~/Library/Application Support/pypoetry
- Windows: C:\Users<username>\AppData\Roaming\pypoetry
repositories
などの情報はconfig.toml、http-basic
の情報はauth.toml
に保存されています。
config.tomlの情報はpoetry config --list
でも見ることが出来ます。
(加えていくつかデフォルトの設定値も表示されます。)
設定を削除するにはこれらのファイルを削除するか
$ poetry config --unset http-basic.testpypi
の様に--unset
を使います。
pipでインストールされたCLIパッケージ
Macで
$ pip install --user --index-url https://test.pypi.org/simple/ rcmdnk-package
しました。
--user
を使うと、Macでは**~/Library/Python/
$ ls ~/Library/Python/2.7/bin/rcmdnk_cli
/Users/user/Library/Python/2.7/bin/rcmdnk_cli
$ ls ~/Library/Python/2.7/lib/python/site-packages/rcmdnk_package
__init__.py __init__.pyc cli.py cli.pyc
$
このrcmdnk_cli
は自動でできたファイルですが、こんな内容
1 2 3 4 5 6 7 8 9 10 11 |
|
設定ファイル: pyproject.toml
直接書く必要があるものとしては 最初の
[tool.poetry]
name = "rcmdnk-package"
version = "0.1.0"
description = ""
authors = ["rcmdnk <[email protected]>"]
の項目にあるdescription
位。
GitHubのユーザー名とかから保管されていなければ(もしくは違うものを使いたければ)authors
も。
加えて
repository = "http://github.com/rcmdnk/rcmdnk_package"
homepage = "http://github.com/rcmdnk/rcmdnk_package"
readme = "READDME.md"
license = "Apache-2.0"
keywords = [...]
などを定義しておくと良いです。
readme
はデフォルトではREADME.rst
でSphinx使うreStructuredText形式です。
変更したければreadme
の設定でmd
にしても変換して
PyPIのページで表示してくれます。
license
はSPDX License List
にあるIdentifierを指定するとパッケージに自動で含めてくれます。
後はversion
を必要に応じて更新していきます。
(その際、src/rcmdnk_package/__init__.pyやtests/test_rcmdnk_package.pyなどにある
バージョンの更新も忘れずに。)
それから自動で作るとpoetry new
したときのPythonのバージョンのみに対応になりますが、変更したければ
[tool.poetry.dependencies]
python = "^2.7 || ^3.4"
の様に3系なども加えたりしておきます。
Dependency specification Documentation Poetry - Python dependency management and packaging made easy
エラー対処
No JSON object could be decoded
Macで使ってる時に
$ poetry build
[ValueError]
No JSON object could be decoded
build [-f|--format FORMAT]
というのが出る様になりました。run
やshell
などどのコマンドでも同じエラーが出ます。
唯一config
だけが動いてる状態。
どうもconfig
だけが動いている、ということからもvirtualenv環境がおかしくなってしまったようで、
$ rm -rf /Users/user/Library/Caches/pypoetry/
としたら治りました(run
コマンドなどを打つとvirtualenv環境を作り直していた)。