🤼‍♀️

Cloud Functions から別プロジェクトの Artifact Registry にあるpythonパッケージを使用する

2024/02/11に公開

概要

Cloud Functions(python) から別プロジェクトの Artifact Registry に格納されている python パッケージをインストールする手順を記載します。

対象読者

  • Google Cloud のサービスをコンソールまたはCLIで構築した経験のある方
  • Python の開発環境を構築した経験のある方

環境

ローカル端末

  • OS: macOS Sonoma 14.1
  • チップ: Apple M3 Max
  • Google Cloud SDK: 463.0.0
  • Pythonパッケージ
    • pip: 24.0
    • setuptools: 69.0.3
    • wheel: 0.42.0
    • twine: 4.0.2
    • keyring: 24.3.0
    • keyrings.google-artifactregistry-auth: 1.1.2

Artifact Registry

  • プロジェクトID: {myname}-sandbox-a(以降プロジェクトAと呼称)
  • リポジトリ形式: Python
  • モード: 標準
  • ロケーションタイプ: us-central1

Cloud Functions

  • プロジェクトID: {myname}-sandbox-b(以降プロジェクトBと呼称)
  • 環境: 第2世代
  • コードのランタイム: Python 3.11
  • リージョン: us-central1

手順

大筋は公式のクイックスタートに沿って進めます。
https://cloud.google.com/artifact-registry/docs/python/store-python

Artifact Registry

プロジェクトAの Artifact Registry に python 用リポジトリを作成します。

1. リポジトリ作成

ローカル端末のターミナル(iTerm2)から実行しています。

  1. Python用リポジトリの作成
gcloud artifacts repositories create quickstart-python-repo \
--repository-format=python \
--location=us-central1 \
--description="Python package repository"
  1. gcloud configにリポジトリを設定
gcloud config set artifacts/repository quickstart-python-repo
gcloud config set artifacts/location us-central1
  1. gcloud configを確認
gcloud config list

$ gcloud config list
[artifacts]
location = us-central1
repository = quickstart-python-repo

Google Cloud コンソール上からもリポジトリの作成を確認できました。
(左メニューの Artifact Registry > リポジトリ)

2. pythonパッケージをリポジトリにアップロード

リポジトリにプッシュする資材を用意します。output_logは渡された文字列を Cloud Logging に出力するだけのコードです。

  • python-quickstart
    • output_log
      • __init__.py
    • requirements.txt
    • setup.py
output_log/__init__.py
import logging

import google.cloud.logging


class SampleClass:
    def __init__(self):
        self._setup_logging()

    @staticmethod
    def _setup_logging():
        logging.basicConfig(
            format="[%(asctime)s][%(levelname)s] %(message)s",
            level=logging.DEBUG
        )
        logger = logging.getLogger()
        logging_client = google.cloud.logging.Client()
        logging_client.setup_logging()
        logger.setLevel(logging.DEBUG)

    def run(self, message):
        logging.info(message)
requirements.txt
google-api-python-client==2.111.0
google-cloud-logging==3.9.0
setup.py
from setuptools import setup, find_packages

setup(
    name='python_quickstart',
    version="1.0.0",
    packages=find_packages(),
    install_requires=open('requirements.txt').read().splitlines()
)
  1. pythonコードをパッケージング
python setup.py sdist bdist_wheel
# distディレクトリと配下に下記2ファイルが作成されます。
# - python_quickstart-1.0.0.tar.gz
# - python_quickstart-1.0.0-py3-none-any.whl
  1. 認証情報ファイルを作成
# .pypirc
gcloud artifacts print-settings python > ~/.pypirc
# pip.conf
mkdir -p ~/.config/pip/
cp ~/.pypirc ~/.config/pip/pip.conf

.pypircとpip.confの中身

# Insert the following snippet into your .pypirc

[distutils]
index-servers =
quickstart-python-repo

[quickstart-python-repo]
repository: https://us-central1-python.pkg.dev/{project_id}/quickstart-python-repo/

  1. リポジトリにアップロード
twine upload --repository quickstart-python-repo  dist/* --verbose
  1. アップロードしたpythonパッケージを確認
gcloud artifacts files list --repository quickstart-python-repo
gcloud artifacts versions list --package=python-quickstart

Google Cloud コンソール上からもアップロードしたpythonパッケージを確認できました。
(左メニューの Artifact Registry > リポジトリ > quickstart-python-repo)

ローカル端末にインストールできることを確認します。

pip install --extra-index-url https://us-central1-python.pkg.dev/{project_id}/quickstart-python-repo/simple/ python-quickstart
pip show python-quickstart

$ pip show python-quickstart
Name: python_quickstart
Version: 1.0.0
Summary:
Home-page:
Author:
Author-email:
License:
Location: /Users/{user_name}/python_quickstart/.venv/lib/python3.11/site-packages
Requires: google-api-python-client, google-cloud-logging
Required-by:

Cloud Functions

プロジェクトBの Cloud Functions に python 関数を作成します。

1. 関数作成

Google Cloud コンソール上から実行しています。
(左メニューの Cloud Functions > ファンクションの作成)

  1. 構成を入力
  • 環境: 第 2 世代
  • 関数名: function-python-quickstart
  • リージョン: us-central1
  • トリガーのタイプ: HTTPS
    ※ランタイム、ビルド、接続、セキュリティの設定 はデフォルトのまま
  1. コードを入力
  • ランタイム: Python 3.11
  • ソースコード: インライン エディタ
  • エントリ ポイント: entry_point
main.py
import functions_framework
from output_log import SampleClass

@functions_framework.http
def entry_point(request):
  sample = SampleClass()
  sample.run("Cloud Functionsから呼び出す")
  return "Success", 200
requirements.txt
--extra-index-url https://us-central1-python.pkg.dev/{project_id}/quickstart-python-repo/simple/
python-quickstart==1.0.0
functions-framework==3.5

デプロイ を押下するとビルドエラーになりました。

左メニューの Cloud Build > 履歴 から失敗したビルド情報を見てみます。

プロジェクトAの Artifact Registry にアップロードしたpython-quickstartパッケージのインストールに失敗しています。

https://cloud.google.com/artifact-registry/docs/integrate-functions

If Cloud Functions and Artifact Registry are in different projects, you must grant repository access to the Cloud Build service account.
To provide read-only access for downloading dependencies, grant the Artifact Registry Reader role.

別プロジェクトの Artifact Registry を Cloud Functions から参照するには Cloud Build サービスアカウントに Artifact Registry 読み取りロールが必要でした。
Cloud Functions で使用される Cloud Build サービスアカウントはデフォルトの場合 Google 管理のサービスアカウントが指定されます。

Cloud Build サービスアカウントのアドレスは[プロジェクト番号]@cloudbuild.gserviceaccount.comになります。
プロジェクト番号は Google Cloud コンソールのダッシュボードからも確認できます。

プロジェクトAに作成した Artifact Registry quickstart-python-repoリポジトリ の Artifact Registry 読み取りロールをプロジェクトBの Cloud Build サービスアカウントに付与します。

再度プロジェクトBの Cloud Functions function-python-quickstartをデプロイすると成功しました。

動作確認

  1. ローカル端末または Cloud Shell からfunction-python-quickstartにリクエストを送信
curl -X POST https://us-central1-{project_id}.cloudfunctions.net/function-python-quickstart \
-H "Authorization: bearer $(gcloud auth print-identity-token)" 

function-python-quickstartのmain.pyで返却している「Success」という文字が表示されました。

  1. プロジェクトB の Cloud Functions ログを確認

    Artifact Registry にアップロードしたquickstart-python-repoパッケージのoutput_logを使用してログ出力されたことを確認できました。

Discussion