ハンドラは、Function Compute 関数の関数エントリポイントです。外部から送信されたイベントを受信し、その処理ロジックを含みます。本トピックでは、Python ハンドラのシグネチャ、パラメーター、コンテキストオブジェクトのプロパティ、および実行可能なサンプルを用いた一般的な使用パターンについて説明します。
仕組み
関数が呼び出されると、Function Compute は ハンドラ パラメーターで指定したメソッドを呼び出します。ハンドラは、イベントペイロードとランタイムコンテキストの 2 つの引数を受け取り、イベントを処理して結果を返します。
Python ハンドラは、ファイル名.メソッド名 の形式を使用します。たとえば、ファイル名が main.py、メソッド名が handler の場合、ハンドラ を main.handler に設定します。
ハンドラ名を変更するには:
Function Compute コンソールで、左側のナビゲーションウィンドウの[関数]をクリックします。
更新対象の関数をクリックします。
コード タブで、ランタイム設定セクションまでスクロールし、ハンドラ フィールドを編集します。
HTTP トリガーまたはカスタムドメイン名を使用する場合は、応答を構築する前に HTTP リクエスト構造体を解析してください。詳細については、「HTTP トリガーを使用して関数を呼び出す」をご参照ください。
ハンドラのシグネチャ
def handler(event, context):
return 'hello world'パラメーター
| パラメーター | 型 | 説明 |
|---|---|---|
event | str(Python 2.7)/bytes(Python 3) | 呼び出し時に渡されるイベントペイロードです。JSON 形式のペイロードはそのまま渡され、コード内で明示的に解析する必要があります。 |
context | オブジェクト | 呼び出し時に提供されるランタイムコンテキストです。実行中の関数に関する認証情報およびメタデータを含みます。 |
JSON 型のマッピング
イベントが JSON オブジェクトの場合、json.loads() を使用してネイティブな Python 型に変換します:
| JSON 型 | Python 型 |
|---|---|
| object | dict |
| array | list |
| number | int または float |
| string | str |
| Boolean | bool |
| null | NoneType |
コンテキストオブジェクト
context オブジェクトは、現在の呼び出しに関するランタイム情報を提供します:
| プロパティ | 説明 |
|---|---|
context.credentials.access_key_id | 一時的な AccessKey ID(Python 3.10 以前) |
context.credentials.access_key_secret | 一時的な AccessKey Secret(Python 3.10 以前) |
context.credentials.security_token | セキュリティトークンサービス(STS)のセキュリティトークン(Python 3.10 以前) |
Python 3.12 ランタイムでは、credentials フィールドが context から削除されます。代わりに、ALIBABA_CLOUD_ACCESS_KEY_ID、ALIBABA_CLOUD_ACCESS_KEY_SECRET、ALIBABA_CLOUD_SECURITY_TOKEN の環境変数を使用してください。
ベストプラクティス
| プラクティス | 理由 |
|---|---|
| ハンドラロジックとビジネスロジックを分離する | ハンドラは軽量に保ち、ヘルパー関数に処理をデリゲートします。これにより、単体テストが容易になります。 |
| 認証情報には環境変数を使用する | AccessKey ペアをコード内にハードコーディングしないでください。Python 3.10 では context.credentials から一時的な認証情報を取得し、Python 3.12 では環境変数を使用してください。 |
| イベントの解析は最初に行う | json.loads(event) をハンドラの冒頭で即座に呼び出すことで、以降のコードがネイティブな Python 型で動作できるようにします。 |
前提条件
以下のサンプルを実行する前に、次の準備を行ってください:
例 1:JSON パラメーターの解析
Function Compute はイベントペイロードを一切変更せずに渡します。ハンドラ内で json.loads() を使用して JSON を解析します。
# -*- coding: utf-8 -*-
import json
def handler(event, context):
evt = json.loads(event)
return evt['key']この例のハンドラは、handler メソッドであり、ファイル名は index.py です。関数で異なるハンドラ名を使用している場合は、ハンドラ 設定を適宜更新してください。
この例をテストする
Function Compute コンソール にログインし、左側ナビゲーションウィンドウで 関数 をクリックします。
上部ナビゲーションバーでリージョンを選択します。関数 ページで、テスト対象の関数をクリックして開きます。
コード タブで、サンプルコードをエディターに貼り付け、デプロイ をクリックします。
[テスト関数] の横にある
アイコンをクリックし、[テストパラメータの設定] を選択し、以下の ペイロードを入力して [OK] をクリックします:{ "key": "value" }関数のテスト をクリックします。
関数は value を返します。
例 2:一時的な認証情報を使用した OSS オブジェクトの読み書き
Function Compute が提供する一時的な認証情報を使用して Object Storage Service (OSS) にアクセスします。ハードコーディングされたシークレットは不要です。
以下の 2 つのバリアントは、認証情報の取得方法のみが異なり、その他のロジックはすべて同一です。
Python 3.12
Python 3.12 では、環境変数から認証情報を読み込みます。認証情報の設定方法の詳細については、「AccessKey の取得」および「ロールの引き受け (AssumeRole)」をご参照ください。
import json
import os
import oss2
def handler(event, context):
evt = json.loads(event)
auth = oss2.StsAuth(
os.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
os.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"),
os.getenv("ALIBABA_CLOUD_SECURITY_TOKEN")
)
bucket = oss2.Bucket(auth, evt['endpoint'], evt['bucket'])
bucket.put_object(evt['objectName'], evt['message'])
return 'success'Python 3.10
Python 3.10 およびそれ以前のバージョンでは、context.credentials から認証情報を読み込みます。
import json
import oss2
def handler(event, context):
evt = json.loads(event)
creds = context.credentials
# STS 一時認証情報を使用する場合は security_token を含める
auth = oss2.StsAuth(creds.access_key_id, creds.access_key_secret, creds.security_token)
bucket = oss2.Bucket(auth, evt['endpoint'], evt['bucket'])
bucket.put_object(evt['objectName'], evt['message'])
return 'success'関数の設定済みロールに OSS 書き込み権限があることを確認してください。権限の付与は、Resource Access Management (RAM) コンソール で行います。
この例を試す
Function Compute コンソール にログインし、左側ナビゲーションウィンドウで 関数 をクリックします。
上部ナビゲーションバーでリージョンを選択します。関数 ページで、テスト対象の関数をクリックして開きます。
コード タブで、サンプルコードをエディターに貼り付け、デプロイ をクリックします。
重要この例のハンドラは、
handlerメソッドであり、ファイル名はindex.pyです。関数で異なるハンドラ名を使用している場合は、ハンドラ 設定を適宜更新してください。[テスト機能] の横にある
アイコンをクリックし、[テストパラメーターの設定] を選択し、次のペイロードを入力して、[OK] をクリックします。{ "endpoint": "http://oss-cn-shenzhen-internal.aliyuncs.com", "bucket": "oss-********", "objectName": "oss-test-object", "message": "oss-test-content" }関数のテスト をクリックします。
関数は success を返します。
例 3:外部コマンドの実行
subprocess モジュールを使用してフォークプロセスを作成し、システムコマンドを実行します。
import subprocess
def handler(event, context):
ret = subprocess.check_output(['ls', '-l'])
return retこの例では、ls -l を実行し、ディレクトリ一覧を返します。
例 4:HTTP トリガー要求の処理
HTTP トリガー経由で呼び出された関数は、構造化された JSON イベントを受信します。応答には、statusCode、headers、isBase64Encoded、および body を含める必要があります。
前提条件
HTTP トリガーが設定された Python イベント関数。詳細については、「イベント関数の作成」および「HTTP トリガーの設定」をご参照ください。
# -*- coding: utf-8 -*-
import logging
import json
import base64
def handler(event, context):
logger = logging.getLogger()
logger.info("receive event: %s", event)
try:
event_json = json.loads(event)
except Exception:
return "The request did not come from an HTTP Trigger because the event is not a json string, event: {}".format(event)
if "body" not in event_json:
return "The request did not come from an HTTP Trigger because the event does not include the 'body' field, event: {}".format(event)
req_body = event_json['body']
if 'isBase64Encoded' in event_json and event_json['isBase64Encoded']:
req_body = base64.b64decode(event_json['body']).decode("utf-8")
return {
'statusCode': 200,
'headers': {'Content-Type': 'text/plain'},
'isBase64Encoded': False,
'body': req_body
}この例をテストする
Function Compute コンソール にログインし、左側ナビゲーションウィンドウで 関数 をクリックします。
上部ナビゲーションバーでリージョンを選択します。関数 ページで、テスト対象の関数をクリックして開きます。
コード タブで、サンプルコードをエディターに貼り付け、デプロイ をクリックします。
トリガー タブで、HTTP トリガーのパブリックエンドポイントをコピーします。
以下のコマンドを実行して関数を呼び出します:
curl -i "https://test-python-ipgrwr****.cn-shanghai.fcapp.run" -d 'Hello fc3.0'https://test-python-ipgrwr****.cn-shanghai.fcapp.runの部分を、先ほどコピーしたエンドポイントに置き換えてください。重要認証方式 が 認証なし に設定されている場合、curl または Postman を直接使用して関数を呼び出せます。
認証方式 が 署名認証 または JWT 認証 に設定されている場合、適切にリクエストに署名してください。詳細については、「認証」をご参照ください。
応答は以下のようになります:
HTTP/1.1 200 OK
Content-Disposition: attachment
Content-Length: 12
Content-Type: application/json
X-Fc-Request-Id: 1-64f7449a-127fbe39cd7681596e33ebad
Date: Tue, 05 Sep 2023 15:09:14 GMT
Hello fc3.0発生しうるエラー
このハンドラは、HTTP トリガーイベントを想定しています。コンソールの 関数のテスト を使用して、"Hello, FC!" のようなプレーン文字列で呼び出した場合、関数は以下を返します:
The request did not come from an HTTP Trigger, event: "Hello, FC!"