Eventarcを用いてCloud Storageへのファイルアップロードイベントを検知してみた
今回はEventarcを利用して、Cloud Storageにファイルがアップロードされたことを検知してCloud Runのエンドポイントを呼び出してみました。以前Pub/Subを使ってBigQueryと連携することはしてみましたが、今回はEventarcを使ってみました。
早速試してみる
今回は以下の公式ドキュメントを参考に進めました。
システム構成は以下のようになっています。
- PCからCloud Storageにファイルをアップロードする
- Cloud Storageに対してファイルがアップロードされたらEventarcトリガーが実行される
- Cloud Run上の
POST /eventarc
に対してリクエストが投げられる
Pythonコードの実行
以下のようなシンプルなFastAPIサーバを立てます。POST /eventarc
に対してEventarcがリクエストを送信し、イベント内容をインメモリのリストに追加します。GET /items
を呼び出すとイベント内容一覧のリストがそのまま返されます。
uv init -p 3.12
uv add fastapi uvicorn
from fastapi import FastAPI, Request
received_items = []
app = FastAPI()
@app.post("/eventarc")
async def set_item(request: Request):
event = await request.json()
received_items.append(event)
@app.get("/items")
def get_items():
return received_items
こちらのコードをCloud Runにデプロイするにあたり、以下のDockerfileを利用します。
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim
WORKDIR /app
COPY . /app
EXPOSE 8080
RUN uv sync
CMD ["uv", "run", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]
Artifact Registryのレポジトリ作成とDockerイメージのPush
先ほど作成したPythonコードをArtifact RegistryにPushするために、以下のスクリプトを実行します。
PROJECT_ID="..."
REGION="asia-northeast1"
REPOSITORY_NAME="eventarc-cloud-run-test"
IMAGE_NAME="fastapi-app"
TAG="latest"
SERVICE_NAME="fastapi-app"
PROJECT_NUMBER="..."
# Create Artifact Repository
gcloud artifacts repositories create $REPOSITORY_NAME \
--repository-format=docker \
--location=$REGION
# Construct the full image URL
IMAGE_URL="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/${IMAGE_NAME}:${TAG}"
echo "Building Docker image for linux/amd64 platform..."
docker build --platform linux/amd64 -t "${IMAGE_URL}" .
docker push "${IMAGE_URL}"
Cloud Storageバケットの作成
Eventarcのトリガー先となるCloud Storageバケットを作成します。
gcloud storage buckets create gs://${PROJECT_ID}-bucket/ --location=${REGION}
Cloud Runのデプロイ
先ほど作成したArtifact Registryのレポジトリからイメージを取得して、Cloud Run上にFastAPIサーバを立てます。
gcloud run deploy ${SERVICE_NAME} --image ${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/${SERVICE_NAME}:${TAG}
今回は公開エンドポイントとしてデプロイしました。サービスが作成された後に/docs
にアクセスするとSwagger UIが確認できます。
Eventarcトリガーの作成
それでは本題のトリガーを作成してみましょう。今まで作成したCloud RunとCloud Storageを対象にして、以下のようにしてトリガーを作成します。イベント送信先のCloud Runサービスは--destination-run-service
で指定し、イベント送信用のエンドポイントとして--destination-run-path=/eventrc
を指定しています。また、ファイルのアップロードを検知する対象のストレージは--event-filters=bucket=${PROJECT_ID}-bucket
のようにして指定しています。
gcloud eventarc triggers create ${SERVICE_NAME} \
--destination-run-service=${SERVICE_NAME} \
--destination-run-region=${REGION} \
--location=${REGION} \
--event-filters="type=google.cloud.storage.object.v1.finalized" \
--event-filters="bucket=${PROJECT_ID}-bucket" \
--service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com \
--destination-run-path=/eventarc
動作チェックしてみる
それではまずはファイルアップロード前のアイテム一覧を取得してみます。Swagger UIから実行した結果、以下のようにまだ何もリストには登録されていないことがわかります。
次にバケットにファイルをアップロードしてみましょう。試しに一番最初に貼り付けたアーキテクチャ図(arch.png)をアップロードしてみます。
その後に再度Swagger UIでGET /items
を実行すると、以下のようにイベント情報が記録されていることが確認できました。内容を見ると、mediaLink/selfLink
に登録したファイル名が記録されていたり、ストレージクラスや登録日時が記録されていることがわかりました。この構成を利用することで、アップロードされたファイルに対してのみ処理を実行するといった利用方法があるかと思います。
まとめ
今回はEventarcを用いてイベントをトリガーし、Cloud Storageへのファイルアップロード情報をCloud Runに伝えてみました。MLの分野で言うとファイルの前処理などのトリガーとして使う機会があると思うので、今後もっと色々なパイプラインをEventarcで組んでみようと思います。
Discussion