Poetryでプライベートリポジトリからインストールする3つの方法

Poetryでプライベートリポジトリからパッケージをインストールする必要がありいろいろ調べてみたのでそのメモ。あとAWS CodeArtifactも試してみたので。

はじめに

まず、pippoetryも基本的には依存関係の解決、つまりパッケージのインストールにはPyPIというリポジトリを参照しているのはご存知だと思うが、したがって通常自作のパッケージを公開するにはこのPyPIへの公開が必要となる。

PyPIで公開するにはPoetryではpoetry buildで配布用パッケージを作成してpoetry publishで可能。

だが、何らかの理由でパブリックには公開したくない、でもいくつかのプロジェクトから利用したいって場合があると思います。

そんなときに一番簡単なのはインストールしたいプロジェクトのリポジトリに同梱してしまうことですが複数のプロジェクトから利用する場合はそれもどうかと思いますよね。

というわけで、選択肢としてはこのあたりがあるのかなーと。

  1. パッケージを作ってそれをローカルでインストール
  2. GitHubなどのリポジトリを直接参照
  3. プライベートリポジトリを用意する

それぞれ順に見ていきます。

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.gzpoetry-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サーバを用意することで作れる模様。

pypi.org

でも、自分でサーバをセットアップしたりするのは面倒なのでこれは使いません。

そこで、今回はAWS CodeArtifactを使ってプライベートリポジトリを用意するのを試してみます。AWS CodeArtifactというのはプライベートなリポジトリをセットアップ可能なマネージドサービスです。

今回使うPython以外にもJavaMavenやnpmやyarn向けのリポジトリも作れます。

早速作ります。AWSのマネージメントコンソールからやります。難しいところが何もないのでここからは手を抜いてスクショで。

f:id:Keisuke69:20210109235926p:plain

f:id:Keisuke69:20210110000034p:plain

f:id:Keisuke69:20210110001434p:plain

f:id:Keisuke69:20210110000058p:plain

f:id:Keisuke69:20210110001736p:plain

さて、リポジトリができたらこれをPoetryで使うようにセットアップしていきます。AWSのマネージメントコンソール上ではpip向けの設定方法が載っているのですがPoetry向けはマニュアルで設定します。

View connection instructionsのボタンを押すと以下のような画面が出てくるのでpipを選べば表示されます。

f:id:Keisuke69:20210110001759p:plain

まずは、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のリポジトリからのインストールはできても公開ができない模様。

github.com

というわけで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だけでなく関連ツールとの組み合わせについてもさらっと解説されているので。

ただし、タイトルにある『テスト駆動開発』については学べません。

テスト駆動Python

テスト駆動Python

  • 作者:Brian Okken
  • 発売日: 2018/08/29
  • メディア: 単行本(ソフトカバー)

テスト駆動開発』そのものを知るにはやはり大定番のこちらがいいかと。Kent Beck先生が書いてt-wadaこと和田卓人氏が翻訳したバイブルとも言える本。

第一部はJavaだけどxUnitについて説明している第二部はPythonだし、テスト駆動開発そのものがどういったものかを知りたいなら言語の違いは大きな問題ではない。

テスト駆動開発

テスト駆動開発

©Keisuke Nishitani, 2020   プライバシーポリシー