2025/2/2 uv + Artifact Registry で publish & install
from 2025/2/1 uv workspace 使う
まとめると
Artifact Registry への publish
$ uv build で dist/ 下に package 作る
monorepo なら uv build --all で workspace メンバを一通りビルド
手元 → Artifact Registry
gcloud の認証情報使う
code:pyproject.toml
tool.uv.index
name = 'artifactregistry'
url = "https://oauth2accesstoken@{region}-python.pkg.dev/{project}/{repository}/simple"
publish-url = "https://{region}-python.pkg.dev/{project}/{repository}/"
$ uv publish --index=artifactregistry --username=oauth2accesstoken --password=$(gcloud auth print-access-token)
これが 2025/2 現在のところ楽だと思う、uv からできる & twine や ~/.pypirc 要らない
Cloud Build でビルド → Artifact Registry への publish
Cloud Build の機能 artifacts.pythonPackages を使う
Build configuration file schema  |  Cloud Build Documentation  |  Google Cloud
paths: ["dist/*"] でいい
Artifact Registry からの install (使う側)
gcloud & ADC の設定 ($ gcloud auth application-default login)
$ uv tool install keyring --with keyrings.google-artifactregistry-auth
$ uv tool run keyring --list-backends で GooglePythonAuth と ChainerBackend 含むのを確認
code:pyproject.toml
project
...
dependencies = "poku-mod-a>=0.1.0", "poku-mod-b>=0.1.0" # private な package への依存
tool.uv
keyring-provider = "subprocess" # UV_KEYRING_PROVIDER 環境変数でなくこっちに書ける
tool.uv.sources
poku-mod-a = { index = "artifactregistry" } # モジュール単位で artifactregistry を index に指定
poku-mod-b = { index = "artifactregistry" }
tool.uv.index
name = 'artifactregistry' # 名前は被らん程度に何でもよい
url = "https://oauth2accesstoken@{region}-python.pkg.dev/{project}/{repository}/simple"
この状態で uv sync すればよい
? このとき uv の tool の keyring 見てる?
見てないなら $ uv tool dir --bin にパス通す、keyring あるかは $ uv sync -v のログ見ればわかる
コンテナ内からは keyring の PATH の追加 と ADC の解決 が居る
ENV PATH=/root/.local/bin:$PATH で通す
https://docs.astral.sh/uv/guides/integration/docker/#using-installed-tools
ローカルなら ADC を secret としてマウントして依存解決時だけ GOOGLE_APPLICATION_CREDENTIALS に設定
RUN --mount=type=secret,id=adc,target=/adc.json GOOGLE_APPLICATION_CREDENTIALS=/adc.json uv sync --frozen
Cloud Build なら docker build --network=cloudbuild で metadata server 見える状態にして ADC 解決
? 同じ Dockerfile の記述でいい感じにできないか?
気になる
その他 Google Cloud 環境なら metadata server 見えるはず
pip で使う
ADC ある上で
$ pip install keyring keyrings.google-artifactregistry-auth
pip install --extra-index-url=https://{region}-python.pkg.dev/{project}/{repository}/simple/ PACKAGE
引数のパターン
--extra-index-url={privateregistry}
PyPI → private の順に探す、大抵良いが、package 名がかぶるとバージョンが大きい方が使われる
--index-url={privateregistry}
private からしか探さない、private package が公開の package に依存していても入らない
--index-url={privateregistry} --no-deps
private からだけ入れて依存は無視する、2回に分けるならよい
--index-url={private_registry_url} --extra-index-url=https://pypi.org/simple/
private → PyPI の順に探しそうに見えて、バージョンが高いものが優先されて最初のと同じ
---.icon
Publishing a package | uv
Using alternative package indexes | uv
Artifact Registry の Python リポジトリ作っておく
$ uv tool install keyring
$ uv tool install keyrings.google-artifactregistry-auth
Python パッケージ リポジトリの Artifact Registry に対する認証を構成する  |  Artifact Registry documentation  |  Google Cloud
$ uv tool run keyring --list-backends
だと見つからない
s $ uv tool install keyring --with keyrings.google-artifactregistry-auth
$ uv tool run keyring --list-backends
だとみつかる
これでだめか
code:index
tool.uv.index
name = 'artifactregistry'
# url = "https://asia-northeast1-python.pkg.dev/pokutuna-playground/py/simple/"
url = "https://oauth2accesstoken@asia-northeast1-python.pkg.dev/pokutuna-playground/py/simple"
publish-url = "https://asia-northeast1-python.pkg.dev/pokutuna-playground/py/"
$ uv publish --keyring-provider=subprocess --username=__token__ --index=artifactregistry
アップロード自体は試みてるけど 401 返ってる
pypirc 必須?
Allow --token to be empty if --keyring-provider is set with uv publish · Issue 9227 · astral-sh/uv
twine 直接実行するとして ~/.pypirc 置きたくねーな...
$ uv tool run twine upload --repository-url='https://asia-northeast1-python.pkg.dev/pokutuna-playground/py/' 'dist/*'
ではユーザ名パスワード聞かれる
$ TWINE_USERNAME=oauth2accesstoken TWINE_PASSWORD=$(gcloud auth print-access-token) uv tool run twine upload --repository-url=... dist/*.whl
これでうまくいく
パスワード認証ではあるが gcloud からトークン取ってるので良いんじゃないか
keyring も結局 ADC 解決するわけだし...
Google Cloud 下では metadata server から引けばいいだろう
いや、じゃあこれでいいんじゃない?
s $ uv publish --index=artifactregistry --username=oauth2accesstoken --password=$(gcloud auth print-access-token)
うまくいく
当然同じバージョンのは publish できないが
Cloud Build からは
pythonPackages - Build configuration file schema  |  Cloud Build Documentation  |  Google Cloud
これ使うのがいいだろう
これを利用する側は
uv で Artifact Registry の Python パッケージをデプロイする に倣って
$ uv tool install keyring --with keyrings.google-artifactregistry-auth
code:pyproject.toml
project
...
dependencies = "poku-mod-a>=0.1.0", "poku-mod-b>=0.1.0"
tool.uv
keyring-provider = "subprocess"
tool.uv.sources
poku-mod-a = { index = "artifactregistry" }
poku-mod-b = { index = "artifactregistry" }
tool.uv.index
name = 'artifactregistry'
url = "https://oauth2accesstoken@asia-northeast1-python.pkg.dev/pokutuna-playground/py/simple"
手元ではすんなり
しかし CI でインストールするのはどうかな?
手元のコンテナビルド
keyring-provider = "subprocess" かつ uv tool install keyring したとて keyring が使われていないような
uv sync -v --fronzen でログ見ると
0.870 WARN Failure running keyring command: No such file or directory (os error 2)
keyring コマンド見えてない
uv tool dir のパスへパス通すとうまくいく
Using installed tools - Using uv in Docker | uv
ENV PATH=/root/.local/bin:$PATH
まあ他で使わないなら inline でもいいけど、通しておいたほうがハマりにくそうかな?
stage 分けても良い
code:Dockerfile
WORKDIR /app
COPY pyproject.toml uv.lock hello.py /app/
RUN uv tool install keyring --with keyrings.google-artifactregistry-auth
RUN --mount=type=secret,id=adc,target=/adc.json \
PATH=$(uv tool dir --bin):$PATH GOOGLE_APPLICATION_CREDENTIALS=/adc.json uv sync --frozen
$ docker build --secret id=adc,src=/Users/pokutuna/.config/gcloud/application_default_credentials.json .
Artifact Registry
特に気にせず metadata server から解決できるかな?
ここで止まる
Checking keyring for credentials for oauth2accesstoken@https://asia-northeast1-python.pkg.dev/pokutuna-playground/...
artifact-registry-python-tools/keyrings/gauth.py at main · GoogleCloudPlatform/artifact-registry-python-tools
うーん metadata server から読んでくれそうだが
止まるの謎だなあ、refresh が timeout しているような雰囲気...
keyring は見に行ってるしねえ
Cloud Build デフォルトサービスアカウントが Artifact Registry の read ついてるのは見た
Cloud Build ネットワーク - ビルド構成ファイルのスキーマ  |  Cloud Build Documentation  |  Google Cloud
--network=cloudbuild これだ!! 知らなかった、まだ知らないことあるなあ
うまくいった
シンプルに落ち着いたね、使う気分になる
code:Dockerfile
FROM python:3.12.8-slim-bookworm
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
COPY pyproject.toml uv.lock /app/
COPY src/ /app/src/
COPY packages/ /app/packages/
WORKDIR /app
RUN uv sync --frozen
code:cloudbuild.yaml
steps:
- name: gcr.io/cloud-builders/docker
args:
- build
- --network=cloudbuild
- --tag=asia-northeast1-docker.pkg.dev/$PROJECT_ID/d/uvwithartifactregistry:latest
- .
- name: gcr.io/cloud-builders/docker
args:
- push
- --all-tags
- asia-northeast1-docker.pkg.dev/$PROJECT_ID/d/uvwithartifactregistry
#Python #Artifact_Registry