uv で Artifact Registry の Python パッケージをデプロイする
はじめに
Poetry v2 のバージョンアップ対応のタイミングで、いっそのこと uv に移行できないかとチーム内で議論となりました。
チームでは複数プロジェクトで利用する共通の自作 Python パッケージは Artifact Registry のプライベートリポジトリで管理しています。uv でも Artifact Registry の Python パッケージを管理できるかどうかを検証しました。
検証条件
uv のバージョンは 執筆時点で最新となる v0.5.18
です。
❯ uv --version
uv 0.5.18 (27d1bad55 2025-01-11)
Artifact Registry の Python パッケージをインストール
まずはドキュメント通りにやってみる
Artifact Registry で管理している Python パッケージを uv でインストールするには、以下の方法で実行します。
# Pre-install keyring and Artifact Registry plugin from the public PyPI
uv tool install keyring --with keyrings.google-artifactregistry-auth
# Enable keyring authentication
export UV_KEYRING_PROVIDER=subprocess
# Configure the index URL with the username
export UV_EXTRA_INDEX_URL=https://oauth2accesstoken@{region}-python.pkg.dev/{projectId}/{repositoryName}/simple
keyring プラグインは gcloud CLI を利用して短期アクセストークンを生成し、システムのキーリングに安全に保存します。トークンは有効期限が切れると自動的に更新されます。
あとは通常パッケージと同様にuv add
でインストールすることができます。
uv add {your_package_name}
インストールはできたのですが、この方法では毎回環境変数を設定する必要があり、ちょっと面倒です。
改良:pyproject.toml に設定を追加
環境変数(UV_KEYRING_PROVIDER
、UV_EXTRA_INDEX_URL
)で設定した内容を pyproject.toml に追加し、同様にuv add
でインストールすることができました。これなら Artifact Registry のアクセス権限とkeyrings.google-artifactregistry-auth
がインストールされていれば、どの環境でもインストールできるようになります。
[tool.uv]
keyring-provider = "subprocess"
[[tool.uv.index]]
name = "{your_package_name}"
url = "https://oauth2accesstoken@{region}-python.pkg.dev/{projectId}/{repositoryName}/simple"
Artifact Registry に Python パッケージをプッシュ
次に uv で管理されている Python パッケージを配布するために、Artifact Registry にプッシュする方法です。
我々はパッケージのビルド&プッシュは Cloud Build で行っています。ビルド構成ファイルは以下のようになります。
steps:
- name: python:3.11
script: |
curl -LsSf https://astral.sh/uv/install.sh | sh
export PATH="/builder/home/.local/bin:${PATH}"
uv build
id: Build demo-lib package
artifacts:
python_packages:
- repository: "https://${_LOCATION}-python.pkg.dev/${PROJECT_ID}/${_REPO}"
paths: ["dist/*"]
options:
# Enable provenance for regional builds
requestedVerifyOption: VERIFIED
これで問題ない!はずでしたが、プッシュ時に以下のエラーが発生しました。
downloading uv 0.5.18 x86_64-unknown-linux-gnu
no checksums to verify
installing to /builder/home/.local/bin
uv
uvx
everything's installed!
To add $HOME/.local/bin to your PATH, either restart your shell or run:
source $HOME/.local/bin/env (sh, bash, zsh)
source $HOME/.local/bin/env.fish (fish)
Building source distribution...
Building wheel from source distribution...
Successfully built dist/uv_demo-0.1.0.tar.gz
Successfully built dist/uv_demo-0.1.0-py3-none-any.whl
PUSH
Already have image (with digest): gcr.io/cloud-builders/twine
Uploading the following paths to https://asia-northeast1-python.pkg.dev/your-project/hoge-repo: [dist/*]
Uploading distributions to
https://asia-northeast1-python.pkg.dev/your-project/hoge-repo
ERROR InvalidDistribution: Metadata is missing required fields: Name,
Version.
Make sure the distribution includes the files where those fields are
specified, and is using a supported Metadata-Version: 1.0, 1.1, 1.2,
2.0, 2.1, 2.2, 2.3.
ERROR
ERROR: could not upload [dist/*] to https://asia-northeast1-python.pkg.dev/your-project/hoge-repo; err = step exited with non-zero status: 1
エラー内容を確認すると、ビルドした Python パッケージの 'Metadata-Version'が 2.4
であり、Python パッケージ公開ツールである twine の執筆時点の最新バージョンである6.0.1
ではサポートされていないことが原因のようです。
解決方法として、pyproject.toml に記述されていたビルドツールの hatch
のバージョンを 1.26.3
に固定することで、ビルドパッケージの'Metadata-Version'が 2.3
となり、この問題は解決しました。
[build-system]
requires = ["hatchling==1.26.3", "hatch-vcs"]
build-backend = "hatchling.build"
まとめ
uv でも poetry と同様に Artifact Registry で Python パッケージを管理できることを確認しました。リポジトリへのプッシュ時に予期せぬ問題が発生しましたが、これも twine のバージョンアップがあれば問題も解決していくと想定しています。
引き続き uv への移行にむけて検証を続けて行きたいと思います。
Discussion