Poetryでプライベートリポジトリからパッケージをインストールする必要がありいろいろ調べてみたのでそのメモ。あとAWS CodeArtifactも試してみたので。
はじめに
まず、pip
もpoetry
も基本的には依存関係の解決、つまりパッケージのインストールにはPyPIというリポジトリを参照しているのはご存知だと思うが、したがって通常自作のパッケージを公開するにはこのPyPIへの公開が必要となる。
PyPIで公開するにはPoetryではpoetry build
で配布用パッケージを作成してpoetry publish
で可能。
だが、何らかの理由でパブリックには公開したくない、でもいくつかのプロジェクトから利用したいって場合があると思います。
そんなときに一番簡単なのはインストールしたいプロジェクトのリポジトリに同梱してしまうことですが複数のプロジェクトから利用する場合はそれもどうかと思いますよね。
というわけで、選択肢としてはこのあたりがあるのかなーと。
それぞれ順に見ていきます。
1. パッケージを作ってそれをローカルでインストール
poetry build
した結果を手元の開発端末とかデプロイ先にコピーなりで持っていってインストールする感じですね。poetry build
を実行するとdist
ディレクトリが作成されてパッケージができあがります。例えばこんなpyproject.toml
を用意します。サンプル用のリポジトリはこちらに。なぜリポジトリ名がpoetry-with-codeartifact
なのは最後まで読んでいただければ…。
[tool.poetry] name = "poetry-with-codeartifact" version = "0.1.0" description = "" authors = [] [tool.poetry.dependencies] python = "^3.9" [tool.poetry.dev-dependencies] [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api"
コマンドを実行するとプロジェクトのdist
以下にpoetry-with-codeartifact-0.1.0.tar.gz
とpoetry-with-codeartifact-0.1.0-py3-none-any.whl
が出来上がるのでどちらかを指定してpip install
できます。なので各プロジェクトにこのtar.gzかwhlのファイルをコピーしてはインストールするという感じですね。
poetryでやる場合はpoetry add ./poetry-with-codeartifact-0.1.0-py3-none-any.whl
みたいな感じです。なお、poetryの場合プロジェクトフォルダとパッケージ名が同じだとエラーになる模様で少しハマった。このブログ試すために作ったプロジェクトでpoetry build
してpoetry add
していたので。
このときのpyproject.toml
はこんな感じです。
[tool.poetry.dependencies] python = "^3.9" poetry_demo = {path = "./poetry-with-codeartifact-0.1.0-py3-none-any.whl", develop = false}
とりあえず愚直にやる手段としてはいいかもしれないがスマートではない感じがする。更新する場合、ライブラリをgit clone
して、poetry build
して、ファイルをコピーしてpoetry install
って手順も多いし。なんかいまいち。
2. GitHubなどのリポジトリを直接参照
というわけで次がGithubとかのリポジトリを直接参照するパターン。
さっきのリポジトリをこんな感じで指定してpoetry add
すると勝手にcloneしてbuildしてinstallしてくれます。
$ poetry add git+https://github.com/Keisuke69/poetry-with-codeartifact#master
pyprojct.toml
に追加されたエントリはこんな感じ。
[tool.poetry.dependencies] python = "^3.9" poetry-demo = {git = "https://github.com/Keisuke69/poetry-with-codeartifact", rev = "master"}
というわけでさっきよりはだいぶいいと思う。というか基本的にこれで十分かと。
3. プライベートリポジトリを用意する
最後はプライベートリポジトリを作るパターン。プライベートリポジトリを作ってPoetryで指定をすると使えます。プライベートリポジトリはpypiserver
をインストールしたLinuxサーバを用意することで作れる模様。
でも、自分でサーバをセットアップしたりするのは面倒なのでこれは使いません。
そこで、今回はAWS CodeArtifactを使ってプライベートリポジトリを用意するのを試してみます。AWS CodeArtifactというのはプライベートなリポジトリをセットアップ可能なマネージドサービスです。
今回使うPython以外にもJavaのMavenやnpmやyarn向けのリポジトリも作れます。
早速作ります。AWSのマネージメントコンソールからやります。難しいところが何もないのでここからは手を抜いてスクショで。
さて、リポジトリができたらこれをPoetryで使うようにセットアップしていきます。AWSのマネージメントコンソール上ではpip向けの設定方法が載っているのですがPoetry向けはマニュアルで設定します。
View connection instructions
のボタンを押すと以下のような画面が出てくるのでpipを選べば表示されます。
まずは、AWS CLIが必要ってことなので入ってないならインストールします。AWS系はこのあたりが便利なような手間なようなって感じですね。普段使ってれば手元の環境に既に入ってることも多いんでしょうけど、自分の場合は基本的にRemote Containersを使って開発してるのでプロジェクトごとに毎回入れる必要があってちょっと面倒。そろそろDockerfileに書いておいてもいいかもしれない…。
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" unzip awscliv2.zip sudo ./aws/install
ちなみにクレデンシャルもセットアップしておく必要があります。これはaws configure
を実行したらAccess KeyとかSecret Access Keyを聞かれるので自分のものを入力しておきます。あ、Default regionはap-northeast-1
を指定しておきました。
AWS CLIを使ってauthorization tokenを取得します。
export CODEARTIFACT_AUTH_TOKEN=`aws codeartifact get-authorization-token --domain python-repo --domain-owner <自分のアカウントID> --query authorizationToken --output text`
そしてPoetryにプライベートリポジトリを設定します。ここがなかなかすんなりいかなかったのですが試行錯誤の結果こんな感じで動くようになりました。
リポジトリのURLはCodeArtifactで作ったものです。URL自体はview connection instructions
で案内されてるコマンド内にあります。
poetry config repositories.private https://<リポジトリ名>-<アカウントID>.d.codeartifact.<リージョン>.amazonaws.com/pypi/<リポジトリ名>/simple/ poetry config http-basic.private aws $CODEARTIFACT_AUTH_TOKEN
URLの<リポジトリ名>-<アカウントID>
のリポジトリ名
とアカウントID
の間の-
を忘れないようにしてください。あと、上記でrepositories.private
としていますがprivate
の部分は何でも構いません。なんでも構わないのですがそのあとのコマンドと揃えてください。
そしてpyproject.toml
に以下を追記。
[[tool.poetry.source]] name = "private" url = "https://<リポジトリ名>-<アカウントID>.d.codeartifact.<リージョン>.amazonaws.com/pypi/<リポジトリ名>/simple/" secondary = true
なお、自前で用意したプライベートリポジトリを使う場合はURLを自分で用意したURLにするといいでしょう。
これでひとまずプライベートリポジトリからのインストールはできるようになります。
ところが、インストールするためにまずは公開と思いきやうまくいきません。poetry publish -r private
を実行してもUpload Errorになります。
いろいろ調べたところ現在のPoetryではCodeArtifactのリポジトリからのインストールはできても公開ができない模様。
というわけで2021年1月10日時点では公開は以下のようにtwine
を使ってやるしかない模様です。
aws codeartifact login --tool twine --repository <リポジトリ名> --domain <リポジトリ名> --domain-owner <アカウントID> twine upload --repository codeartifact ./dist/poetry-demo-0.1.0.tar.gz
twine upload
で指定している--repository
はなぜかcodeartifact
を指定しないと動かない。きっと手前のlogin処理で生成された.pypirc
の中身の兼ね合いとかなんだろうけど深くは追ってないです。
とりあえず、ここまで来たらこのプライベートリポジトリを使ってpoetryで自分のパッケージをインストールすることが可能になってるはずなので普通にpoetry add <自分のパッケージ>
をすればいい。
これでCodeArtifactを使ったプライベートリポジトリからのインストールができるようになったわけですが、pipで使うならともかくPoetryで使うには正直ちょっと面倒だな。
あと、CodeArtifactは当然有料です。安いですが有料ではあります。登録している容量とリクエスト量、転送量でかかる。
結論
以上、3パターンを試したけどセットアップの手間などを考えると今回はパターン2のGitHubリポジトリを直接参照の一択かな。GitHubのリポジトリをプライベートにしておけばいい。
余談
最後に余談ですが最近オススメされたのでこの本買いました。ざっと読んだ感じ、pytestを使ったテストの実装方法について網羅的に書かれていて復習に良かったです。pytestだけでなく関連ツールとの組み合わせについてもさらっと解説されているので。
ただし、タイトルにある『テスト駆動開発』については学べません。
- 作者:Brian Okken
- 発売日: 2018/08/29
- メディア: 単行本(ソフトカバー)
『テスト駆動開発』そのものを知るにはやはり大定番のこちらがいいかと。Kent Beck先生が書いてt-wadaこと和田卓人氏が翻訳したバイブルとも言える本。
第一部はJavaだけどxUnitについて説明している第二部はPythonだし、テスト駆動開発そのものがどういったものかを知りたいなら言語の違いは大きな問題ではない。