PythonでAzureFunctionsを動かす
「サーバーレスがやってみたい」ので、AzureFunctionsをPythonで動かします。
AzureFunctionsでのPython対応は割と最近なようです。情報
個人利用レベルでまとめたものを以下に記載します。
チーム開発での利用方法や本番運用の方法などはまた後日しらべます。
動作環境
Windows10 / Powershell
Python 関数アプリではポータルにおける関数の編集はサポートされていません。開発には CLI または VS Code を使用してください。詳細情報
とのことなので、Pythonを用いて開発するにはCLIかVSCodeを用いる必要があり、今回はCLIで進めます。
CLIでの操作の方が、自分が今何をしているのか理解できるからいいですね(Gitもコマンドライン派です)
また、AzureFunctionsがpython3.6.xにしか対応していないようです。(2019/11/01現在)
私の環境は現在3.8が入っているので、切り変える必要があります。
バージョンの切り替えは、簡単にですが以下に記載しました。 参考にしてください。
AzureFunctionsとは?
そもそもAzureFunctionsはどんなものでしょうか。
Azure Functions は、インフラストラクチャを明示的にプロビジョニングしたり管理したりする必要がない、イベントトリガー型のコードを実行できるサーバーレス コンピューティング サービスです。
Function as a Service (FaaS)
と呼ばれるもので、AWS Lambda
やGoogle Cloud Functions
と似た機能です。
関数アプリのプラン
関数アプリには実行環境の異なる3種類のプランがあり、通常のCLI構築では従量課金プラン
が選択されます。
プラン | 英名 | 概要 | 課金体系 |
---|---|---|---|
従量課金プラン | Consumption plan | 受信イベントの数に基づいて動的に追加および削除 | 関数の実行中にのみ課金 |
Premium プラン | Premium plan | 従量課金プランと同じように、Azure Functions ホストのインスタンスが、受信イベントの数に基づいて追加および削除 | 課金は、実行や消費されたメモリごとの課金ではなく、必要なインスタンスや事前ウォーミングされたインスタンスで使用されたコア秒数とメモリに基づいています。 1 つのプランにつき、少なくとも 1 つのインスタンスが常にウォーム状態である必要があります。 つまり、実行数に関係なく、アクティブなプランごとに最小の月額コストがかかります。 |
App Serviceプラン | Dedicated plan | 他の App Service アプリ (Basic、Standard、Premium、Isolated SKU) と同じ専用 VM 上でも実行できます。 | App Service プランの関数アプリに対する支払いは、Web アプリなどの他の App Service リソースの場合と同じ |
AzureFunctions(2.x)の対応言語
2019/11/05現在では、以下の言語に対応しています。
C#(.NET Core 2.2) / JavaScript(Bide 8,10) / F#(.NET Core 2.2) / Java(Java8) / PowerShell(PowerShell Core 6) / Python(Python 3.6.x) / TypeScript
AzureFunctionsの作成
本題に入ります。
AzureFunctionsをローカル開発するには、Azure Functions Core Tools
が必要です。
Azure Functions Core Tools を使用すると、ローカル コンピューター上のコマンド プロンプトまたはターミナルから関数を開発およびテストできます。 ローカル関数はライブ Azure サービスに接続できるため、完全な Functions ランタイムを使用してローカル コンピューター上で関数をデバッグすることができます。 Azure サブスクリプションに関数アプリをデプロイすることもできます。
npmを利用してインストールします。(要 Node.js)
npm install -g azure-functions-core-tools
関数アプリの作成
関数アプリプロジェクトの作成
関数アプリを作成するためのプロジェクトを作成します。
前述でインストールしたAzure Functions Core Tools
を利用します。
func init <project_name>
でプロジェクトを作成します。
func init MyFunctionProj
実装言語の選択肢が表示されるので、今回はpython
を選択します。
Select a worker runtime:
dotnet
node
python
powershell
選択後、フォルダが作成されるので、フォルダを移動します。
cd MyFunctionProj
関数アプリの作成
関数アプリを作成します。
AzureFunctionsでは、起動トリガーを選択する必要があります。
起動トリガーは、何を起因として関数アプリを起動させるかの設定で、以下の種類があります。
本記事では、よく利用されるHTTP trigger
を利用します。
トリガー | 概要 |
---|---|
Azure Blob Storage trigger | Azure Blob Storage 内でファイルがアップロードまたは変更されると実行 |
Azure Cosmos DB trigger | Azure Cosmos DB データベースでドキュメントが追加または変更されると実行 |
Azure Event Grid trigger | Event Gridのルーティング棋院で関数を実行 |
Azure Event Hub trigger | Event Hubがメッセージを受信すると関数を実行 |
HTTP trigger | Web アプリで HTTP 要求が発生すると関数を実行(今回のもの) |
Azure Queue Storage trigger | Azure Storage Queueに新しいアイテムが追加されると関数を実行 |
Azure Service Bus Queue trigger | Azure Service Bus キューに新しいアイテムが追加されたら関数を実行 |
Azure Service Bus Topic trigger | Azure Service Bus Topicへの新しいメッセージの到着に応答して関数を実行 |
Timer trigger | 定義したスケジュールに従って定期的に Azure 関数を実行 |
関数アプリには、以下コマンドを利用します。
func new
起動トリガーの選択肢が表示されるので、HTTP trigger
を選びます。
Select a template:
Azure Blob Storage trigger
Azure Cosmos DB trigger
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
選択後、関数名を記載要求されるので任意の関数名を記載します。
以下では、「httpTrigger」を記載しています。
Select a template: HTTP trigger
Function name: [HttpTrigger] httpTrigger
関数アプリのフォルダ構成
関数アプリのフォルダ構成は以下のような構成になっています。
1つのプロジェクトには複数の関数アプリを作成することも可能です。
/
│ .gitignore
│ host.json
│ local.settings.json
│ requirements.txt
│
├─.vscode
│ extensions.json
│
├─<function_name_1>
│ function.json
│ __init__.py
│
└─<function_name_2>
function.json
__init__.py
関数アプリで重要となってくるのは以下のファイルです。
中身の詳細については、後述します。
ファイル | 役割 |
---|---|
_init_.py | 関数アプリプログラム |
function.json | 関数アプリの設定 |
host.json | すべての関数アプリに影響するグローバル設定 |
local.settings.json | ローカル環境でのアプリケーション変数 |
関数アプリの動作確認とデプロイ
前述までで処理で、既に動作可能なサンプルアプリが構築されています。
動作を確認してAzureへデプロイします。
関数アプリの動作確認
以下コマンドで、ローカル環境での実行を行います。
func host start
%%%%%%
%%%%%%
@ %%%%%% @
@@ %%%%%% @@
@@@ %%%%%%%%%%% @@@
@@ %%%%%%%%%% @@
@@ %%%% @@
@@ %%% @@
@@ %% @@
%%
%
Azure Functions Core Tools (2.7.1724 Commit hash: faf97bb64a53fbf1c7ef7e5c608c392c8662951b)
Function Runtime Version: 2.0.12763.0
...
Http Functions:
httpTrigger: [GET,POST] http://localhost:7071/api/httpTrigger
...
上記のように実行され、表示されるhttp://localhost:7071/api/httpTrigger
が関数アプリのURLです。
構築されているアプリは、クエリストリングを読み取って画面を表示するアプリです。
http://localhost:7071/api/httpTrigger
へアクセス
Please pass a name on the query string or in the request body
http://localhost:7071/api/httpTrigger?name=TanakaTaro
へアクセス
Hello TanakaTaro!
Azureへの関数アプリのデプロイ
動作していることが確認できたので、Azureへ関数アプリをデプロイします。
前提条件
ResousGroup 作成済
AzureStorageAccount 作成済
未作成の場合は、以前書いた記事を参考にしてみてください。
Azure側での関数アプリの作成
デプロイ先となるAzureの関数アプリを以下のコマンドで作成します。
az functionapp create --resource-group <resource_group> --os-type <os_type> --consumption-plan-location <c_plan_location> --runtime <runtime> --name <app_name> --storage-account <storage_account>
コマンドのオプションは以下のものを利用します。
値 | 概要 |
---|---|
--resource_group (-g) | 作成済のリソースグループ |
--os_type | functionの動作環境のOS Linux/Windows |
--consumption_plan_location (-c) | アプリを動作させるロケーション(※注) |
--runtime | 利用言語 dotnet/java/node/powershell/python |
--storage_account (-s) | 作成済のAzureStorageAccount |
(※注)
ロケーションにより、対応言語が異なる場合があります。
2019/11/05現在、pythonの従量課金プランは日本では提供されていないようです。(プランは以下参照)
Requested features are not supported in region. Please try another region.
以下の構成で作成します。
az functionapp create -g <resource_groupe> --os-type Linux -c eastus --runtime python --name <function_name> --storage-account <storage_account>
Your Linux function app '<function_name>', that uses a consumption plan has been successfullycreated but is not active until content is published usingAzure Portal or the Functions Core Tools.
Azureへのデプロイ実施
以下コマンドで、ローカル環境の関数アプリをAzure環境へデプロイします。
func azure functionapp publish <app_name> --build remote
Getting site publishing info...
Creating archive for current directory...
Performing remote build for functions project.
Uploading 11.16 MB [###########################----------------------------------------]
...
Remote build succeeded!
Syncing triggers...
Functions in function_name:
httpTrigger - [httpTrigger]
Invoke url: https://function_name.azurewebsites.net/api/httpTrigger?code=<接続キー>
上記のようにURLが表示されれば、デプロイ成功です。
表示されているURLで、ローカル環境での接続と同じような結果が表示されます。
実行されたコードは、デプロイ時に同時に生成されるApplicationInsightsにログが残ります。
各種ファイルの詳細
前述までで、作成~デプロイは出来ましたが、あくまでもドキュメントの手順通りに実施したもので、関数アプリを使いこなせているとは言えません。
関数アプリを自由に使いこなすために、各ファイルの中身を確認していきます。
__init__.py
__init__.py
は、関数アプリのプログラム本体です。
引数に、azure.functions.HttpRequest
返値に、azure.functions.HttpResponse
を定義しています。
その他、特に気になる部分は無し。 普通のHTTP通信のやりとりのように思えます。
import logging
import azure.functions as func
def main(req: func.HttpRequest) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
name = req.params.get('name')
if not name:
try:
req_body = req.get_json()
except ValueError:
pass
else:
name = req_body.get('name')
if name:
return func.HttpResponse(f"Hello {name}!")
else:
return func.HttpResponse(
"Please pass a name on the query string or in the request body",
status_code=400
)
function.json
関数アプリのもう一つの重要な要素であり、関数アプリに関わる各種設定を記載するファイルです。
{
"scriptFile": "__init__.py",
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "$return"
}
]
}
まず、2つの要素があります。
scriptFile
は、関数アプリのプログラムファイル名を記載しています。
bindings
は、関数アプリに対する input と output のトリガーとバインド情報を設定します。
詳細は公式を参照するのが良いかと思います。
bindings
は、以下のような構成になっており、これを踏まえたうえで公式情報を見ればすんなりと理解できそうです。
{
"type":"<type_name>",
"direction":"in または out",
"トリガー毎の個別設定":"個別設定"
}
本記事で構成している内容だと、
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
]
}
『
input
のトリガーのタイプはHTTP Trigger
認証レベルは"function"レベル
inputのazure.functions.HttpRequest
をreq
と変数定義する
対応するメソッドはGET
またはPOST
』
と読み取ることができます。
認証レベルについての公式情報
{
"type": "http",
"direction": "out",
"name": "$return"
}
『
output
のタイプはhttp
返却値は関数の戻り値
』
と読み取ることができます。
$return
についての公式情報
→ $return
を指定すると返り値を応答時の値と認識できるそうです。(C# 以外)
環境設定の所得
az functionapp config appsettings list -g resourcegroupus -n azuresamplefunction -o table
上記に記載したのは、HTTP Trigger
時かつあくまでもサンプルの内容なので、他トリガーを利用する際はドキュメントをご覧ください。
host.json
host.json
は、関数アプリ全体に影響を及ぼす設定です。
初期構築の際は、関数アプリのバージョンを表す情報しか記載されていません。
{
"version": "2.0"
}
関数アプリの同時実行やログの出力設定など、細かい調整を行うもので、本番運用する際には記載必須になるかと思います。
今回は特に気にせず進めるため、詳細は公式情報をご覧ください。
local.settings.json
local.settings.json
は、ローカル環境構築時に利用される設定情報です。公式情報
デプロイ後の動作には影響しません。
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "python",
"AzureWebJobsStorage": "{AzureWebJobsStorage}"
}
}
Values
の値は、関数アプリの環境変数です。
環境変数は、Azure側に存在するので必要に応じて記載します。
{AzureWebJobsStorege}
となっている箇所は、ストレージ アカウントの接続文字列です。公式情報
以下の形で記載またはAzureから環境情報を取得して設定する必要があります。
Key | 値の例 |
---|---|
AzureWebJobsStorage | DefaultEndpointsProtocol=https;AccountName=[name];AccountKey=[key] |
Azure環境情報取得
az functionapp config appsettings list -g <resource_groupe> -n <function_name> -o table
Name SlotSetting Value
------------------------------ ------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
FUNCTIONS_WORKER_RUNTIME False python
FUNCTIONS_EXTENSION_VERSION False ~2
AzureWebJobsStorage False <接続文字列>
AzureWebJobsDashboard False <接続文字列>
WEBSITE_NODE_DEFAULT_VERSION False 10.14.1
APPINSIGHTS_INSTRUMENTATIONKEY False <Application Insightsとの接続キー>
終わりに
AzureFunctionsを初めて利用した際に利用した情報を記載させていただきました。
FaaS
は抽象度が高く、どのように動いているのか掴みづらい部分はありますが、CLIを通して、設定ファイルの内容を見つめることで少しづつ理解できるものかと思います。
まだ全然使いこなせていないので、引き続き学習していきます。
誤りがありましたらご連絡いただければ幸いです。
Pythonの仮想動作環境の作成
Pythonの仮想環境切り替えにvenv
を利用します。
現在のバージョン確認
py --version
Python 3.8.0
仮想環境の作成
3.6系仮想環境の作成
別バージョンの仮想環境を作成する場合も、対象のバージョンのPythonをインストールしておく必要があります。
現在インストールされているバージョンを確認してない場合にはダウンロードしておきます。
py --list
-3.8-32 *
-3.7-32
-3.6-64
仮想環境作成
py -3.6 -m venv <venv_name>
py -3.6 -m venv venv
.\venv\Scripts\activate
(venv) PS C:\**>
再度バージョン確認
3.6系になってます
py --version
Python 3.6.8