リクエスト本文の利用#

要求には本文が付属する場合があります。たとえば POST 要求の場合、本文にはウェブページからのフォームエンコードされたデータやクライアントからの JSON エンコードされたデータを含めることができます。本文は、HTTP/1 と HTTP/2 両方の要求行とヘッダーの後に送信されます。これにより、Quart は本文全体が受信される前にアプリの要求処理コードをトリガすることができます。さらに、要求者はリクエスト本文をストリーミングすることを選択できます。特に、ファイルを多数送信するときのように本文が大きい場合はなおさらです。

Quart は Flask に従って、続行する前に本文全体を待機する方法を提供します。

@app.route('/', methods=['POST'])
async def index():
    await request.get_data()

高度な使い方#

リクエスト本文の利用方法を完全に制御したい場合、おそらく受信時にデータを消費したいでしょう。そのためには、Quart は本文を反復処理する方法を提供します。

from async_timeout import timeout

@app.route('/', methods=['POST'])
async def index():
    async with timeout(app.config['BODY_TIMEOUT']):
        async for data in request.body:
            ...

注記

上記のコード例では Async-Timeout を使用して、本文が指定されたタイムアウト内に受信されるようにします。

警告

他の要求メソッドや本文にアクセスするための属性は、クライアントが要求の送信に時間がかかりすぎるとタイムアウトします。body の使用はタイムアウトしません。使用にタイムアウトを組み込むのはあなた次第です。

警告

本文の反復処理ではデータが消費されるため、反復処理中に保存されない限り、その後のデータの使用は不可能になります。

テスト#

ルートが本文を反復処理して消費するかをテストするには、request() メソッドを使用する必要があります。

async def test_stream() -> None:
    test_client = app.test_client()
    async with test_client.request(...) as connection:
        await connection.send(b"data")
        await connection.send_complete()
    response = await connection.as_response()
    assert response ...

要求本文の送信中にクライアントが切断された場合、コードが予期どおりにクリーンアップされることを確認することも理にかなっています。

async def test_stream_closed() -> None:
    test_client = app.test_client()
    async with test_client.request(...) as connection:
        await connection.send(b"partial")
        await connection.disconnect()
    # Check cleanup markers....