Azure Functions Python Programming v2 で Blob Storage Trigger (w/ Event Grid) を使う！

# 本記事について

Azure Functions で Python のコードを動かすには、現在 Programming Model が v1 と v2 の2種類があります。

https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-reference-python?tabs=asgi%2Capplication-level&pivots=python-mode-decorators

この記事では、v2 モデルのほうで、Blob Storage Trigger を利用する際に、より高速で高信頼な Event Grid を経由させてトリガーさせるときの設定を見ていきます。

https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-reference-python?tabs=asgi%2Capplication-level&pivots=python-mode-decorators

https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-event-grid-blob-trigger?tabs=isolated-process%2Cnodejs-v4&pivots=programming-language-python

# 実際の手順

下記に主な手順を見ていきます。

## VS Code から Python v2 で Blob Trigger の関数アプリを作成する

VS Code のコマンドパレットで、Azure Functions: Create Function... を選択し、Python v2 で Blob Trigger で関数アプリのコードを生成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/d3599e42-dea2-431a-78ea-242098c8bfa6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/ef92d359-b7a8-f46c-66c7-b920de1816ba.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/717e7c13-53e1-370e-38aa-1501b6844a32.png)

function_app.py を以下のように書き換えます。

```python:function_app.py
import azure.functions as func
import logging

app = func.FunctionApp()

@app.blob_trigger(arg_name="myblob", path="mycontainer/{name}",
                               connection="Connection_String",
                               source="EventGrid") 
def BlobTriggerEventGrid(myblob: func.InputStream):
    logging.info(f"Python blob trigger function processed blob"
                f"Name: {myblob.name}"
                f"Blob Size: {myblob.length} bytes")

    file = myblob.read()
    logging.info(f"File Content: {file}")
```

* path はトリガーされるファイルの Blob Storage での PATH になります。上記例は、コンテナー直下にファイルを置く構成です。

* connection は環境変数への参照になります。Azure Functions の環境変数に同名の変数を作成し、今回利用するストレージアカウントの接続文字列を入れておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/9b47d14e-ac1e-ab24-4276-4e0756317f7f.png)

* source には、source="EventGrid" という値を入れます。

そして、Azure 上の関数アプリにこの関数をデプロイします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/a5121b6a-9e0d-257b-faad-e3f3808486b3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/c67d5dc3-446b-6b12-48b8-21fa014fdd60.png)


## ストレージアカウントでイベントを設定する

次にストレージアカウント側で、イベントを設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/3765f8e3-1ff2-f2fe-95e9-97bc5bf4c28a.png)

イベントサブスクリプション名とシステムトピック名は適当な値を入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/d15c42b4-fcb6-3220-a18a-a93a34f30d0b.png)

フィルターはトリガーで使いたい種別を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/eff57554-9abf-6a89-6910-36c5ac5f365d.png)

エンドポイントは種類は webhook にし、エンドポイントは下記の値を入力します。

```
https://<関数アプリ名>.azurewebsites.net/runtime/webhooks/blobs?functionName=Host.Functions.<関数名>&code=<BLOB_EXTENSION_KEY>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/187bb0cf-e570-93bd-1372-dc64e18bd4ef.png)


関数アプリ名、関数名はそれぞれ作成したものの値を入れ、BLOB_EXTENSION_KEY は関数アプリのアプリキーのページから取得します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/3b171281-416e-11d5-2eb9-f1914101354d.png)

次のフィルタータブでは、イベントをトリガーする対象のファイルを制限できます。例えば、特定のコンテナー内のテキストファイルに絞りたいときは、下記のように記述します。

```
/blobServices/default/containers/<コンテナー名>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/0f6d436e-4285-0fd9-954c-50995cab5761.png)

作成すると、Event Grid リソースが作成され、下記のようなイベントサブスクリプションができています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/657e95cb-ff98-b216-0e12-ef1d7b07b05b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/808790d7-ef13-2439-0979-db474b3ccf5e.png)

## 関数のテスト

この状態で、ストレージアカウント内の mycontainer にテキストファイルをアップロードしてみます。

すると、関数が実行され、下記のようなログが出てきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276225/147e448d-0b7e-3f93-da51-6f5739bc0609.png)


# 最後に

＊本稿は、個人の見解に基づいた内容であり、所属する会社の公式見解ではありません。また、いかなる保証を与えるものでもありません。正式な情報は、各製品の販売元にご確認ください。