HTTP ハンドラを使用すると、Python Web Server Gateway Interface (WSGI) 仕様を使用して、Python で HTTP リクエストを直接処理できます。リクエストが到着すると、Function Compute は指定されたハンドラを呼び出し、environ を介してリクエストデータを渡し、start_response を介してレスポンスコールバックを渡します。
HTTP リクエストで関数を呼び出すには、事前に HTTP トリガーを設定する必要があります。「HTTP リクエストで関数を呼び出す HTTP トリガーの設定」をご参照ください。
ハンドラの署名
すべての HTTP ハンドラは、WSGI 署名に従います。
def handler(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
return [b'<h1>Hello, world!</h1>']| パラメーター | 型 | 説明 |
|---|---|---|
environ | dict | すべての HTTP リクエストデータを含む Python ディクショナリです。フィールドの完全なリストについては、「リクエストフィールド (environ)」をご参照ください。 |
start_response | callable | FC ランタイムによって提供される関数です。レスポンスボディを返す前に、これを呼び出してレスポンスステータスとヘッダーを設定します。 |
戻り値はイテラブルである必要があります。return [b'<h1>Hello, world!</h1>'] は、単一のバイトオブジェクトを含むリストを返し、ランタイムはこれを HTTP レスポンスボディとしてクライアントに送信します。
WSGI 仕様の完全な詳細については、「PEP 3333」をご参照ください。
Flask アプリケーションの Function Compute への移行
HTTP ハンドラは WSGI 仕様に従うため、Flask および Django アプリケーションは、Function Compute で実行するために単一のアダプター関数のみを必要とします。
以下の例は、Python 3 ランタイムで Flask の hello world アプリケーションを実行します。
# Flask application — define routes as usual
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Web App with Python Flask!'
# FC handler — forwards every request to the Flask WSGI app
def handler(environ, start_response):
return app(environ, start_response)この例には 2 つの部分があります。
Flask アプリケーション (1~7 行目): 標準的な Flask コードです。変更は不要です。
FC ハンドラ (9~11 行目):
environとstart_responseを Flask アプリケーションに直接渡す最小限のアダプターです。この 1 行だけで、WSGI 互換の任意のフレームワークを Function Compute で実行できます。
Flask アプリケーションのデプロイ
開始する前に、「サービスを作成する」をご参照ください。
Function Compute コンソールにログインします。左側のナビゲーションウィンドウで、[サービスと関数] をクリックします。
トップナビゲーションバーで、リージョンを選択します。 「[サービス]」ページで、目的のサービスをクリックします。
「[関数]」ページで、[関数の作成] をクリックします。Python 3 ランタイムを使用した HTTP 関数を作成します。詳細については、「関数の作成」をご参照ください。
[関数の詳細]ページで、[コード]タブをクリックして、エディターにサンプルコードを貼り付けます。次に、[ターミナル] > [新しいターミナル]を選択し、[ターミナル]パネルで次のコマンドを実行して、現在のディレクトリに Flask をインストールします:
pip install flask -t .[デプロイ] をクリックします。
[テスト関数]をクリックし、応答を確認します。
Web App with Python Flask!が表示された場合、関数は正常に実行されています。
リクエストフィールド (environ)
environ は、すべての HTTP リクエストデータを含む Python ディクショナリです。以下の表に、Function Compute ハンドラで最も一般的に使用されるフィールドを示します。フィールドの完全なリストについては、「environ 変数」をご参照ください。
| フィールド | 型 | 説明 |
|---|---|---|
REQUEST_METHOD | 文字列 | HTTP リクエストメソッド (例: GET または POST)。 |
HTTP_* | 文字列 | クライアント提供のリクエストヘッダーです。各ヘッダーキーは、HTTP_ + 大文字化され、ハイフンがアンダースコアに変換されたキーに正規化されます。たとえば、x-Custom-key: value は environ['HTTP_X_CUSTOM_KEY'] = 'value' になります。 |
CONTENT_TYPE | 文字列 | リクエストボディのメディアタイプ。 |
CONTENT_LENGTH | 文字列 | リクエストボディのバイト単位の長さ。 |
REMOTE_ADDR | 文字列 | クライアント IP アドレス。 |
wsgi.input | BytesIO | リクエストボディ。 |
fc.request_uri | 文字列 | Function Compute によって定義された完全なリクエスト URL。 |
fc.context | FCContext | Function Compute によって定義された関数呼び出しコンテキスト。 |
次の例は、environ から一般的なフィールドを読み取ります。
HELLO_WORLD = b"Hello world!\n"
def handler(environ, start_response):
# FC-specific context and request URI
context = environ['fc.context']
request_uri = environ['fc.request_uri']
# Iterate over custom request headers (all start with HTTP_)
for k, v in environ.items():
if k.startswith("HTTP_"):
pass # process custom headers here
# Read request body
try:
request_body_size = int(environ.get('CONTENT_LENGTH', 0))
except ValueError:
request_body_size = 0
request_body = environ['wsgi.input'].read(request_body_size)
# Read other common fields
request_method = environ['REQUEST_METHOD']
path_info = environ['PATH_INFO']
server_protocol = environ['SERVER_PROTOCOL']
try:
content_type = environ['CONTENT_TYPE']
except KeyError:
content_type = " "
try:
query_string = environ['QUERY_STRING']
except KeyError:
query_string = " "
print('request_body: {}'.format(request_body))
print('method: {}\n path: {}\n query_string: {}\n server_protocol: {}\n'.format(
request_method, path_info, query_string, server_protocol))
status = '200 OK'
response_headers = [('Content-type', 'text/plain')]
start_response(status, response_headers)
return [HELLO_WORLD] # return value must be iterableレスポンス構造体 (start_response)
レスポンスボディを返す前に、start_response を呼び出してレスポンスステータスとヘッダーを設定します。FC ランタイムは、次の署名を持つこの呼び出し可能なものを提供します。
# Provided by FC runtime.
# status: a string like '200 OK' or '403 FORBIDDEN'
# return: must be a write(body_data) callable
def start_response(status, response_headers, exc_info=None):
...完全な仕様については、「start_response() 呼び出し可能」をご参照ください。
| パラメーター | 型 | 説明 |
|---|---|---|
status | 文字列 | HTTP レスポンスステータス (例: '200 OK' または '403 FORBIDDEN')。 |
response_headers | リスト | HTTP レスポンスヘッダーです。各ヘッダーは、(header_name, header_value) の 2 つの文字列のタプルです。 |
exc_info | リスト | エラー応答のタプル形式の例外情報です。Function Compute では使用されません。 |
ハンドラによって返されるレスポンスボディは、イテラブルオブジェクトである必要があります。
制限事項
リクエストの制限事項
次の制限を超えるリクエストは、HTTP ステータス 400 およびエラー InvalidArgument で拒否されます。
| フィールド | 制限 |
|---|---|
headers | すべてのキーと値の合計サイズ ≤ 8 KB |
path | リクエストパスとクエリパラメーターの合計サイズ ≤ 4 KB |
body (同期呼び出し) | ≤ 32 MB |
body (非同期呼び出し) | ≤ 128 KB |
レスポンスの制限事項
次の制限を超える応答は、HTTP ステータス 502 およびエラー BadResponse になります。
| フィールド | 制限 |
|---|---|
headers | すべてのキーと値の合計サイズ ≤ 8 KB |