Azure Functions - ローカルでのテスト、デバッグ（Python）

# 目的

Azure Functionsをローカルでテスト、デバッグする方法を確認する

# 準備

## 必要なもの

- Pyhon
- Azure Functions Core Tools
- Azure Functions（VS Code拡張機能）
- Azurite（VS Code拡張機能）

### Azure Functions Core Tools

ローカルPC上のターミナルから関数を開発およびテストするためのツール

以下からインストール
[Azure Functions Core Tools のインストール](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-run-local?tabs=windows%2Ccsharp%2Cbash#install-the-azure-functions-core-tools)
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/247c6cb0-b386-2b43-305e-1ff6055ef3e5.png)

### Azure Functions の VS Code Extension

VSCodeの拡張機能からインストール
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/fdea61e2-1a5a-fdb7-8b9d-7c57b1c8c209.png)

### Azurite

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/1422102f-287c-98dc-53c4-17a7983bb263.png)

`Azure Storage Emulator`を使用しようとしたが、[開発とテストに Azure ストレージ エミュレーターを使用する](https://docs.microsoft.com/ja-jp/azure/storage/common/storage-use-emulator)に`Azurite`が推奨されているので、
VSCodeの拡張機能から`Azurite`をインストール
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/8bc93619-d931-5f46-bfc5-2aafe3a078e3.png)

# プロジェクト、関数の作成

## プロジェクトの作成

[ローカル関数プロジェクトを作成する](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-run-local?tabs=windows%2Ccsharp%2Cbash#create-a-local-functions-project)より以下でプロジェクトを作成（`pyFunctions`は任意のプロジェクト名）

```:ターミナル
$ func init pyFunctions
```
ランタイムの選択が出てくるので今回はPythonを選択
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/9916d578-8e20-e08d-477e-b214e863440a.png)

## 関数の作成

[関数を作成する](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-run-local?tabs=windows%2Ccsharp%2Cbash#create-a-function)より以下で関数を作成

```:ターミナル
$ func new
```

関数トリガの選択が出てくるので今回は`HTTP trigger`と`Azure Event Grid trigger`で作成、
それぞれ関数名を`httpTrigger-test`、`eventGridTrigger-test`とした
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/02b07587-f4f1-b56a-591d-d71ede7cca88.png)

指定した関数名のサブフォルダーに関数のコードが生成されるので、今回は変更せず使用する
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/c62e8d86-e7e7-943d-3c2c-e082776d891d.png)

# 関数のテスト

## Azuriteの起動

VSCodeのコマンドパレットから`Azurite:Start`を実行
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/237a6bbb-963d-a2cf-447f-251f3675e2e4.png)

## 関数の起動

[関数をローカルで実行する](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-run-local?tabs=windows%2Cpython%2Cbash#run-functions-locally)より以下で関数を起動

```:ターミナル
$ func start
```

起動すると以下のように出力される
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/9715251d-3bbe-20a2-4ddc-6c3691f782fe.png)

## 関数の実行

今回、関数の実行にPostmanを使用

### HTTP trigger

[HTTP と webhook でトリガーされる関数](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-run-local?tabs=windows%2Cpython%2Cbash#http-and-webhook-triggered-functions)より以下のURLで関数を実行することができる

```:URL
http://localhost:{port}/api/{function_name}
```

以下Postmanの実行結果
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/f98f369d-9009-d677-0a96-a9845def2ddc.png)

以下ターミナルの出力結果
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/028766e7-255b-5fc6-24cb-de5ad1662a95.png)

### Azure Event Grid trigger

[HTTP でトリガーされない関数](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-run-local?tabs=windows%2Cpython%2Cbash#non-http-triggered-functions)には「HTTP トリガー、Webhook トリガー、Event Grid トリガーを除く、あらゆる種類の関数の場合、管理エンドポイントを呼び出すことによって、関数をローカルでテストできます。」と記載があり、Event Grid トリガの記載はなく、
[要求を手動で投稿する](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-bindings-event-grid-trigger?tabs=python%2Cbash#manually-post-the-request)に記載がある

以下の設定が必要

- Content-Type: application/json ヘッダを設定
- aeg-event-type: Notification ヘッダを設定
- 要求本文に RequestBin のデータを貼り付け

```:URL
http://localhost:7071/runtime/webhooks/eventgrid?functionName={FUNCTION_NAME}
```

要求本文には[イベント スキーマ](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-bindings-event-grid-trigger?tabs=python%2Cbash#event-schema)を参考に張り付け


以下Postmanにヘッダ、ボディを設定して実行した結果
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/5d847d82-8fd7-689c-bf9f-88cab8a296e1.png)
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/90c6fe80-f34b-a7f1-4735-0165c6ca6e76.png)

以下ターミナルの出力結果
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/8ac64e97-7cd4-c83e-a309-dde12ce0d68a.png)

# 関数のデバッグ

## プロジェクトの初期化

拡張機能Azure Functionsを選択し、`initialize Project for Use with VS Code...`をクリック
![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/88e63d0f-2712-238a-a6d5-a34b08ce21ac.png)

Pythonを選択
![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/fa44df0b-5303-e6a5-e571-d52d5498aad9.png)

以下初期化完了状態
![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/c4447b30-4301-469a-1638-9871ee76ab30.png)

## デバッグ

以下の`Attach to Python Functions`をクリック
![18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/b5a26706-fcc3-cd2c-629d-77f2aa267074.png)

関数が起動したら、関数のテスト時と同様にPostmanから関数を実行するとブレークすることができる
![20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/a6fe756b-2e2c-bd2b-8b16-b900050de296.png)