Azure Functions の Python 開発者向けガイド

この記事では、Python を使用した Azure Functions の開発について紹介します。 以下の内容は、「Azure Functions の開発者向けガイド」を既に読んでいることを前提としています。

Python 開発者は、次のいずれかの記事にも興味があるかもしれません。

作業の開始 概念 シナリオとサンプル

注意

Python ベースの Azure 関数を Windows 上のローカルで開発できますが、Python は、Azure で実行されている場合、Linux ベースのホスティング プランでのみサポートされます。 サポートされているオペレーティング システムとランタイムの組み合わせの一覧を参照してください。

プログラミング モデル

Azure Functions では、関数は入力を処理して出力を生成する Python スクリプト内のステートレスなメソッドであることが求められます。 既定で、ランタイムでは、このメソッドは main() と呼ばれるグローバル メソッドとして __init__.py ファイル内に実装されると想定されます。 また、代替エントリ ポイントを指定することもできます。

トリガーとバインディングからのデータをメソッド属性を介して関数にバインドするには、function.json ファイル内で定義されている name プロパティを使用します。 たとえば、次の function.json には、req という名前の HTTP 要求によってトリガーされるシンプルな関数が記述されています。

{
    "scriptFile": "__init__.py",
    "bindings": [
        {
            "authLevel": "function",
            "type": "httpTrigger",
            "direction": "in",
            "name": "req",
            "methods": [
                "get",
                "post"
            ]
        },
        {
            "type": "http",
            "direction": "out",
            "name": "$return"
        }
    ]
}

この定義に基づき、関数コードを含む __init__.py ファイルは次の例のようになります。

def main(req):
    user = req.params.get('user')
    return f'Hello, {user}!'

Python の型の注釈を使用することで、関数内に属性の種類および戻り値の型を明示的に宣言することもできます。 これは、多くの Python コード エディターによって提供される IntelliSense およびオートコンプリート機能を使用するのに役立ちます。

import azure.functions


def main(req: azure.functions.HttpRequest) -> str:
    user = req.params.get('user')
    return f'Hello, {user}!'

azure.functions.* パッケージに含まれる Python の注釈を使用すると、入力と出力がご利用のメソッドにバインドされます。

代替エントリ ポイント

function.json ファイル内で scriptFile プロパティと entryPoint プロパティをオプションで指定することによって、関数の既定の動作を変更できます。 たとえば、以下の function.json では、ご利用の Azure 関数のエントリ ポイントとして、main.py ファイル内の customentry() メソッドを使用するようにランタイムに指示が出されます。

{
  "scriptFile": "main.py",
  "entryPoint": "customentry",
  "bindings": [
      ...
  ]
}

フォルダー構造

Python 関数プロジェクトの推奨フォルダー構造は、次の例のようになります。

 <project_root>/
 | - .venv/
 | - .vscode/
 | - my_first_function/
 | | - __init__.py
 | | - function.json
 | | - example.py
 | - my_second_function/
 | | - __init__.py
 | | - function.json
 | - shared_code/
 | | - __init__.py
 | | - my_first_helper_function.py
 | | - my_second_helper_function.py
 | - tests/
 | | - test_my_second_function.py
 | - .funcignore
 | - host.json
 | - local.settings.json
 | - requirements.txt
 | - Dockerfile

メイン プロジェクト フォルダー (<project_root>) には、次のファイルを含めることができます。

  • local.settings.json:ローカルで実行するときに、アプリの設定と接続文字列を格納するために使用されます。 このファイルは Azure に公開されません。 詳細については、「local.settings.file」に関するページを参照してください。
  • requirements.txt:Azure に公開するときにシステムによってインストールされる Python パッケージの一覧が含まれます。
  • host.json: 関数アプリ インスタンス内にあるすべての関数に影響する構成オプションが含まれます。 このファイルは Azure に公開されます。 ローカルで実行する場合は、すべてのオプションがサポートされるわけではありません。 詳細については、「host.json」に関するページを参照してください。
  • .vscode/ :(省略可能) ストア VSCode 構成が含まれます。 詳細については、VSCode 設定に関するページを参照してください。
  • .venv/ :(省略可能) ローカル開発で使用される Python 仮想環境が含まれます。
  • Dockerfile:(省略可能) カスタム コンテナーでプロジェクトを発行するときに使用されます。
  • tests/ :(省略可能) 関数アプリのテスト ケースが含まれます。
  • .funcignore:(省略可能) Azure に発行しないファイルを宣言します。 通常、このファイルには、エディター設定を無視する場合は .vscode/、ローカルの Python 仮想環境を無視する場合は .venv/、テスト ケースを無視する場合は tests/、ローカル アプリの設定を発行しない場合は local.settings.json が含まれます。

各関数には、独自のコード ファイルとバインディング構成ファイル (function.json) があります。

Azure の関数アプリにプロジェクトをデプロイする場合は、メイン プロジェクト ( <project_root> ) フォルダーの内容全体をパッケージに含める必要がありますが、フォルダー自体は含めないでください。つまり、host.json はパッケージ ルートに存在する必要があります。 テストは、他の関数と一緒に 1 つのフォルダーに保存することをお勧めします (この例では tests/)。 詳細については、「単体テスト」を参照してください。

インポートの動作

絶対と相対の各参照の両方を使用して、関数コードにモジュールをインポートすることができます。 次のインポートは、上記のフォルダー構造に基づいて、関数ファイル <project_root>\my_first_function\__init__.py 内から機能します。

from shared_code import my_first_helper_function #(absolute)
import shared_code.my_second_helper_function #(absolute)
from . import example #(relative)

注意

shared_code/ フォルダーには、絶対インポート構文を使用するときに Python パッケージとしてマークするための __init__.py ファイルが含まれている必要があります。

次の __app__ インポートおよび最上位を超える相対インポートは、静的な型チェッカーでサポートされておらず、Python テスト フレームワークでサポートされていないため非推奨です。

from __app__.shared_code import my_first_helper_function #(deprecated __app__ import)
from ..shared_code import my_first_helper_function #(deprecated beyond top-level relative import)

トリガーと入力

Azure Functions では、入力はトリガー入力とその他の入力の 2 つのカテゴリに分けられます。 function.json ファイルではこれらは同じではありませんが、Python コードでは同じように使用されます。 トリガーの接続文字列またはシークレットと入力ソースは、ローカル実行時には local.settings.json ファイル内の値にマップし、Azure での実行時にはアプリケーションの設定にマップします。

たとえば、次のコードでは 2 つの違いが示されています。

// function.json
{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "name": "req",
      "direction": "in",
      "type": "httpTrigger",
      "authLevel": "anonymous",
      "route": "items/{id}"
    },
    {
      "name": "obj",
      "direction": "in",
      "type": "blob",
      "path": "samples/{id}",
      "connection": "AzureWebJobsStorage"
    }
  ]
}
// local.settings.json
{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "AzureWebJobsStorage": "<azure-storage-connection-string>"
  }
}
# __init__.py
import azure.functions as func
import logging


def main(req: func.HttpRequest,
         obj: func.InputStream):

    logging.info(f'Python HTTP triggered function processed: {obj.read()}')

この関数が呼び出されると、HTTP 要求は req として関数に渡されます。 エントリは、ルート URL 内の ID に基づいて Azure Blob Storage から取得され、関数の本体で obj として使用できるようになります。 ここで、指定されるストレージ アカウントは、AzureWebJobsStorage アプリ設定で見つかる接続文字列であり、関数アプリケーションで使用されるストレージ アカウントと同じものです。

出力

出力は、戻り値および出力パラメーターの両方で表現できます。 出力が 1 つのみの場合は、戻り値の使用をお勧めします。 出力が複数の場合は、出力パラメーターを使用する必要があります。

出力バインディングの値として関数の戻り値を使用するには、バインディングの name プロパティを function.json 内の $return に設定する必要があります。

複数の出力を生成するには、azure.functions.Out インターフェイスによって提供される set() メソッドを使用して、バインディングに値を割り当てます。 たとえば、次の関数を使用すると、キューにメッセージをプッシュすることに加え、HTTP 応答を返すこともできます。

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "name": "req",
      "direction": "in",
      "type": "httpTrigger",
      "authLevel": "anonymous"
    },
    {
      "name": "msg",
      "direction": "out",
      "type": "queue",
      "queueName": "outqueue",
      "connection": "AzureWebJobsStorage"
    },
    {
      "name": "$return",
      "direction": "out",
      "type": "http"
    }
  ]
}
import azure.functions as func


def main(req: func.HttpRequest,
         msg: func.Out[func.QueueMessage]) -> str:

    message = req.params.get('body')
    msg.set(message)
    return message

ログ記録

Azure Functions ランタイム ロガーへのアクセスは、ご利用の関数アプリ内のルート logging ハンドラーを介して利用できます。 このロガーは Application Insights に関連付けられているため、関数の実行中に発生する警告とエラーにフラグを設定することができます。

次の例では、HTTP トリガーを介して関数が呼び出されるときに、情報メッセージが記録されます。

import logging


def main(req):
    logging.info('Python HTTP trigger function processed a request.')

他にも次のようなログ記録メソッドが用意されています。これにより、さまざまなトレース レベルでコンソールへの書き込みが可能になります。

方法 説明
critical(_message_) ルート ロガー上に CRITICAL レベルのメッセージを書き込みます。
error(_message_) ルート ロガー上に ERROR レベルのメッセージを書き込みます。
warning(_message_) ルート ロガー上に WARNING レベルのメッセージを書き込みます。
info(_message_) ルート ロガー上に INFO レベルのメッセージを書き込みます。
debug(_message_) ルート ロガー上に DEBUG レベルのメッセージを書き込みます。

ログ記録の詳細については、「Azure Functions を監視する」を参照してください。

カスタム テレメトリをログに記録する

既定では、Functions ランタイムには、関数によって生成されたログとその他のテレメトリ データが収集されます。 このテレメトリは、Application インサイト のトレースとして終了します。 特定の Azure サービスの要求と依存関係のテレメトリは、既定でトリガーおよびバインディングでも収集されます。 バインディングによらずにカスタム要求およびカスタムの依存関係テレメトリを収集する目的で、OpenCensus Python Extensions を使用して、カスタム テレメトリ データを Application Insights インスタンスに送信することができます。 サポートされている拡張機能の一覧は、OpenCensus リポジトリで確認できます。

注意

OpenCensus Python 拡張機能を使用するには、アプリケーション設定PYTHON_ENABLE_WORKER_EXTENSIONS1 に設定して、関数アプリの Python 拡張機能を有効にする必要があります。

// requirements.txt
...
opencensus-extension-azure-functions
opencensus-ext-requests
import json
import logging

import requests
from opencensus.extension.azure.functions import OpenCensusExtension
from opencensus.trace import config_integration

config_integration.trace_integrations(['requests'])

OpenCensusExtension.configure()

def main(req, context):
    logging.info('Executing HttpTrigger with OpenCensus extension')

    # You must use context.tracer to create spans
    with context.tracer.span("parent"):
        response = requests.get(url='http://example.com')

    return json.dumps({
        'method': req.method,
        'response': response.status_code,
        'ctx_func_name': context.function_name,
        'ctx_func_dir': context.function_directory,
        'ctx_invocation_id': context.invocation_id,
        'ctx_trace_context_Traceparent': context.trace_context.Traceparent,
        'ctx_trace_context_Tracestate': context.trace_context.Tracestate,
        'ctx_retry_context_RetryCount': context.retry_context.retry_count,
        'ctx_retry_context_MaxRetryCount': context.retry_context.max_retry_count,
    })

HTTP トリガーとバインディング

HTTP トリガーは function.json ファイルで定義されています。 バインディングの name は、関数の名前付きパラメーターと一致している必要があります。 前の例では、バインド名 req が使用されています。 このパラメーターは HttpRequest オブジェクトであり、HttpResponse オブジェクトが返されます。

HttpRequest オブジェクトからは、要求ヘッダー、クエリ パラメーター、ルート パラメーター、およびメッセージ本文を取得できます。

次の例は、Python 用の HTTP トリガー テンプレートからのものです。

def main(req: func.HttpRequest) -> func.HttpResponse:
    headers = {"my-http-header": "some-value"}

    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}!", headers=headers)
    else:
        return func.HttpResponse(
             "Please pass a name on the query string or in the request body",
             headers=headers, status_code=400
        )

この関数では、name クエリ パラメーターの値は HttpRequest オブジェクトの params パラメーターから取得されます。 JSON でエンコードされたメッセージ本文は get_json メソッドを使用して読み取られます。

同様に、返される HttpResponse オブジェクトに応答メッセージの status_code および headers を設定できます。

スケーリングとパフォーマンス

Python 関数アプリのスケーリングとパフォーマンスのベスト プラクティスについては、Python のスケーリングとパフォーマンスに関する記事を参照してください。

Context

実行中に関数の呼び出しコンテキストを取得するには、そのシグニチャに context 引数を含めます。

次に例を示します。

import azure.functions


def main(req: azure.functions.HttpRequest,
         context: azure.functions.Context) -> str:
    return f'{context.invocation_id}'

コンテキスト クラスには次の文字列属性が含まれています。

function_directory 関数が実行されるディレクトリです。

function_name 関数の名前です。

invocation_id 現在の関数呼び出しの ID です。

trace_context 分散トレース用のコンテキスト。 詳細については、Trace Context をご覧ください。

retry_context 関数への再試行のコンテキスト。 詳細については、「retry-policies」を参照してください。

グローバル変数

将来の実行に対してアプリの状態が保持されることは保証されません。 ただし、Azure Functions ランタイムでは、多くの場合、同じアプリの複数の実行に対して同じプロセスが再利用されます。 高コストの計算の結果をキャッシュするには、グローバル変数として宣言します。

CACHED_DATA = None


def main(req):
    global CACHED_DATA
    if CACHED_DATA is None:
        CACHED_DATA = load_json()

    # ... use CACHED_DATA in code

環境変数

Functions では、サービス接続文字列などのアプリケーション設定は、実行中に環境変数として公開されます。 コードでこれらの設定にアクセスするには、主に 2 つの方法があります。

Method 説明
os.environ["myAppSetting"] アプリケーション設定をキー名で取得しようとして失敗した場合はエラーを発生させます。
os.getenv("myAppSetting") アプリケーション設定をキー名で取得しようとして失敗した場合は null を返します。

どちらの方法も、import os を宣言する必要があります。

次の設定では、os.environ["myAppSetting"] を使用して myAppSetting という名前のキーのアプリケーション設定が取得されます。

import logging
import os
import azure.functions as func

def main(req: func.HttpRequest) -> func.HttpResponse:

    # Get the setting named 'myAppSetting'
    my_app_setting_value = os.environ["myAppSetting"]
    logging.info(f'My app setting value:{my_app_setting_value}')

ローカル開発の場合、アプリケーション設定は local.settings.json ファイルに保持されます

Python バージョン

Azure Functions では次の Python バージョンがサポートされています。

Functions バージョン Python* バージョン
4.x 3.9
3.8
3.7
3.x 3.9
3.8
3.7
3.6
2.x 3.7
3.6

*公式 CPython ディストリビューション

Azure で関数アプリを作成するときに特定の Python バージョンを要求するには、az functionapp create コマンドの --runtime-version オプションを使用します。 Functions ランタイム バージョンは --functions-version オプションによって設定されます。 Python バージョンは関数アプリの作成時に設定され、変更できません。

ローカルで実行する場合、ランタイムは使用可能な Python バージョンを使用します。

Python バージョンの変更

Python 関数アプリを特定の言語バージョンに設定するには、サイトの構成の LinuxFxVersion フィールドで言語と言語のバージョンを指定する必要があります。たとえば、Python 3.8 を使用するように Python アプリを変更するには、linuxFxVersionpython|3.8 に設定します。

Azure Functions のランタイム サポート ポリシーの詳細については、こちらの記事を参照してください。

サポートされている Python バージョンの関数アプリの詳細な一覧については、こちらの記事を参照してください。

Azure CLI から linuxFxVersion を表示および設定することができます。

Azure CLI を使用して、az functionapp config show コマンドにより現在の linuxFxVersion を表示します。

az functionapp config show --name <function_app> \
--resource-group <my_resource_group>

このコードでは、<function_app> をお使いの関数アプリの名前に置き換えます。 また、<my_resource_group> をお使いの関数アプリのリソース グループの名前に置き換えます。

明確にするために切り捨てられていますが、次の出力に linuxFxVersion が表示されます。

{
  ...
  "kind": null,
  "limits": null,
  "linuxFxVersion": <LINUX_FX_VERSION>,
  "loadBalancing": "LeastRequests",
  "localMySqlEnabled": false,
  "location": "West US",
  "logsDirectorySizeLimit": 35,
   ...
}

az functionapp config set コマンドを使用して、関数アプリの linuxFxVersion の設定を更新できます。

az functionapp config set --name <FUNCTION_APP> \
--resource-group <RESOURCE_GROUP> \
--linux-fx-version <LINUX_FX_VERSION>

<FUNCTION_APP> をお使いの関数アプリの名前に置き換えます。 また、<RESOURCE_GROUP> をお使いの関数アプリのリソース グループの名前に置き換えます。 さらに、使用する Python バージョンで <LINUX_FX_VERSION> を置き換えて、先頭に python| を付けます (たとえば、python|3.9 のようになります)。

このコマンドは、上記のコード サンプルの [テスト] をクリックすることで、Azure Cloud Shell から実行できます。 また、Azure CLI をローカルに使用して、az ログインを実行してサインインした後に、このコマンドを実行することもできます。

サイト構成に変更が加えられると、関数アプリが再起動されます。

パッケージの管理

Azure Functions Core Tools または Visual Studio Code を使用してローカルで開発を行う場合は、必要なパッケージの名前とバージョンを requirements.txt ファイルに追加し、pip を使用してそれらをインストールしてください。

たとえば、次の要件のファイルと pip コマンドを使用すれば、PyPI から requests パッケージをインストールすることができます。

requests==2.19.1
pip install -r requirements.txt

Azure への発行

発行する準備ができたら、一般公開されているすべての依存関係が、プロジェクト ディレクトリのルートにある requirements.txt ファイルに一覧表示されていることを確認します。

発行から除外されたプロジェクト ファイルとフォルダー (仮想環境フォルダーなど) は、.funcignore ファイルに一覧表示されます。

Python プロジェクトを Azure に発行するために、リモート ビルド、ローカル ビルド、およびカスタム依存関係を使用したビルドの 3 つのビルド アクションがサポートされています。

Azure Pipelines を使用して依存関係をビルドし、継続的デリバリー (CD) を使用して発行することもできます。 詳細については、「Azure DevOps を使用した継続的デリバリー」を参照してください。

リモート ビルド

リモート ビルドを使用する場合、サーバー上に復元された依存関係とネイティブの依存関係は運用環境と一致します。 これにより、アップロードするデプロイ パッケージが小さくなります。 Windows 上で Python アプリを開発する場合は、リモート ビルドを使用します。 プロジェクトにカスタム依存関係がある場合は、追加のインデックスの URL を使用するリモート ビルドを使用することができます。

依存関係は、requirements.txt ファイルの内容に基づいてリモートで取得されます。 リモート ビルド は推奨されるビルド方法です。 次の func azure functionapp publish コマンドを使用して Python プロジェクトを Azure に発行すると、既定では Azure Functions Core Tools によってリモート ビルドが要求されます。

func azure functionapp publish <APP_NAME>

<APP_NAME> を、Azure 内のご自分の関数アプリの名前に置き換えることを忘れないでください。

Visual Studio Code の Azure Functions 拡張機能も、既定ではリモート ビルドを要求します。

ローカル ビルド

依存関係は、requirements.txt ファイルの内容に基づいてローカルで取得されます。 次の func azure functionapp publish コマンドを使用してローカル ビルドとして発行することで、リモート ビルドを実行しないようにすることができます。

func azure functionapp publish <APP_NAME> --build local

<APP_NAME> を、Azure 内のご自分の関数アプリの名前に置き換えることを忘れないでください。

--build local オプションを使用すると、プロジェクトの依存関係が requirements.txt ファイルから読み取られ、これらの依存パッケージがローカルにダウンロードされ、インストールされます。 プロジェクト ファイルと依存関係は、ローカル コンピューターから Azure にデプロイされます。 これにより、大きいサイズのデプロイ パッケージが Azure にアップロードされます。 何らかの理由で、コア ツールが requirements.txt ファイルの依存関係を取得できない場合は、発行に際して [custom dependencies](カスタムの依存関係) オプションを使用する必要があります。

Windows でローカルに開発する場合は、ローカル ビルドの使用をお勧めしません。

カスタムの依存関係

Python パッケージ インデックスにない依存関係がプロジェクトにある場合、2 つの方法でプロジェクトをビルドすることができます。 ビルド方法は、プロジェクトのビルド方法によって異なります。

追加のインデックスの URL を使用するリモート ビルド

アクセス可能なカスタム パッケージ インデックスからパッケージを取得できる場合は、リモート ビルドを使用します。 発行する前に、必ず、PIP_EXTRA_INDEX_URL という名前のアプリ設定を作成してください。 この設定の値は、カスタム パッケージ インデックスの URL です。 この設定は、リモート ビルドで --extra-index-url オプションを使用して pip install を実行することを指示するために使用します。 詳細については、Python の pip install に関するドキュメントを参照してください。

また、基本認証の資格情報を追加のパッケージ インデックスの URL と共に使用することもできます。 詳細については、Python ドキュメントの「基本認証の資格情報」を参照してください。

ローカル パッケージをインストールする

ツールで公開されていないパッケージをプロジェクトに使用している場合は、それを __app__/.python_packages ディレクトリに配置することで、アプリで使用可能にすることができます。 発行する前に次のコマンドを実行して、依存関係をローカルでインストールします。

pip install  --target="<PROJECT_DIR>/.python_packages/lib/site-packages"  -r requirements.txt

カスタムの依存関係を使用する場合は、既に依存関係がプロジェクト フォルダーにインストールされているため、--no-build 発行オプションを使用する必要があります。

func azure functionapp publish <APP_NAME> --no-build

<APP_NAME> を、Azure 内のご自分の関数アプリの名前に置き換えることを忘れないでください。

単体テスト

Python で記述された関数は、標準的なテスト フレームワークを使用して、他の Python コードのようにテストできます。 ほとんどのバインドでは、azure.functions パッケージから適切なクラスのインスタンスを作成することにより、モック入力オブジェクトを作成できます。 azure.functions パッケージはすぐには利用できないため、上記の「パッケージ管理」セクションの説明に従って、requirements.txt ファイルを使用してインストールしてください。

my_second_function を例にとると、次に示すのは、HTTP によってトリガーされる関数のモック テストです。

最初に、 <project_root>/my_second_function/function.json ファイルを作成し、この関数を http トリガーとして定義する必要があります。

{
  "scriptFile": "__init__.py",
  "entryPoint": "main",
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
  ]
}

これで、my_second_functionshared_code.my_second_helper_function を実装できます。

# <project_root>/my_second_function/__init__.py
import azure.functions as func
import logging

# Use absolute import to resolve shared_code modules
from shared_code import my_second_helper_function

# Define an http trigger which accepts ?value=<int> query parameter
# Double the value and return the result in HttpResponse
def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Executing my_second_function.')

    initial_value: int = int(req.params.get('value'))
    doubled_value: int = my_second_helper_function.double(initial_value)

    return func.HttpResponse(
      body=f"{initial_value} * 2 = {doubled_value}",
      status_code=200
    )
# <project_root>/shared_code/__init__.py
# Empty __init__.py file marks shared_code folder as a Python package
# <project_root>/shared_code/my_second_helper_function.py

def double(value: int) -> int:
  return value * 2

http トリガーのテスト ケースの記述を開始できます。

# <project_root>/tests/test_my_second_function.py
import unittest

import azure.functions as func
from my_second_function import main

class TestFunction(unittest.TestCase):
    def test_my_second_function(self):
        # Construct a mock HTTP request.
        req = func.HttpRequest(
            method='GET',
            body=None,
            url='/api/my_second_function',
            params={'value': '21'})

        # Call the function.
        resp = main(req)

        # Check the output.
        self.assertEqual(
            resp.get_body(),
            b'21 * 2 = 42',
        )

.venv の Python 仮想環境内で、任意の Python テスト フレームワーク (pip install pytest など) をインストールします。 続いて pytest tests を実行して、テスト結果を確認します。

一時ファイル

tempfile.gettempdir() メソッドは一時フォルダーを返します。Linux では /tmp です。 アプリケーションは、実行中に関数が生成および使用する一時ファイルを格納するためにこのディレクトリを使用できます。

重要

一時ディレクトリに書き込まれるファイルは、呼び出しをまたいで保持されることは保証されません。 スケールアウトの間、一時ファイルはインスタンス間で共有されません。

次の例では、名前付きの一時ファイルを一時ディレクトリ (/tmp) に作成します。

import logging
import azure.functions as func
import tempfile
from os import listdir

#---
   tempFilePath = tempfile.gettempdir()
   fp = tempfile.NamedTemporaryFile()
   fp.write(b'Hello world!')
   filesDirListInTemp = listdir(tempFilePath)

テストは、プロジェクト フォルダーとは別のフォルダーに保存することをお勧めします。 これにより、アプリでテスト コードをデプロイすることを防ぐことができます。

プレインストール済みライブラリ

Python Functions ランタイムには、いくつかのライブラリが付属しています。

Python 標準ライブラリ

Python 標準ライブラリには、各 Python ディストリビューションに同梱されている組み込み Python モジュールの一覧が含まれています。 これらのライブラリのほとんどは、ファイル I/O などのシステム機能へのアクセスに役立ちます。 Windows システムでは、これらのライブラリは Python と共にインストールされます。 Unix ベースのシステムでは、これらはパッケージ コレクションによって提供されます。

これらのライブラリの一覧の完全な詳細については、次のリンク先を参照してください。

Azure Functions Python worker の依存関係

Functions Python worker は、特定のライブラリ セットを必要とします。 これらのライブラリは、関数内で使用することもできますが、Python 標準の一部ではありません。 対象の関数がこれらのライブラリのいずれかに依存している場合、Azure Functions の外部で実行したときにコードでそれらのライブラリを使用できない場合があります。 依存関係の詳細な一覧は、setup.py ファイルの install_requires セクションで確認できます。

注意

関数アプリの requirements.txt に azure-functions-worker エントリが含まれている場合は、それを削除します。 Functions worker は Azure Functions プラットフォームによって自動的に管理され、新しい機能とバグの修正のための更新が定期的に行われます。 古いバージョンの worker を requirements.txt に手動で組み込むと、予期しない問題が発生する可能性があります。

注意

ワーカーの依存関係と競合する可能性がある特定のライブラリ (protobuf、tensorflow、grpcio など) がパッケージに含まれている場合は、アプリの設定で PYTHON_ISOLATE_WORKER_DEPENDENCIES1 に設定して、アプリケーションでワーカーの依存関係を参照しないようにしてください。 この機能はプレビュー段階にあります。

Azure Functions Python ライブラリ

すべての Python worker の更新プログラムには、新しいバージョンの Azure Functions Python ライブラリ (azure.functions) が含まれています。 各更新プログラムには下位互換性があるため、これで簡単に Python 関数アプリを継続的に更新できるようになります。 このライブラリのリリースの一覧は、azure-functions PyPi で確認できます。

ランタイム ライブラリのバージョンは Azure によって修正され、requirements.txt で上書きすることはできません。 requirements.txt の azure-functions エントリは、リンティングと顧客意識のためだけに用意されています。

対象のランタイムの Python Functions ライブラリの実際のバージョンを追跡するには、次のコードを使用します。

getattr(azure.functions, '__version__', '< 1.2.1')

ランタイム システム ライブラリ

Python worker の Docker イメージにプレインストールされているシステム ライブラリの一覧については、次のリンク先を参照してください。

Functions ランタイム Debian のバージョン Python のバージョン
バージョン 2.x Stretch Python 3.6
Python 3.7
バージョン 3.x Buster Python 3.6
Python 3.7
Python 3.8
Python 3.9

Python worker 拡張機能

Azure Functions で実行される Python worker プロセスを使用すると、サードパーティ製ライブラリを関数アプリに統合できます。 これらの拡張ライブラリは、関数の実行のライフサイクル中に特定の操作を挿入できるミドルウェアとして機能します。

これらの拡張機能は、標準の Python ライブラリ モジュールと同様に関数コードにインポートされます。 拡張機能は、次のスコープに基づいて実行されます。

Scope 説明
アプリケーション レベル 関数トリガーにインポートされると、拡張機能はアプリ内のすべての関数実行に適用されます。
関数レベル インポート先の特定の関数トリガーにのみ実行が制限されます。

特定の拡張機能に関する情報を参照して、拡張機能が実行されるスコープの詳細を確認してください。

拡張機能は、Python worker プロセスが関数実行のライフサイクル中に拡張機能コードを呼び出せるようにする Python worker 拡張機能インターフェイスを実装します。 詳細については、「拡張機能の作成」を参照してください。

拡張機能の使用

お使いの Python 関数で Python worker 拡張機能ライブラリを使用するには、次の基本的な手順を実行します。

  1. 拡張機能パッケージをプロジェクトの requirements.txt ファイルに追加します。
  2. ライブラリをアプリにインストールします。
  3. アプリケーション設定 PYTHON_ENABLE_WORKER_EXTENSIONS を以下のとおり追加します。
  4. 関数トリガーに拡張機能モジュールをインポートします。
  5. 必要に応じて、拡張機能インスタンスを構成します。 構成要件は、拡張機能のドキュメントに明記されているはずです。

重要

サード パーティ製の Python worker 拡張機能ライブラリについては、Microsoft はサポートも保証もしていません。 関数アプリで使用する拡張機能が信頼できることを確認する必要があります。悪意のある、または適切に作成されていない拡張機能を使用するリスクはすべてお客様が負うこととなります。

サードパーティは、関数アプリに特定の拡張機能をインストールして使用する方法に関する具体的なドキュメントを提供する必要があります。 拡張機能の使用方法の基本的な例については、拡張機能の使用に関するページを参照してください。

以下に、関数アプリで拡張機能を使用する例をスコープ別に示します。

# <project_root>/requirements.txt
application-level-extension==1.0.0
# <project_root>/Trigger/__init__.py

from application_level_extension import AppExtension
AppExtension.configure(key=value)

def main(req, context):
  # Use context.app_ext_attributes here

拡張機能の作成

拡張機能は、Azure Functions に統合可能な機能を作成したサードパーティ製ライブラリの開発者によって作成されます。 拡張機能の開発者は、関数実行のコンテキストで実行されるように特別に設計されたカスタム ロジックを含む Python パッケージを設計、実装、リリースします。 これらの拡張機能は、PyPI レジストリまたは GitHub リポジトリに発行できます。

Python worker 拡張機能パッケージを作成、パッケージ化、発行、使用する方法については、「Azure Functions 用の Python worker 拡張機能の開発」を参照してください。

アプリケーション レベルの拡張機能

AppExtensionBase から継承された拡張機能は、"アプリケーション" スコープで実行されます。

AppExtensionBase は、実装のための次の抽象クラス メソッドを公開します。

方法 説明
init 拡張機能がインポートされた後に呼び出されます。
configure 拡張機能を構成する必要がある場合に、関数コードから呼び出されます。
post_function_load_app_level 関数が読み込まれた直後に呼び出されます。 関数名と関数ディレクトリが拡張機能に渡されます。 関数ディレクトリは読み取り専用であり、このディレクトリ内のローカル ファイルに書き込もうとしても失敗することに注意してください。
pre_invocation_app_level 関数がトリガーされる直前に呼び出されます。 関数コンテキストと関数呼び出しの引数が、拡張機能に渡されます。 通常、他の属性をコンテキスト オブジェクトで渡して、関数コードで使用することができます。
post_invocation_app_level 関数の実行が完了した直後に呼び出されます。 関数コンテキスト、関数呼び出しの引数、呼び出しの戻りオブジェクトが拡張機能に渡されます。 これは、ライフサイクル フックの実行が成功したかどうかを検証するのに適した実装です。

関数レベルの拡張機能

FuncExtensionBase から継承された拡張機能は、特定の関数トリガーで実行されます。

FuncExtensionBase は、実装のための次の抽象クラス メソッドを公開します。

方法 説明
__init__ このメソッドは、拡張機能のコンストラクターです。 これは、拡張機能インスタンスが特定の関数で初期化されると呼び出されます。 この抽象メソッドを実装する際、適切な拡張機能登録のために、filename パラメーターを受け入れて、親のメソッド super().__init__(filename) に渡すことが必要になる場合があります。
post_function_load 関数が読み込まれた直後に呼び出されます。 関数名と関数ディレクトリが拡張機能に渡されます。 関数ディレクトリは読み取り専用であり、このディレクトリ内のローカル ファイルに書き込もうとしても失敗することに注意してください。
pre_invocation 関数がトリガーされる直前に呼び出されます。 関数コンテキストと関数呼び出しの引数が、拡張機能に渡されます。 通常、他の属性をコンテキスト オブジェクトで渡して、関数コードで使用することができます。
post_invocation 関数の実行が完了した直後に呼び出されます。 関数コンテキスト、関数呼び出しの引数、呼び出しの戻りオブジェクトが拡張機能に渡されます。 これは、ライフサイクル フックの実行が成功したかどうかを検証するのに適した実装です。

クロス オリジン リソース共有

Azure Functions では、クロス オリジン リソース共有 (CORS) がサポートされています。 CORS はポータル内でAzure CLI によって構成されます。 CORS の許可配信元一覧は、関数アプリ レベルで適用されます。 CORS を有効にすると、応答に Access-Control-Allow-Origin ヘッダーが含まれます。 詳細については、「 クロス オリジン リソース共有」を参照してください。

CORS は、Python 関数アプリでは完全にサポートされています。

既知の問題とよくあるご質問

一般的な問題のトラブルシューティング ガイドの一覧を次に示します。

既知の問題と機能に関する要望はすべて、GitHub issues リストを使用して追跡されます。 問題が発生してその問題が GitHub で見つからない場合は、新しい Issue を開き、その問題の詳細な説明を記載してお知らせください。

次のステップ

詳細については、次のリソースを参照してください。

問題がある場合は、お知らせください。