Open14

Durable Functions

sayasaya

Azure Blob Storageとの操作を行うためにazure.storage.blobモジュールを使用します。また、Excelファイルとの操作のためにopenpyxlモジュールを使用します。これらのモジュールは、Azure FunctionsのPython環境にインストールする必要があります。

まず、必要なモジュールをインストールします:

bash
Copy code
pip install azure-storage-blob openpyxl

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

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

# クライアント関数
@myApp.route(route="start-batch")
@myApp.durable_client_input(client_name="client")
async def start_batch(req: func.HttpRequest, client: df.DurableOrchestrationClient):
    try:
        instance_id = await client.start_new(orchestrator_function_name="batch_orchestrator")
        response = client.create_check_status_response(req, instance_id)
        return func.HttpResponse("バッチを正常に開始しました。", status_code=200)
    except Exception as e:
        return func.HttpResponse(f"バッチの開始に失敗しました: {str(e)}", status_code=500)

# オーケストレータ関数
@myApp.orchestration_trigger(context_name="context")
def batch_orchestrator(context: df.DurableOrchestrationContext):
    tasks = []

    task1 = context.call_activity("activity_function1", "Input1")
    tasks.append(task1)

    task2 = context.call_activity("activity_function2", "Input2")
    tasks.append(task2)

    # すべてのアクティビティ関数が完了するのを待つ
    results = yield context.task_all(tasks)
    return results

# アクティビティ関数1
@myApp.activity_trigger(input_name="input_data1")
def activity_function1(input_data1: str):
    # 処理
    return f"Processed: {input_data1}"

# アクティビティ関数2
@myApp.activity_trigger(input_name="input_data2")
def activity_function2(input_data2: str):
    # 処理
    return f"Processed: {input_data2}"

このサンプルでは、API Managementから/start-batchのエンドポイントを呼び出すことで、バッチ処理が開始されるようになっています。オーケストレータ関数内で、複数のアクティビティ関数を呼び出し、すべてのアクティビティ関数が完了するのを待ってから結果を返すようになっています。

このコードをVisual Studio Codeで実装し、Azureポータル上にデプロイすることで、API Management経由でAzure Functionsを呼び出し、バッチ処理を起動することができます。

sayasaya

指定されたタスクを行うアクティビティ関数の例を以下に示します。この例では、Azure Blob Storageとの操作を行うためにazure.storage.blobモジュールを使用します。また、Excelファイルとの操作のためにopenpyxlモジュールを使用します。これらのモジュールは、Azure FunctionsのPython環境にインストールする必要があります。

まず、必要なモジュールをインストールします:

pip install azure-storage-blob openpyxl
次に、アクティビティ関数のコードを示します:

from azure.storage.blob import BlobServiceClient
import openpyxl
import re
from datetime import datetime
import io

@myApp.activity_trigger(input_name="input_data")
def process_blob(input_data):
    # Blob Storageの設定
    connection_string = "YOUR_CONNECTION_STRING"
    container_name = "YOUR_CONTAINER_NAME"
    blob_service_client = BlobServiceClient.from_connection_string(connection_string)

    # Blob Storageからファイルを取得
    blobs = blob_service_client.get_container_client(container_name).list_blobs()
    for blob in blobs:
        # 命名則に則っているか確認
        match = re.match(r"^[A-Z]{3}_\d{8}.xlsx$", blob.name)
        if match:
            code = blob.name[:3]
            blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob.name)
            stream = blob_client.download_blob().readall()

            # Excelファイルを読み込む
            wb = openpyxl.load_workbook(filename=io.BytesIO(stream))
            ws = wb.active

            # A列の先頭行のデータがあるフォーマットに則っているかを確認
            header = ws['A1'].value
            if not re.match(r"^[A-Z]{3}-\d{4}$", header):
                return "Header format does not match"

            # A列とB列のデータを取得
            col_a = [cell.value for cell in ws['A'] if cell.value]
            col_b = [cell.value for cell in ws['B'] if cell.value]

            # データの整形
            exclusion_data = []
            data = []
            for a, b in zip(col_a, col_b):
                # データのチェック(例として文字列のチェック)
                if not isinstance(a, str) or len(a) > 10:
                    exclusion_data.append((a, b))
                else:
                    data.append((a, b))

            # データをBlob Storageに格納
            today = datetime.today().strftime('%Y%m%d')
            exclusion_blob_name = f"{today}/exclusion_data.txt"
            data_blob_name = f"{today}/data.txt"

            blob_service_client.get_blob_client(container=container_name, blob=exclusion_blob_name)\
                .upload_blob("\n".join([f"{a},{b}" for a, b in exclusion_data]))
            blob_service_client.get_blob_client(container=container_name, blob=data_blob_name)\
                .upload_blob("\n".join([f"{a},{b}" for a, b in data]))

    return "Data processing completed successfully"

この関数をアプリケーションに組み込むことで、Blob Storageのデータの処理とその後の保存を自動化することができます。


Azure Blob Storageを操作するためには、connection_stringとcontainer_nameが必要です。これらの情報はAzureポータルで確認・取得できます。

connection_string:
Blob Storageアカウントの接続文字列は、Azureポータルから特定のストレージアカウントの「アクセスキー」セクションにある「接続文字列」欄からコピーできます。

この接続文字列は、ストレージアカウントへのアクセス権を提供するため、安全に管理する必要があります。
接続文字列の例:

DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=mykey;EndpointSuffix=core.windows.net

この接続文字列には、ストレージアカウントの名前(AccountName)、アクセスキー(AccountKey)、その他のエンドポイント情報が含まれています。

container_name:
Blob Storageでは、データは"blob"として保存され、これらのblobは"container"という単位でグループ化されます。
container_nameは、あなたが操作したい特定のコンテナの名前です。
コンテナ名の例:

mycontainer

この名前は、AzureポータルでBlob Storageアカウント内に作成されたコンテナの一覧から確認できます。

これらの情報を得た後、コード内の該当箇所を適切な値に置き換えることで、Azure Blob Storageの操作が可能となります。

sayasaya

エラー処理とトランザクション管理は、特にデータベース操作の際に非常に重要です。

エラー処理:

通常、データベース関連の操作では、例外が発生する可能性があります(例:データベースが接続できない、クエリの文法が間違っているなど)。これらの例外をキャッチして、適切にハンドルすることが必要です。
トランザクション管理:

複数のデータベース操作を1つのトランザクションとしてグループ化し、すべての操作が成功するか、1つでも失敗するとすべての操作がロールバックされるようにすることができます。これにより、データの整合性が保たれます。

@myApp.activity_trigger(name="register_data")
def register_data(conn, a_code, x_code, b_code, c_code):
    cursor = conn.cursor()

    try:
        # トランザクション開始
        conn.begin()

        # AコードがFXテーブルに登録されているか確認
        cursor.execute("SELECT COUNT(1) FROM FX WHERE A_Code = ?", a_code)
        exists = cursor.fetchone()[0]

        if exists == 0:
            # AコードとXコードをFXテーブルに新規登録
            cursor.execute("INSERT INTO FX (A_Code, X_Code) VALUES (?, ?)", a_code, x_code)
        else:
            # 既存のレコードを新しいXコードで更新
            cursor.execute("UPDATE FX SET X_Code = ? WHERE A_Code = ?", x_code, a_code)

        # F1テーブルのAコードにリンクされているすべてのレコードを削除
        cursor.execute("DELETE FROM F1 WHERE A_Code = ?", a_code)

        # F1テーブルに新しいレコードを追加
        cursor.execute("INSERT INTO F1 (A_Code, B_Code, C_Code) VALUES (?, ?, ?)", a_code, b_code, c_code)

        # Oコードに関連するデータの場合、FOテーブルの関連操作を行う
        if o_code:
            # FOテーブルのOコードにリンクされているすべてのレコードを削除
            cursor.execute("DELETE FROM FO WHERE O_Code = ?", o_code)

            # FOテーブルに新しいレコードを追加
            cursor.execute("INSERT INTO FO (B_Code, O_Code, C_Code) VALUES (?, ?, ?)", b_code, o_code, c_code)

        # トランザクション確定
        conn.commit()

    except Exception as e:
        # エラーが発生した場合、トランザクションをロールバック
        conn.rollback()
        cursor.close()
        return f"登録中にエラーが発生しました: {str(e)}"

    cursor.close()
    return "データの登録が完了しました"

このコードでは、try-exceptブロックを使用してエラーを捕捉し、エラーが発生した場合にはトランザクションをロールバックしています。これにより、部分的な更新や追加が行われず、データの整合性が保たれます。

このような方法でエラー処理とトランザクション管理を実装することで、より安全で信頼性の高いデータベース操作を行うことができます。

sayasaya
  1. 各関数の組み合わせ:
    1.1 クライアント関数
    この関数はAPIからのHTTPトリガーを受け取り、オーケストレータ関数を起動します。

python
Copy code
@myApp.route(route="orchestrators/{functionName}")
@myApp.durable_client_input(client_name="client")

async def http_start(req: func.HttpRequest, client):
    instance_id = await client.start_new("main_orchestrator")
    response = client.create_check_status_response(req, instance_id)
    return response

1.2 オーケストレータ関数
この関数は、アクティビティ関数の実行順序や、条件に応じたアクティビティ関数の呼び出しをコントロールします。

@myApp.orchestration_trigger
def main_orchestrator(context):
    # データチェックとBlobへのデータ保存
    output = context.call_activity("check_blob_data", "input_data")

    # データ登録
    result = context.call_activity("register_data", output)
    
    return result

  1. Azureポータルでのテスト方法:
    デプロイ:

Visual Studio CodeのAzure Functions拡張を使用して関数をAzureにデプロイします。
テスト:

Azureポータルにログインします。
作成したFunction Appを選択します。
左ペインから「関数」をクリックして、関数のリストを表示します。
http_start関数を選択して、右上の角にある「テスト/実行」をクリックします。
新しいペインが表示され、入力データやHTTPメソッドを提供することができます。必要に応じてこれらを設定し、「実行」をクリックして関数をテストします。
ログの確認:

関数の実行中や実行後に発生したエラーや警告、情報などのログを確認することができます。Azureポータルの「モニタリング」セクションからこれらのログを確認することができます。
このようにしてAzureポータルで関数のテストを行うことができます。一度関数が正常に動作することを確認したら、実際のシナリオで使用するAPIやその他のサービスとの統合を進めることができます。

sayasaya

Visual Studio Code (VSC) を使用してAzureにDurable Functionをデプロイし、テストする手順は以下のとおりです。

前提条件:

Azureアカウントを持っていること。
Azure Functions拡張機能とAzure Storage拡張機能がVSCにインストールされていること。
Azure Functions Core Toolsがインストールされていること。
Python、JavaScript、またはC#のAzure FunctionsのプロジェクトがVSC上で準備されていること。
Azureにサインイン:

VSC左側のバーから、Azureのアイコンをクリックします。
"Sign in to Azure"をクリックしてAzureにサインインします。
Function Appの作成:

Azure Functionsエクスプローラーから、"+" アイコンをクリックして新しいFunction Appを作成します。
必要な情報 (リソースグループ、ストレージアカウント、ロケーションなど) を提供します。
デプロイ:

Azure Functionsエクスプローラーで、作成したFunction Appを右クリックし、"Deploy to Function App"を選択します。
プロジェクトとFunction Appを選択し、デプロイを開始します。
デプロイが完了したら、出力ウィンドウにURLが表示されます。
テスト:

ブラウザを使用して、提供されたURLにアクセスします。これは、HTTPトリガーを使用している場合に有効です。
AzureポータルでFunction Appを開き、Functionのログを確認します。これにより、Functionが正しく動作しているかどうかを確認できます。
必要に応じて、Azure Storage ExplorerやAzureポータルを使用して、テーブルやキュー、Blobなどの関連するリソースを確認します。
ローカルでのテスト:

VSCのターミナルで func start を実行すると、ローカルでFunctionが実行されます。
ローカルエンドポイントURLが表示されますので、Postmanやcurlを使用してテストリクエストを送信することができます。
これで、VSCからAzureにDurable Functionをデプロイし、テストする基本的な手順を完了しました。

sayasaya

Azureポータルにデプロイが反映されない場合の原因はさまざまです。以下は一般的な原因と対処方法をリストアップしています:

デプロイ先の確認:

VSCからデプロイしたときに、正確に目的のFunction Appにデプロイされているか確認してください。異なるリソースグループやサブスクリプションにデプロイしてしまっている可能性があります。
キャッシュのクリア:

ブラウザのキャッシュが原因で最新の情報が表示されないことがあります。キャッシュをクリアするか、別のブラウザやプライベートモードでAzureポータルにアクセスしてみてください。
デプロイログの確認:

VSCの出力パネルでAzure Functionsのデプロイログを確認してください。何かしらの警告や情報が出力されている場合があります。
アクティビティログの確認:

Azureポータルにて、対象のFunction Appを選択し、「アクティビティログ」を確認してください。ここにデプロイ関連の情報やエラーが記録されている可能性があります。
デプロイ設定の確認:

Function Appの設定で、デプロイメントソースとしてどこが選択されているか確認してください。たとえば、GitHubやDevOps Pipelinesなどの外部のCI/CDツールからのデプロイ設定がある場合、VSCからのデプロイが上書きされる可能性があります。
Function Appの再起動:

AzureポータルからFunction Appを再起動してみてください。稀にこれで反映されることがあります。
ローカル設定の問題:

local.settings.json にはローカル環境でのみ使用する設定が含まれている場合があります。これがデプロイ先に適用されると問題が生じることがあります。このファイルがデプロイされていないことを確認してください。
依存関係の確認:

必要なパッケージや依存関係が正しくデプロイされているか確認してください。
リソースの制限:

使用しているAzureサブスクリプションにリソースの制限(クォータ)がある場合、デプロイに失敗することがあります。Azureポータルの「利用状況とクォータ」セクションで確認できます。
もし上記のステップで問題が解決しない場合、具体的な設定やエラーメッセージなどの詳細情報を元にさらに調査する必要があります。

sayasaya

Azure Durable Functionsにおいて、クライアント関数、オーケストレータ関数、アクティビティ関数は通常、異なるファイルに分割して記載するのが一般的です。しかし、それらをすべて一つのファイルにまとめても問題はありません。関数の分割はプロジェクトの規模やチームの開発スタイルによって変わります。

一般的な構造は以下のようになります:

アクティビティ関数: Activities.py

すべてのアクティビティ関数をこのファイルに格納します。
オーケストレータ関数: Orchestrators.py

オーケストレーションのロジックをこのファイルに記述します。
クライアント関数: Starters.py または Client.py

HTTPトリガーを使用してオーケストレーションを開始する関数をこのファイルに記述します。
共通の設定やユーティリティ関数: Utils.py や Shared.py

オーケストレータやアクティビティ関数で共通して使用する関数や設定をここに置くことができます。
しかし、すべてをfunction_app.pyにまとめることも可能です。小規模なアプリケーションの場合、それが簡単で理解しやすいかもしれません。

注意点として、各関数(アクティビティ、オーケストレータ、クライアント)にはそれぞれ対応するfunction.json設定ファイルが必要です。ファイルを分割する場合、各関数のフォルダ内にそれぞれのfunction.jsonを配置する必要があります。

最終的には、プロジェクトの規模、チームの好み、保守性の要件などに応じて適切な構造を選択してください。

sayasaya

zure Durable Functionsは、Azure Functionsの拡張機能であり、長時間のバックグラウンドタスク、ワークフロー、および関連する状態管理を簡単に実装するためのものです。以下は、Durable Functionsの主な特徴とその使い方の概要です。

  1. 主な特徴
    状態の保存と継続: Durable Functionsは、関数の状態を自動的にチェックポイントし、後でその状態を復元することができます。これにより、長時間のワークフローを実装することが可能となります。

自動的な再試行: アクティビティ関数の失敗時に自動的な再試行をサポートしています。

時間の経過に基づく待機: ワークフローの一部として、特定の期間の待機を組み込むことができます。

ファンアウト/ファンイン: 複数の関数の同時実行(ファンアウト)と、その結果の集約(ファンイン)を簡単に実装できます。

状態のクエリ: オーケストレーションの状態や履歴をクエリすることができます。

  1. Durable Functionsの主なコンポーネント
    a. オーケストレータ関数
    ワークフローのロジックを記述する部分。
    複数のアクティビティ関数の呼び出しや、条件分岐、ループなどの制御構文を持つことができます。
    b. アクティビティ関数
    実際のタスクを実行する関数。
    データベースへのクエリ、外部サービスとの通信など、オーケストレータ関数から呼び出される具体的な操作を実行します。
    c. クライアント関数
    オーケストレーションの開始、停止、状態の確認などを行う関数。
    主にHTTPトリガーに基づいてオーケストレーションを管理します。

  2. サンプルコード
    前回提供したサンプルコードは、Durable Functionsの基本的な構文を示すものです。その中で、オーケストレータ関数、アクティビティ関数、およびクライアント関数の使用方法を示しています。

  3. ヒントとベストプラクティス
    オーケストレータ関数内での非決定論的な操作(現在の日時の取得、乱数の生成、外部システムとの通信など)は避けるべきです。これらの操作はアクティビティ関数内で行うのが適切です。

オーケストレータ関数は再入可能であるため、その実行中に複数回呼び出される可能性があります。そのため、その実行が副作用を持たないことを確認することが重要です。

sayasaya

HTTPトリガーを使用すると、HTTPリクエストに応答してAzure Functionを実行できます。以下は、HTTPトリガーを使用してAzure Functionを作成・実行する基本的な手順を示しています。

  1. 新しいHTTPトリガー関数の作成
    Visual Studio Code:
    Azure Functionsの拡張機能をインストールします。
    コマンドパレットを開いて(Ctrl+Shift+P)、Azure Functions: Create New Projectを選択します。
    適切なディレクトリと言語を選択します。
    トリガーとしてHTTP triggerを選択します。
    トリガーの認証レベルを選択します(通常はFunctionやAnonymousを選びます)。
    これで、基本的なHTTPトリガー関数が生成されます。この関数は、デフォルトでGETまたはPOSTリクエストを受け入れ、クエリ文字列またはボディからnameパラメータを読み取り、Hello, [name]というレスポンスを返します。

  2. ローカルでの関数の実行
    Visual Studio Codeを使って関数をローカルで実行する場合:

関数プロジェクトを開きます。
デバッグセッションを開始します(F5キー)。
コンソールに表示されるURLにブラウザやHTTPクライアントツール(例: Postman)を使用してアクセスします。
例: http://localhost:7071/api/YourFunctionName?name=Azure

  1. Azureにデプロイ
    Visual Studio Codeから直接Azureにデプロイするには:

Azure Functionsの拡張機能のサイドバーを開きます。
Deploy to Function Appをクリックして、デプロイ先のFunction Appを選択または新しく作成します。
指示に従ってデプロイを完了します。
4. Azureでの関数のテスト
Azure Portalを開き、作成したFunction Appを選択します。
HTTPトリガー関数を選択します。
右側のペインに表示されるURLをコピーします。
そのURLにアクセスして関数をテストします。
これらの手順に従うと、HTTPリクエストに応答するAzure Functionが作成できます。関数のロジックやHTTPレスポンスのカスタマイズについては、関数のコードを編集して調整することができます。

sayasaya
  1. 新しいDurable Functionsプロジェクトの作成
    Visual Studio CodeのAzure Functions拡張機能を使用して新しいFunctionsプロジェクトを作成します。
    HTTPトリガーを選択して、新しいDurable FunctionsのHTTPスターターを作成します。
  2. 各関数の定義
    1. ローカルでのテスト
      Visual Studio CodeでFunctionsプロジェクトを開きます。
      デバッグセッションを開始します(F5キー)。
      コンソールに表示されるHTTPトリガーのURLにアクセスします。これにより、オーケストレーションが開始されます。
      Azure Storage Explorerなどのツールを使用して、Azure Storageエミュレータ上のDurable Functionsのテーブルやキューを監視し、オーケストレーションの進行状況を確認します。
  3. Azureへのデプロイ
    Azure Functionsの拡張機能のサイドバーを開き、Deploy to Function Appをクリックします。
    デプロイ先のFunction Appを選択または新しく作成します。
  4. Azureでのテスト
    Azure Portalで作成したFunction Appに移動し、HTTPトリガー関数のURLを取得します。
    そのURLを使用して、オーケストレーションを開始します。
    Azure PortalのDurable Functionsタブで、オーケストレーションのステータスと履歴を確認します。
    この手順を完了すると、クライアント関数、オーケストレータ関数、アクティビティ関数の全てがAzure上で正常に動作していることが確認できます。

Azure Durable Functionsに関連する用語にはいくつか特有のものがあり、それらの概念を理解することが重要です。以下に、質問の中で挙げられた「オーケストレーション」と「HTTPスターター」に関する説明をします。

オーケストレーション (Orchestration):
オーケストレーションは、複数のタスクや関数の実行を調整・管理するプロセスを指します。Azure Durable Functionsにおいて、オーケストレーションはオーケストレータ関数によって行われます。オーケストレータ関数は、アクティビティ関数の呼び出し、外部システムとの通信、タイマーの設定、条件分岐、ループなどの複雑なワークフローを定義することができます。Durable Task Frameworkにより、オーケストレーションは長時間実行されるものとして設計されており、中断・再開が可能です。

HTTPスターター (HTTP starter):
HTTPスターターは、HTTP経由でオーケストレーションを開始するための特別な関数です。具体的には、HTTPリクエストを受け取り、そのリクエストに基づいてオーケストレータ関数を開始する機能を持っています。このHTTPスターター関数は、クライアント関数とも呼ばれることがあります。

クライアント関数は、オーケストレーションを開始する際に、オーケストレータ関数の名前や、オーケストレーションに渡す初期パラメータなどを指定することができます。また、クライアント関数は、オーケストレーションの開始に成功すると、オーケストレーションのインスタンスIDや、オーケストレーションのステータスを確認するためのURLなどの情報をHTTPレスポンスとして返すことが一般的です。

これらの用語は、Azure Durable Functionsのドキュメントやチュートリアル、公式のサンプルコードなどで頻繁に使用されていますので、理解しておくと、Durable Functionsの利用がスムーズになります。

sayasaya
  1. まず、基本的な概念:
    Azure Functions: Microsoft Azureのサービスの1つで、コードをサーバーレス環境で実行できるプラットフォームです。簡単に言うと、特定のトリガー(例: HTTPリクエスト、タイマーなど)に反応して動く小さなプログラムをクラウド上で動かすことができます。

API Management: Microsoft Azureのサービスで、APIの作成、公開、管理、監視、保護をサポートするツールです。APIのゲートウェイの役割を果たします。

Power Apps: Microsoftのサービスの1つで、コードを書かずにアプリケーションを作成することができるプラットフォームです。

  1. あなたのシナリオの説明:
    Power Appsでアプリを作成:

このアプリを使って、バッチ処理を開始するためのボタンなどのUIがあります。
API ManagementでAPIをセットアップ:

Power Appsからのリクエストを受け取るAPIをAPI Managementでセットアップします。
このAPIは、実際のバッチ処理を実行するAzure Functionsを呼び出す役割を持っています。
Azure Functionsでバッチ処理:

Azure Functionsには、バッチ処理を行うためのコード(関数)があります。
API Managementを通じてこの関数が呼び出されると、実際の処理が始まります。
3. フローの動作:
Power Appsでユーザーが「バッチ処理開始」ボタンをクリックします。
Power Appsは、API Managementに設定されている特定のAPIエンドポイントにリクエストを送信します。
API Managementは、そのリクエストを受け取り、Azure Functionsにリダイレクトします。
Azure Functionsでのクライアント関数(バッチ処理関数)が実行されます。
このフローにより、Power Appsのユーザーインターフェイスを使用してAzure Functionsのバッチ処理を簡単に開始することができます。API Managementは、リクエストのルーティング、認証、ロギングなどの追加的な機能を提供して、このフローをより安全かつ効率的にします。

sayasaya

ファイルがBlob Storageに正しくアップロードされるが、片方のファイルの中身が反映されないという状況にはいくつか考えられる原因があります:

ファイルのオープン時の問題:with openを使用してファイルを開いているとき、ファイルの内容が完全に読み込まれていないか、読み込みモードが正しくない可能性があります。

ファイルの書き込み:アップロードする前にファイルを書き込んでいる場合、ファイルのクローズが正しく行われていないか、データが完全にフラッシュされていない可能性があります。

Blob Storageへのアップロードの問題:正しいBlob StorageコンテナやBlob名にデータをアップロードしているか確認してください。また、アップロードの際のエラーが発生していないか確認すると良いでしょう。

キャッシュの問題:Blob Storageのデータがキャッシュされている可能性があります。Azure PortalやStorage Explorerのキャッシュや、ブラウザのキャッシュをクリアして、再度確認してみてください。

エンコーディングの問題:特定のファイルのエンコーディングがAzure Blob Storageと互換性がないか、読み込み時と書き込み時のエンコーディングが異なる可能性があります。

解決のために以下のアクションを試してみると良いでしょう:

使用しているコードを再度確認し、両方のファイルの処理が同じ方法で行われていることを確認してください。

ファイルの内容をプリントして、正しく読み込まれているか確認してください。

Blob Storageの操作に関するエラーや警告が表示されていないか、ログやトレースを確認してください。

これらの手順を試しても問題が解決しない場合、具体的なコードやエラーメッセージを共有していただければ、より詳しいサポートが可能です。

sayasaya

クティビティ関数1 (Blob Storageのファイル名を判定):
この関数はBlob Storageに格納されたデータのファイル名を判定します。

import azure.functions as func

def main(blob: func.InputStream, name: str) -> str:
    # ファイル名の命名規則に基づいて判定
    if "特定の命名規則" in name:
        return "Valid filename"
    else:
        return "Invalid filename"

function.json (アクティビティ関数1のバインディング):

{
  "bindings": [
    {
      "name": "blob",
      "type": "blobTrigger",
      "direction": "in",
      "path": "your-container-name/{name}",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

これにより、Blob Storageに新しいデータが追加されると、Azure Functionが自動的に起動し、ファイル名を判定するアクティビティ関数が実行されます。

注意: 上記のコードは概念的なものです。実際の環境や要件に合わせて調整が必要です。特に、ファイル名の命名規則の部分やBlob Storageのコンテナ名などは、具体的な要件に応じて変更してください。

こちらの関数定義について詳しく説明します。

def main(blob: func.InputStream, name: str) -> str:

この関数定義にはいくつかの部分が含まれています:

def main(...): これはPythonの関数を定義するための標準的な構文です。mainは関数名です。Azure Functionsでは、関数のエントリーポイントとしてよくmainが使われます。

blob: func.InputStream:

blob:関数内で使用する変数名です。この変数を使用して、Blob Storageからのデータのストリームを参照します。
func.InputStream:変数blobのデータ型を示しています。func.InputStreamは、Azure Functionsが提供するBlob Storageからの入力ストリームを表す型です。この型を使って、Blobの内容を読み取ることができます。
name: str:

name:関数内で使用する変数名です。この変数を使用して、トリガーされたBlobのファイル名を参照します。
str:変数nameのデータ型を示しています。nameは文字列型(str)です。
-> str: これは関数の戻り値の型を示しています。この関数は文字列(str)を返すことを期待しています。

この関数は、Blob Storageに新しいデータがアップロードされるか、既存のデータが更新されるたびにトリガーされます。この際、アップロードまたは更新されたBlobの内容とそのファイル名が関数に自動的に渡されます。関数は、これらの情報を用いて特定の処理(このケースでは、ファイル名の命名規則の確認)を行い、結果として文字列を返します。

sayasaya

function.jsonはAzure Functionsのプロジェクトにおいて非常に重要な役割を果たします。このファイルは、関数がどのようにトリガーされるのか、どんな入出力を持つのか、その他の設定について定義します。

以下に、Azure Functionsのfunction.jsonの主要な要素について説明します:

bindings:

これは関数に関連するトリガーや入出力の設定を含む配列です。

type: トリガーの種類やバインドの種類を指定します(例:"httpTrigger", "blob", "queue", etc.)。

direction: 入力、出力、またはトリガーのいずれかを示します。可能な値は "in", "out", または "inout" です。

name: Python関数内で使用されるパラメータ名。例えば、"name": "myBlob"とすると、Python関数内ではmyBlobという名前のパラメータを使ってblobデータにアクセスします。

disabled:

関数のトリガーを無効にするかどうかを指定します。trueに設定すると、関数は自動的にトリガーされません。
scriptFile:

実際の関数コードが含まれるPythonファイルの名前を指定します。通常、このファイルは同じディレクトリに存在します。
entryPoint:

関数ファイル内の特定の関数をエントリーポイントとして指定します。通常、この設定はPythonのAzure Functionsで必要ではありません。
例:

{
  "bindings": [
    {
      "name": "myBlob",
      "type": "blobTrigger",
      "direction": "in",
      "path": "samples-workitems/{name}",
      "connection": "AzureWebJobsStorage"
    }
  ],
  "disabled": false
}

この例では、samples-workitemsという名前のBlob Storageコンテナ内のBlobが変更されるたびに、関数がトリガーされる設定になっています。変更されたBlobのデータは、Python関数内のmyBlobという名前のパラメータを介してアクセスされます。

注意: 実際のAzure Functionsのアプリケーションでは、local.settings.jsonというファイルに、接続文字列などの設定が含まれることが多いです。これを使って、function.json内で"connection": "AzureWebJobsStorage"といった設定が参照されます。