Azure Functionsの基本的な使い方 with Python
この記事の目的
Azure Functionsは様々なアップデートを経て使い方が変わっており、新旧の情報がネット上で入り混じっていたり、公式のドキュメントは言葉足らずだったりで使い始める際の嵌まりのあるポイントサービスです。
この記事では以下のような前提で「ふつうに」Azure Functionsを開発してデプロイするための手順をまとめます。
今回の前提:
- Ubuntu22.04
- Python 3.X
- HTTPトリガーで簡易なREST API関数を追加する
2024/12月時点の情報に基づいています。
環境を整える
Pythonの仮想環境を作る
pyenvでもvenvでもよいので、Python環境を整えます。
後で作るAzure上のランタイムとバージョンを合わせるためにここでは 3.11.10 をpyenvでインストールすると仮定します。
pyenv install 3.11.10
cd (作業ディレクトリ)
pyenv local 3.11.10
pyenvのインストールについては以下をご参照ください。
Azure Functions Core Tools4のインストール
こちらのリンクを参考にAzure Functions Core Toolsをインストールします。
マイクロソフトリポジトリをaptサーバに追加します。
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg
sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-$(lsb_release -cs 2>/dev/null)-prod $(lsb_release -cs 2>/dev/null) main" > /etc/apt/sources.list.d/dotnetdev.list'
aptパッケージリストをアップデートします。
sudo apt-get update
Core Tools4をインストールします
sudo apt-get install azure-functions-core-tools-4
(Optional)OpenSSL1.1のインストール
インストールが完了したら func
コマンドを実行してみてください。
No usable version of libssl was found
というメッセージが表示された場合、適したバージョンのOpenSSLがインストールされていません。
Ubuntu22.04の標準OpenSSLパッケージは3.0ですが、以下のページの手順でOpenSSL1.1をインストール可能です。
https://zenn.dev/mizti/articles/2f53f012b2c842
プロジェクトの骨組みを作る
プロジェクトの作成
Core Toolsを使ってAzure Functionsのプロジェクトを作ります。
func init my-function-app --worker-runtime python --model V2
これによって、以下のようなファイル構成のディレクトリが作成されます。
my-function-app/
├── function_app.py
├── host.json
├── local.settings.json
└── requirements.txt
作成したプロジェクトディレクトリに入ります。このプロジェクトがデプロイ時には「関数アプリ」に対応します。
cd my-function-app
Pythonのプログラミングモデルv1/v2について
AzureでPythonを動作させる場合、プログラミングモデルv1とv2が存在しており、現在の主流はv2です。しかし、テンプレートから作成される関数はプログラミングモデルv1となっています。
大きな違いはv1はfunctions.jsonでトリガーや出力を定義し、v2はPythonのメソッドへのアノテーションで定義を行うためfunctions.jsonが不要な点となります。
また、v1ではプロジェクトディレクトリ内に関数ごとのディレクトリを作成し__init__.pyを作りますが、v2ではルートディレクトリにあるfunction_app.pyにすべての関数を原則的に記載する点も異なります。(適宜関数定義をpythonの参照を使って外部ファイルに書き出すことは可能です)
- Pythonプログラミングモデルv2 (参考)
(参考: Functionsの構造について)
プログラミングモデルv1とv2の違いについては以下の記事でもまとめておりますのでご参考ください。
HTTP関数の追加
このプロジェクトに各関数を追加していきます。この関数もまずはテンプレートによって追加していきます。
まず、利用できるテンプレートの一覧を確認します。
$ func templates list
テンプレートの一覧
C# Templates:
Azure Blob Storage trigger
Azure Cosmos DB trigger
Durable Functions activity
Durable Functions entity (class)
Durable Functions entity (function)
Durable Functions Entity HTTP starter
Durable Functions HTTP starter
Durable Functions orchestrator
Azure Event Grid Cloud Event trigger
Azure Event Grid trigger
Azure Event Hub trigger
HTTP trigger
IoT Hub (Event Hub)
Kafka output
Kafka trigger
Azure Queue Storage trigger
RabbitMQ trigger
SendGrid
Azure Service Bus Queue trigger
Azure Service Bus Topic trigger
SignalR negotiate HTTP trigger
SQL Input Binding
SQL Output Binding
SQL Trigger
Timer trigger
Custom Templates:
Azure Blob Storage trigger
Azure Cosmos DB trigger
Azure Event Grid trigger
Azure Event Hub trigger
HTTP trigger
IoT Hub (Event Hub)
Kafka trigger
Azure Queue Storage trigger
RabbitMQ trigger
SendGrid
Azure Service Bus Queue trigger
Azure Service Bus Topic trigger
SignalR negotiate HTTP trigger
Timer trigger
JavaScript Templates:
Azure Blob Storage trigger
Azure Cosmos DB trigger
Dapr Publish Output Binding
Dapr Service Invocation Trigger
Dapr Topic Trigger
Durable Functions activity
Durable Functions entity
Durable Functions Entity HTTP starter
Durable Functions HTTP starter
Durable Functions orchestrator
Azure Blob Storage Trigger (using Event Grid)
Azure Event Grid trigger
Azure Event Hub trigger
HTTP trigger
IoT Hub (Event Hub)
Kafka output
Kafka trigger
Azure Queue Storage trigger
RabbitMQ trigger
SendGrid
Azure Service Bus Queue trigger
Azure Service Bus Topic trigger
SignalR negotiate HTTP trigger
SQL Input Binding
SQL Output Binding
SQL Trigger
Timer trigger
Azure Blob Storage trigger
Azure Cosmos DB trigger
Durable Functions entity
Durable Functions orchestrator
Azure Blob Storage trigger (using Event Grid)
Azure Event Grid trigger
Azure Event Hub trigger
HTTP trigger
Azure Queue Storage trigger
Azure Service Bus Queue trigger
Azure Service Bus Topic trigger
Timer trigger
Dapr Publish Output Binding
Dapr Service Invocation Trigger
Dapr Topic Trigger
PowerShell Templates:
Azure Blob Storage trigger
Azure Cosmos DB trigger
Dapr Publish Output Binding
Dapr Service Invocation Trigger
Dapr Topic Trigger
Durable Functions activity
Durable Functions HTTP starter
Durable Functions orchestrator
Azure Blob Storage Trigger (using Event Grid)
Azure Event Grid trigger
Azure Event Hub trigger
HTTP trigger
IoT Hub (Event Hub)
Kafka output
Kafka trigger
Azure Queue Storage trigger
RabbitMQ trigger
SendGrid
Azure Service Bus Queue trigger
Azure Service Bus Topic trigger
SignalR negotiate HTTP trigger
SQL Input Binding
SQL Output Binding
SQL Trigger
Timer trigger
Python Templates:
Azure Blob Storage trigger
Azure Cosmos DB trigger
Dapr Publish Output Binding
Dapr Service Invocation Trigger
Dapr Topic Trigger
Durable Functions activity
Durable Functions entity
Durable Functions HTTP starter
Durable Functions orchestrator
Azure Blob Storage Trigger (using Event Grid)
Azure Event Grid trigger
Azure Event Hub trigger
HTTP trigger
Kafka output
Kafka trigger
Azure Queue Storage trigger
RabbitMQ trigger
Azure Service Bus Queue trigger
Azure Service Bus Topic trigger
SQL Input Binding
SQL Output Binding
SQL Trigger
Timer trigger
TypeScript Templates:
Azure Blob Storage trigger
Azure Cosmos DB trigger
Durable Functions activity
Durable Functions entity
Durable Functions Entity HTTP starter
Durable Functions HTTP starter
Durable Functions orchestrator
Azure Blob Storage Trigger (using Event Grid)
Azure Event Grid trigger
Azure Event Hub trigger
HTTP trigger
IoT Hub (Event Hub)
Kafka output
Kafka trigger
Azure Queue Storage trigger
RabbitMQ trigger
SendGrid
Azure Service Bus Queue trigger
Azure Service Bus Topic trigger
SignalR negotiate HTTP trigger
SQL Input Binding
SQL Trigger
Timer trigger
Azure Blob Storage trigger
Azure Cosmos DB trigger
Durable Functions entity
Durable Functions orchestrator
Azure Blob Storage trigger (using Event Grid)
Azure Event Grid trigger
Azure Event Hub trigger
HTTP trigger
Azure Queue Storage trigger
Azure Service Bus Queue trigger
Azure Service Bus Topic trigger
Timer trigger
func new --template "Http Trigger" --name my_http_func
すると
Select a number for Auth Level:
1. FUNCTION
2. ANONYMOUS
3. ADMIN
Choose option:
と聞かれるため、ここでは1(FUNCTION)を選んでおきます。これは関数のセキュリティレベルを選択するもので、FUNCTION
の場合、各関数ごとに発行される関数キーがリクエストに必要になります。
ローカル実行する
デプロイに先立ちまずはローカルで実行します。
func start
上記を実行すると以下のようにサーバが起動します。
リクエストをしてみます
curl http://localhost:7071/api/my-http-func
This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.
というレスポンスが戻ってきて正常にAPIリクエストが捌かれていることがわかります。
POSTリクエストも投げてみます。
curl -X POST -d '{"name":"John"}' http://localhost:7071/api/my-http-func
Hello, John. This HTTP triggered function executed successfully.
name要素で与えた名前が戻ってきます。(ローカルで実行しているときは認証不要です)
Azure側のリソースを作成する
デプロイする
func azure functionapp publish $FUNCTION_APP_NAME
Azure上にデプロイされた関数にアクセスする
関数の認証レベルには以下の三種類があります。
認証レベル | 意味 |
---|---|
Function(デフォルト) | 関数キーが必要 |
Admin | 関数アプリ全体のキー(マスターキー)が必要 |
Anonymous | 認証なしでアクセス可能 |
テンプレートで作成されたHTTPは認証レベルが "authLevel": "function"
に設定されています。このためAzure上にデプロイされたFunctionにアクセスする際には関数キーを付与してリクエストする必要があります。
鍵の取得コマンド
az functionapp keys list --name $FUNCTION_APP_NAME --resource-group $RESOURCE_GROUP_NAME
ポータルで関数を選択>関数キーからでも確認可能です。
GETリクエストをしてみます。
curl https://$FUNCTION_APP_NAME.azurewebsites.net/api/my-http-func?code=$FUNCTION_KEY
POSTリクエストをしてみます。
curl -X POST -H "Content-Type: application/json" -H"x-functions-key: $FUNCTION_KEY" -d '{"name":"John"}' https://$FUNCTION_APP_NAME.azurewebsites.net/api/my-http-func
ログを確認する
ログの種類ごとに確認方法が異なります。
基盤ログ確認 (Premiumプランのみ)
基盤側で出力されているデプロイログ等のログです。
- リアルタイムなログ確認
az webapp log tail --name $FUNCTION_APP_NAME --resource-group $RESOURCE_GROUP_NAME
過去ログ数十行が表示された後、同ログの最新をストリームで表示し続けます。
このログはデプロイに関するログや、Functionのトリガー、出力などを含んでいるためこのログを見るだけでも一応デバッグ等も可能ではありますが、出力が多すぎるためアプリケーションのデバッグには後述の方法を併用することもお勧めします。
- Kuduサイトによる確認
https://{$FUNCTION_APP_NAME}.scm.azurewebsites.net/
にアクセスすると、以下のような画面が表示されます。
この画面のLog Stream
タブから1.と同様のログを確認できます。
アクセスログの確認
HTTPアクセスログは関数アプリに連携しているApplication Insights(内のLog Analytics)のrequestsテーブルに保存されています。
関数アプリの左メニュー > 監視 > ログからアクセスし、requests
テーブルをリクエストすることでログを確認できます。
※ログ出力がLog Analyticsに反映されるまで30秒~1分程度時間を要します。
Log AnalyticsへのクエリはKQLと呼ばれるクエリ言語で行います。テーブル内容をまとめてみる以上の高度なクエリを作りたい場合には以下をご参照ください。
アプリケーションログの確認
print()
やlogging.info
等で出力されたアプリケーションログを確認したい場合にはアクセスログと同様にLog Analyticsのtraces
テーブルで確認することができます。
例外ログの確認
アプリケーションで発生した例外はLog Analyticsのexceptions
テーブルで確認が可能です。このテーブル内のinnermostMessage
テーブルがアプリから送信された生のスタックトレースを保持しています。
保存されているメッセージの例
Result: Failure
Exception: SyntaxError: unmatched ')' (init.py, line 10)
Stack: File "/azure-functions-host/workers/python/3.11/LINUX/X64/azure_functions_worker/dispatcher.py", line 535, in _handle__function_load_request
func = loader.load_function(
File "/azure-functions-host/workers/python/3.11/LINUX/X64/azure_functions_worker/utils/wrappers.py", line 44, in call
return func(*args, **kwargs)
File "/azure-functions-host/workers/python/3.11/LINUX/X64/azure_functions_worker/loader.py", line 220, in load_function
mod = importlib.import_module(fullmodname)
File "/usr/local/lib/python3.11/importlib/init.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 846, in exec_module
File "<frozen importlib._bootstrap_external>", line 983, in get_code
File "<frozen importlib._bootstrap_external>", line 913, in source_to_code
File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
開発に入る
ここまでの確認できた後でテンプレートを修正しながら具体的なPythonコード開発に入るのが良いと思います。
Discussion