0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DevContainerでAzure Durable Functionsを試す

Posted at

以下のQuickStartに従い、PythonでDurable Functionsを作ってみる。最近はDev Containerに興味があるので、こちらを使ってみる。

環境設定

AzureでFunctionsを作成する

これはAzure上で従量課金プランでAzure Functionsのリソースを作成するだけ。特に何も特別なこともしていないのでスキップ。

durablefunという名前で作りました。

Dev Containerの準備

PythonでAzure Functionsを開発するためのDev Containerを立ち上げる。しばやんさんのイメージを使う。
image.png
Pythonを選択。
image.png
Azure Functionsの最新サポートバージョンは3.11なのでそれにする。
image.png
初回は10分ほどかかった。こんな風になりました。
image.png
image.png

feature、拡張機能は以下のようなものが入っていた。

devcontainer.json
  "features": {
    "ghcr.io/jlaundry/devcontainer-features/azure-functions-core-tools:1": {},
    "ghcr.io/devcontainers/features/docker-in-docker:2": {}
  },
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-azuretools.vscode-azurefunctions",
        "ms-azuretools.vscode-docker",
        "ms-python.python"
      ]
    }
  },

Python環境

Durable Functionsの開発のために必要なものを入れる。

Requirements.txt
azure-functions
azure-functions-durable
vscode ➜ /workspaces/DurableFunction $ python -m venv venv
vscode ➜ /workspaces/DurableFunction $ venv/bin/activate

以下の記事に従って、venvとvscodeをcacheするために、mountsを追加。

devcontainer.json
{
  "name": "Azure Functions (Python 3)",
  "dockerComposeFile": "docker-compose.yml",
  "service": "app",
  "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
  "forwardPorts": [
    7071,
    10000,
    10001,
    10002
  ],
  "otherPortsAttributes": {
    "onAutoForward": "ignore"
  },
  "features": {
    "ghcr.io/jlaundry/devcontainer-features/azure-functions-core-tools:1": {},
    "ghcr.io/devcontainers/features/docker-in-docker:2": {}
  },
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-azuretools.vscode-azurefunctions",
        "ms-azuretools.vscode-docker",
        "ms-python.python"
      ]
    }
  },
    "mounts": [
    "source=vscode-extensions,target=/vscode/.vscode-server/extensions,type=volume",
    {
      "type": "volume",
      "source": "myprj-cache-vscode",
      "target": "/home/vscode/.cache"
    },
    {
      "type": "volume",
      "source": "myprj-venv",
      "target": "${containerWorkspaceFolder}/.venv"
    }
  ]
}

devcontainer.jsonを更新したので、Rebuilld Dev Containerをして、次は10秒程度で起動するようになりました。

開発

拡張機能でCreate new Azure Functionsを選択。
image.png
HTTPトリガーで作成。
image.png

image.png

Add new setting
image.png

Azureにサインイン

流れで環境変数をAzure側にも作成する。
image.png

function_app.py
import azure.functions as func
import azure.durable_functions as df

myApp = df.DFApp(http_auth_level=func.AuthLevel.FUNCTION)

# An HTTP-triggered function with a Durable Functions client binding
@myApp.route(route="orchestrators/{functionName}")
@myApp.durable_client_input(client_name="client")
async def http_start(req: func.HttpRequest, client):
    function_name = req.route_params.get('functionName')
    instance_id = await client.start_new(function_name)
    response = client.create_check_status_response(req, instance_id)
    return response

# Orchestrator
@myApp.orchestration_trigger(context_name="context")
def hello_orchestrator(context):
    result1 = yield context.call_activity("hello", "Seattle")
    result2 = yield context.call_activity("hello", "Tokyo")
    result3 = yield context.call_activity("hello", "London")

    return [result1, result2, result3]

# Activity
@myApp.activity_trigger(input_name="city")
def hello(city: str):
    return f"Hello {city}"

デバッグ

そのままローカル上でデバッグしようとしたところ、以下のエラーになった。Storage Accountに接続できていないらしい。

[2025-01-25T02:58:09.754Z] A host error has occurred during startup operation '5690128b-8db5-4f7b-bc11-69c78fb57d31'.
[2025-01-25T02:58:09.774Z] Microsoft.Azure.WebJobs.Extensions.DurableTask: Unable to resolve the Azure Storage connection named 'Storage'.
Value cannot be null. (Parameter 'provider')
[2025-01-25T02:58:09.808Z] Host startup operation has been canceled
[2025-01-25T02:58:09.836Z] Exception encountered while listening to EventStream
[2025-01-25T02:58:09.836Z] System.Private.CoreLib: The request stream was aborted. The HTTP/2 connection faulted.
[2025-01-25T02:58:09.889Z] The Azure Storage connection string is either empty or invalid. Unable to record diagnostic events, so the diagnostic logging service is being stopped.
[2025-01-25T02:58:09.889Z] Azure.Data.Tables: Value cannot be null. (Parameter 'connectionString').
[2025-01-25T02:58:09.890Z] Unable to get table reference. Aborting write operation.

が、しばやんさんが作ってくれたDev Containerのイメージでは、Azuriteの設定はしてくれている。

docker-compose.yml
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    platform: linux/amd64
    volumes:
      - ../..:/workspaces:cached
    command: sleep infinity
    network_mode: service:azurite

  azurite:
    image: mcr.microsoft.com/azure-storage/azurite
    restart: unless-stopped

調べてみたところ、Azure FunctionsをデバッグするときはVSCodeの設定もしてやる必要がある。localsettings.jsonで設定の追加が必要らしい。

local.settings.json
{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "AzureWebJobsDashboard": "UseDevelopmentStorage=true"
  }
}

正常にデバッグされ、エンドポイントが表示された。

Functions:

        http_start:  http://localhost:7071/api/orchestrators/{functionName}

        hello: activityTrigger

        hello_orchestrator: orchestrationTrigger

Postmanでたたいてみる。
image.png

{
    "id": "583f5b37ee2a4c4b829e728a6741c220",
    "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/583f5b37ee2a4c4b829e728a6741c220?taskHub=TestHubName&connection=Storage&code=Avb4lMcPpaQnisWEc5fm6JzHLEkPnDGgtGESzDchauzqAzFu5eA6wA==",
    "sendEventPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/583f5b37ee2a4c4b829e728a6741c220/raiseEvent/{eventName}?taskHub=TestHubName&connection=Storage&code=Avb4lMcPpaQnisWEc5fm6JzHLEkPnDGgtGESzDchauzqAzFu5eA6wA==",
    "terminatePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/583f5b37ee2a4c4b829e728a6741c220/terminate?reason={text}&taskHub=TestHubName&connection=Storage&code=Avb4lMcPpaQnisWEc5fm6JzHLEkPnDGgtGESzDchauzqAzFu5eA6wA==",
    "rewindPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/583f5b37ee2a4c4b829e728a6741c220/rewind?reason={text}&taskHub=TestHubName&connection=Storage&code=Avb4lMcPpaQnisWEc5fm6JzHLEkPnDGgtGESzDchauzqAzFu5eA6wA==",
    "purgeHistoryDeleteUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/583f5b37ee2a4c4b829e728a6741c220?taskHub=TestHubName&connection=Storage&code=Avb4lMcPpaQnisWEc5fm6JzHLEkPnDGgtGESzDchauzqAzFu5eA6wA==",
    "restartPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/583f5b37ee2a4c4b829e728a6741c220/restart?taskHub=TestHubName&connection=Storage&code=Avb4lMcPpaQnisWEc5fm6JzHLEkPnDGgtGESzDchauzqAzFu5eA6wA==",
    "suspendPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/583f5b37ee2a4c4b829e728a6741c220/suspend?reason={text}&taskHub=TestHubName&connection=Storage&code=Avb4lMcPpaQnisWEc5fm6JzHLEkPnDGgtGESzDchauzqAzFu5eA6wA==",
    "resumePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/583f5b37ee2a4c4b829e728a6741c220/resume?reason={text}&taskHub=TestHubName&connection=Storage&code=Avb4lMcPpaQnisWEc5fm6JzHLEkPnDGgtGESzDchauzqAzFu5eA6wA=="
}

statusQueryGetUriをたたいてみると処理結果が表示された。

{
    "name": "hello_orchestrator",
    "instanceId": "583f5b37ee2a4c4b829e728a6741c220",
    "runtimeStatus": "Completed",
    "input": null,
    "customStatus": null,
    "output": [
        "Hello Seattle",
        "Hello Tokyo",
        "Hello London"
    ],
    "createdTime": "2025-01-25T03:21:19Z",
    "lastUpdatedTime": "2025-01-25T03:21:34Z"
}

VSCodeの設定

pip installでライブラリをインストールしているのに、import <ライブラリ>の下に黄色い波線が表示され、インテリセンスも効かないときがあった。そういう時はDev ContainerのVSCodeの設定で、Pylance拡張機能の設定を更新したところ直った。
"Pylance" を検索し、"Python > Analysis: Type Checking Mode" を "basic" に設定。

image.png

Azureにデプロイしてみる

拡張機能が入って入っているのでサインイン。
image.png
拡張機能でデプロイ。
image.png

image.png

Azure上のものを叩いて、正常にレスポンスが返ってくることをかくに
image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?