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

この記事では、Python を使用した Azure Functions の開発について紹介します。This article is an introduction to developing Azure Functions using Python. 以下の内容は、「Azure Functions の開発者向けガイド」を既に読んでいることを前提としています。The content below assumes that you've already read the Azure Functions developers guide.

注意

Python 用の Azure Functions は現在プレビュー段階です。Python for Azure Functions is currently in preview. 重要な更新プログラムを受け取るために、GitHub 上で Azure App Service のお知らせリポジトリをサブスクライブしてください。To receive important updates, subscribe to the Azure App Service announcements repository on GitHub.

プログラミング モデルProgramming model

Azure 関数は、入力を処理して出力を生成する Python スクリプト内でステートレスなメソッドである必要があります。An Azure Function should be a stateless method in your Python script that processes input and produces output. 既定で、ランタイムでは、これは main() と呼ばれるグローバル メソッドとして __init__.py ファイル内に実装されると想定されます。By default, the runtime expects this to be implemented as a global method called main() in the __init__.py file.

function.json ファイル内で scriptFile プロパティと entryPoint プロパティを指定すれば、既定の構成を変更することができます。You can change the default configuration by specifying the scriptFile and entryPoint properties in the function.json file. たとえば、以下の function.json では、ご利用の Azure 関数のエントリ ポイントとして、main.py ファイル内の customentry() メソッドを使用するようにランタイムに指示が出されます。For example, the function.json below tells the runtime to use the customentry() method in the main.py file, as the entry point for your Azure Function.

{
  "scriptFile": "main.py",
  "entryPoint": "customentry",
  ...
}

トリガーとバインディングからのデータをメソッド属性を介して関数にバインドするには、function.json 構成ファイル内に定義されている name プロパティを使用します。Data from triggers and bindings is bound to the function via method attributes using the name property defined in the function.json configuration file. たとえば、次の function.json には、req という名前の HTTP 要求によってトリガーされるシンプルな関数が記述されています。For example,the function.json below describes a simple function triggered by an HTTP request named req:

{
  "bindings": [
    {
      "name": "req",
      "direction": "in",
      "type": "httpTrigger",
      "authLevel": "anonymous"
    },
    {
      "name": "$return",
      "direction": "out",
      "type": "http"
    }
  ]
}

__init__.py ファイルには、次の関数コードが含まれています。The __init__.py file contains the following function code:

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

必要があれば、Python の型の注釈を使用することで、関数内にパラメーターの型および戻り値の型を宣言することもできます。Optionally, you can also declare the parameter types and return type in the function using Python type annotations. たとえば、次のように注釈を使用して同じ関数を記述することができます。For example, the same function can be written using annotations, as follows:

import azure.functions

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

azure.functions.* パッケージに含まれる Python の注釈を使用すると、入力と出力がご利用のメソッドにバインドされます。Use the Python annotations included in the azure.functions.* package to bind input and outputs to your methods.

フォルダー構造Folder structure

Python 関数プロジェクトのフォルダー構造は、次のようになります。The folder structure for a Python Functions project looks like the following:

 FunctionApp
 | - MyFirstFunction
 | | - __init__.py
 | | - function.json
 | - MySecondFunction
 | | - __init__.py
 | | - function.json
 | - SharedCode
 | | - myFirstHelperFunction.py
 | | - mySecondHelperFunction.py
 | - host.json
 | - requirements.txt
 | - extensions.csproj
 | - bin

関数アプリの構成に使用できる共有 host.json ファイルがあります。There's a shared host.json file that can be used to configure the function app. 各関数には、独自のコード ファイルとバインディング構成ファイル (function.json) があります。Each function has its own code file and binding configuration file (function.json).

共有コードは、別のフォルダーに保存する必要があります。Shared code should be kept in a separate folder. SharedCode フォルダー内のモジュールを参照するには、次の構文を使用します。To reference modules in the SharedCode folder, you can use the following syntax:

from ..SharedCode import myFirstHelperFunction

Functions ランタイムで使用されるバインディング拡張機能は、extensions.csproj ファイル内に定義されており、実際のライブラリ ファイルは bin フォルダー内にあります。Binding extensions used by the Functions runtime are defined in the extensions.csproj file, with the actual library files in the bin folder. ローカルで開発する場合は、Azure Functions Core Tools を使用して、バインディング拡張機能を登録する必要があります。When developing locally, you must register binding extensions using Azure Functions Core Tools.

Functions プロジェクトを Azure 内のご利用の関数アプリにデプロイする場合は、フォルダー自体ではなく、パッケージに FunctionApp フォルダーの内容全体を含める必要があります。When deploying a Functions project to your function app in Azure, the entire content of the FunctionApp folder should be included in the package, but not the folder itself.

入力Inputs

Azure Functions では、入力はトリガー入力と追加入力の 2 つのカテゴリに分けられます。Inputs are divided into two categories in Azure Functions: trigger input and additional input. function.json ではこれらは同じではありませんが、Python コードでは同じように使用されます。Although they are different in function.json, the usage is identical in Python code. 次のコード スニペットを例として使用します。Let's take the following code snippet as an example:

{
  "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"
    }
  ]
}
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 として関数に渡されます。When the function is invoked, the HTTP request is passed to the function as req. エントリは、ルート URL 内の id に基づいて Azure Blob Storage から取得され、関数の本体で obj として使用できるようになります。An entry will be retrieved from the Azure Blob Storage based on the id in the route URL and made available as obj in the function body.

出力Outputs

出力は、戻り値および出力パラメーターの両方で表現できます。Output can be expressed both in return value and output parameters. 出力が 1 つのみの場合は、戻り値の使用をお勧めします。If there's only one output, we recommend using the return value. 出力が複数の場合は、出力パラメーターを使用する必要があります。For multiple outputs, you'll have to use output parameters.

出力バインディングの値として関数の戻り値を使用するには、バインディングの name プロパティを function.json 内の $return に設定する必要があります。To use the return value of a function as the value of an output binding, the name property of the binding should be set to $return in function.json.

複数の出力を生成するには、azure.functions.Out インターフェイスによって提供される set() メソッドを使用して、バインディングに値を割り当てます。To produce multiple outputs, use the set() method provided by the azure.functions.Out interface to assign a value to the binding. たとえば、次の関数を使用すると、キューにメッセージをプッシュすることに加え、HTTP 応答を返すこともできます。For example, the following function can push a message to a queue and also return an HTTP response.

{
  "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

ログの記録Logging

Azure Functions ランタイム ロガーへのアクセスは、ご利用の関数アプリ内のルート logging ハンドラーを介して利用できます。Access to the Azure Functions runtime logger is available via a root logging handler in your function app. このロガーは Application Insights に関連付けられているため、関数の実行中に検出される警告とエラーにフラグを設定することができます。This logger is tied to Application Insights and allows you to flag warnings and errors encountered during the function execution.

次の例では、HTTP トリガーを介して関数が呼び出されるときに、情報メッセージが記録されます。The following example logs an info message when the function is invoked via an HTTP trigger.

import logging

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

他にもログ記録メソッドが用意されています。これにより、さまざまなトレース レベルでコンソールへの書き込みが可能になります。Additional logging methods are available that let you write to the console at different trace levels:

方法Method 説明Description
logging.critical(message)logging.critical(message) ルート ロガー上に CRITICAL レベルのメッセージを書き込みます。Writes a message with level CRITICAL on the root logger.
logging.error(message)logging.error(message) ルート ロガー上に ERROR レベルのメッセージを書き込みます。Writes a message with level ERROR on the root logger.
logging.warning(message)logging.warning(message) ルート ロガー上に WARNING レベルのメッセージを書き込みます。Writes a message with level WARNING on the root logger.
logging.info(message)logging.info(message) ルート ロガー上に INFO レベルのメッセージを書き込みます。Writes a message with level INFO on the root logger.
logging.debug(message)logging.debug(message) ルート ロガー上に DEBUG レベルのメッセージを書き込みます。Writes a message with level DEBUG on the root logger.

関数モジュールへの共有コードのインポートImporting shared code into a function module

関数モジュールと共に発行する Python モジュールは、相対インポート構文を使用してインポートする必要があります。Python modules published alongside function modules must be imported using the relative import syntax:

from . import helpers  # Use more dots to navigate up the folder structure.
def main(req: func.HttpRequest):
    helpers.process_http_request(req)

あるいは、共有コードをスタンドアロン パッケージに配置し、それをパブリックまたはプライベートの PyPI インスタンスに発行して、通常の依存関係として指定します。Alternatively, put shared code into a standalone package, publish it to a public or a private PyPI instance, and specify it as a regular dependency.

非同期Async

1 つの関数アプリに付き、1 つの Python プロセスしか存在することができないので、async def ステートメントを使用してご自分の Azure 関数を非同期コルーチンとして実装することをお勧めします。Since only a single Python process can exist per function app, it is recommended to implement your Azure Function as an asynchronous coroutine using the async def statement.

# Will be run with asyncio directly
async def main():
    await some_nonblocking_socket_io_op()

main() 関数が同期 (async 修飾子が付いていない) の場合、それは asyncio スレッド プール内で自動的に実行されます。If the main() function is synchronous (no async qualifier) we automatically run it in an asyncio thread-pool.

# Would be run in an asyncio thread-pool
def main():
    some_blocking_socket_io()

ContextContext

実行中に関数の呼び出しコンテキストを取得するには、そのシグニチャに context 引数を含めます。To get the invocation context of a function during execution, include the context argument in its signature.

例: For example:

import azure.functions

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

コンテキスト クラスには次のメソッドが含まれています。The Context class has the following methods:

function_directory
関数が実行されるディレクトリです。The directory in which the function is running.

function_name
関数の名前です。Name of the function.

invocation_id
現在の関数呼び出しの ID です。ID of the current function invocation.

Python のバージョンとパッケージの管理Python version and package management

現在、Azure Functions では、Python 3.6.x (公式な CPython 配布) のみがサポートされています。Currently, Azure Functions only supports Python 3.6.x (official CPython distribution).

Azure Functions Core Tools または Visual Studio Code を使用してローカルで開発を行う場合は、必要なパッケージの名前とバージョンを requirements.txt ファイルに追加し、pip を使用してそれらをインストールしてください。When developing locally using the Azure Functions Core Tools or Visual Studio Code, add the names and versions of the required packages to the requirements.txt file and install them using pip.

たとえば、次の要件のファイルと pip コマンドを使用すれば、PyPI から requests パッケージをインストールすることができます。For example, the following requirements file and pip command can be used to install the requests package from PyPI.

pip install requests
requests==2.19.1
pip install -r requirements.txt

発行の準備ができたら、ご利用の依存関係がすべて、プロジェクト ディレクトリのルートにある requirements.txt ファイル内にリストされていることを確認します。When you're ready for publishing, make sure that all your dependencies are listed in the requirements.txt file, located at the root of your project directory. ご自分の Azure 関数を正常に実行するには、少なくとも次のパッケージが要件ファイルに含まれている必要があります。To successfully execute your Azure Functions, the requirements file should contain a minimum of the following packages:

azure-functions
azure-functions-worker
grpcio==1.14.1
grpcio-tools==1.14.1
protobuf==3.6.1
six==1.11.0

Azure への発行Publishing to Azure

使用しているパッケージにおいてコンパイラが必要とされるが、PyPI からの manylinux 対応のホイールのインストールがサポートされていない場合、Azure への発行は失敗し、次のエラーが返されます。If you're using a package that requires a compiler and does not support the installation of manylinux-compatible wheels from PyPI, publishing to Azure will fail with the following error:

There was an error restoring dependencies.ERROR: cannot install <package name - version> dependency: binary dependencies without wheels are not supported.  
The terminal process terminated with exit code: 1

必要なバイナリを自動的にビルドして構成するには、Azure Functions Core Tools (func) を使用することにより、ご利用のローカル マシン上に Docker をインストールし、次のコマンドを実行して発行します。To automatically build and configure the required binaries, install Docker on your local machine and run the following command to publish using the Azure Functions Core Tools (func). <app name> を、Azure 内のご自分の関数アプリの名前に置き換えることを忘れないでください。Remember to replace <app name> with the name of your function app in Azure.

func azure functionapp publish <app name> --build-native-deps

Core Tools では、ご利用のローカル マシン上で mcr.microsoft.com/azure-functions/python イメージをコンテナーとして実行するためにバックグラウンドで Docker が使用されます。Underneath the covers, Core Tools will use docker to run the mcr.microsoft.com/azure-functions/python image as a container on your local machine. この環境を使用する場合、必要なモジュールがソース配布からビルドおよびインストールされてから、Azure への最終的なデプロイに備えてそれらがパッケージ化されます。Using this environment, it'll then build and install the required modules from source distribution, before packaging them up for final deployment to Azure.

注意

Core Tools (func) では、PyInstaller プログラムを使用して、ユーザーのコードと依存関係が、Azure 内で実行される 1 つのスタンドアロン実行可能ファイルに固定されます。Core Tools (func) uses the PyInstaller program to freeze the user's code and dependencies into a single stand-alone executable to run in Azure. この機能は現在プレビュー段階にあり、すべての種類の Python パッケージに展開されるとは限りません。This functionality is currently in preview and may not extend to all types of Python packages. 使用するモジュールをインポートできない場合は、--no-bundler オプションを使用してもう一度発行を試みてください。If you're unable to import your modules, try publishing again using the --no-bundler option.

func azure functionapp publish <app_name> --build-native-deps --no-bundler

それでもまだ問題が発生する場合は、Microsoft にお知らせください。そのためには、issue を開き、問題の説明を入力してください。If you continue to experience issues, please let us know by opening an issue and including a description of the problem.

依存関係をビルドし、継続的インテグレーション (CI) と継続的デリバリー (CD) システムを使用して発行するには、Azure パイプラインまたは Travis CI のカスタム スクリプトを使用します。To build your dependencies and publish using a continuous integration (CI) and continuous delivery (CD) system, you can use an Azure Pipeline or Travis CI custom script.

次に示すのは、ビルドおよび発行プロセスに関する azure-pipelines.yml スクリプトの例です。Following is an example azure-pipelines.yml script for the build and publishing process.

pool:
  vmImage: 'Ubuntu 16.04'

steps:
- task: NodeTool@0
  inputs:
    versionSpec: '8.x'

- script: |
    set -e
    echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ wheezy main" | sudo tee /etc/apt/sources.list.d/azure-cli.list
    curl -L https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
    sudo apt-get install -y apt-transport-https
    echo "install Azure CLI..."
    sudo apt-get update && sudo apt-get install -y azure-cli
    npm i -g azure-functions-core-tools --unsafe-perm true
    echo "installing dotnet core"
    curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel 2.0
- script: |
    set -e
    az login --service-principal --username "$(APP_ID)" --password "$(PASSWORD)" --tenant "$(TENANT_ID)" 
    func settings add FUNCTIONS_WORKER_RUNTIME python
    func extensions install
    func azure functionapp publish $(APP_NAME) --build-native-deps

次に示すのは、ビルドおよび発行プロセスに関する .travis.yaml スクリプトの例です。Following is an example .travis.yaml script for the build and publishing process.

sudo: required

language: node_js

node_js:
  - "8"

services:
  - docker

before_install:
  - echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ wheezy main" | sudo tee /etc/apt/sources.list.d/azure-cli.list
  - curl -L https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
  - sudo apt-get install -y apt-transport-https
  - sudo apt-get update && sudo apt-get install -y azure-cli
  - npm i -g azure-functions-core-tools --unsafe-perm true


script:
  - az login --service-principal --username "$APP_ID" --password "$PASSWORD" --tenant "$TENANT_ID"
  - az account get-access-token --query "accessToken" | func azure functionapp publish $APP_NAME --build-native-deps

既知の問題とよくあるご質問Known issues and FAQ

既知の問題と機能に関する要望はすべて、GitHub issues リストを使用して追跡されます。All known issues and feature requests are tracked using GitHub issues list. 問題が発生してその問題が GitHub で見つからない場合は、新しい Issue を開き、その問題の詳細な説明を記載してお知らせください。If you run into a problem and can't find the issue in GitHub, open a new issue and include a detailed description of the problem.

次の手順Next steps

詳細については、次のリソースを参照してください。For more information, see the following resources: