コンテンツにスキップ

リクエスト

Starletteには Request クラスが含まれており、AS GIスコープと受信チャネルに直接アクセスするのではなく、着信リクエストを処理するためのより使いやすいインターフェイスを提供します。

リクエスト

署名: Request(scope, receive=None)

インポートリクエスト
from starlette. response import Response


async def app(スコープ、受信、送信):
    assert scope['type']=='http'
    request=Request(スコープ、受信)
    content='%s%s'%(request. method,request.url.path)
    response=Response(content, media_type='text/plain')
    await応答(スコープ、受信、送信)

リクエストはマッピングインターフェイスを提供するので、scope と同じように使用できます。

例えば、request['path'] はAS GIパスを返します。

リクエストボディにアクセスする必要がない場合は、receive にパラメータを指定せずにリクエストをインスタンス化できます。

方法

リクエストメソッドは request.method でアクセスします。

ユニファイドリソースロケータ(通常はURLとも呼ばれます)

要求されたURLは request.url でアクセスされます。

このプロパティは、URLから解析できるすべてのコンポーネントを公開する文字列のようなオブジェクトです。

例えば、request.url.path、request.url.port、request.url.scheme

タイトル

ヘッダーは、大文字と小文字を区別しない不変のマルチディクショナリとして公開されます。

例えば: request.headers['content-type']

クエリパラメータ

クエリパラメータは、不変のマルチディクショナリとして公開されます。

例えば: request.query_params['search']

パスパラメータ

ルーターのパスパラメータは、辞書インターフェイスとして公開されます。

例えば: request.path_params['username']

顧客の住所

クライアントのリモートアドレスは、request.client(または None)という名前のバイナリとして公開されます。

ホスト名またはIPアドレス: request.client.host

クライアントが接続しているポート番号: request.client.port

クッキー

Cookieは、通常の辞書インターフェイスとして表示されます。

例えば: request.cookies.get('mycookie')

無効なCookieの場合、Cookieは無視されます。(RFC 2109)

体

リクエストの本体を返すためのいくつかの異なるインターフェースがあります。

リクエスト本体はバイト形式です: await request.body()

フォームデータまたはマルチパートとして解析されるリクエストボディ: async with request.form() as form:

リクエストボディ、JSONとして解析: await request.json()

async for 構文を使用して、リクエスト本体にストリームとしてアクセスすることもできます。

インポートリクエスト
from starlette. response import Response


async def app(スコープ、受信、送信):
    assert scope['type']=='http'
    request=Request(スコープ、受信)
    body=b''
    ASync for chunk inrequest.stream():
        body+=チャンク
    response=Response(body, media_type='text/plain')
    await応答(スコープ、受信、送信)

.stream() にアクセスすると、本体全体をメモリに格納せずにバイトブロックが提供されます。その後、.body()、.form()、または .json() を呼び出すと、エラーが発生します。

長いポーリングやストリームレスポンスなどの状況では、クライアントが切断されているかどうかを判断する必要があります。disconnected = await request.is_disconnected() を使用して、この状態を判断できます。

リクエストファイル

リクエストファイルは通常、マルチパートフォームデータ(multipart/form-data)として送信されます。

署名: request.form(max_files=1000, max_fields=1000)

パラメーター max_files と max_fields を使用して、フィールドまたはファイルの最大数を構成できます。

request. form(max_files=1000,max_field=1000)で非同期:
    ...

!!! Informationは、セキュリティ上の理由からこれらの制限を設定し、無制限の数のフィールドまたはファイルを許可すると、空のフィールドが多すぎるとCPUとメモリを大量に消費するため、サービス拒否攻撃につながる可能性があります。

async with request.form() as form を呼び出すと、ファイルのアップロードとテキスト入力を含む不変のマルチディクショナリである starlette.datastructures.FormData を受け取ります。ファイルのアップロード項目は starlette.datastructures.UploadFile のインスタンスとして表されます。

UploadFile 次の属性を持つ:

  • filename:アップロードされた元のファイル名を持つ str、または利用できない場合は None(myimage.jpg など)。
  • content_type :コンテンツタイプ(MIMEタイプ/メディアタイプ)を持つ str 、または使用できない場合(たとえば、 image/jpeg )は None 。
  • file 一つ SpooledTemporaryFile (ファイルのようなオブジェクト)。これは実際のPythonファイルで、「ファイルのような」オブジェクトを期待する他の関数やライブラリに直接渡すことができます。
  • headers 一つ Headers オブジェクト。通常、これは Content-Type ヘッダーですが、マルチパートフィールドに他のヘッダーが含まれている場合は、ここにも含まれます。これらのヘッダーは Request.headers 頭は関係ありません。
  • size :バイト単位のアップロードファイルサイズ int を選択します。この値はリクエストの内容に基づいて計算されるため、アップロードファイルのサイズを決定するのに適しています Content-Length ヘッダー。設定されていない場合は、 None 。

UploadFile には以下のような async メソッドがあります。いずれも下位レベルで対応するファイルメソッドを呼び出します(内部 SpooledTemporaryFile を使用します)。

  • async write(data):data(bytes)をファイルに書き込む。
  • async read(size):ファイルを読み取る size(int)バイト。
  • async seek(offset):ファイル内のバイト位置 offset(int)に移動します。
    • たとえば、await myfile.seek(0) はファイルの開始位置に移動します。
  • async close() :ファイルを閉じます。

これらのメソッドはすべて async メソッドなので、それらを「待つ」必要があります。

たとえば、次の方法でファイル名とコンテンツを取得できます。

request. form()をformとして非同期化する:
    file name=form["up load_file"]. file name
    content=await form["up load_file"]. read()

!!! 情報RFC-7578: 4.2で規定されているように、ファイルを含むフォームデータのコンテンツ部分は、Content-Disposition ヘッダーに name および filename フィールド:Content-Disposition: form-data; name="user"; filename="somefile" があると仮定します。 filename フィールドはRFC-7578ではオプションですが、Starletteがどのデータをファイルと見なすかを区別するのに役立ちます。 filename フィールドが指定されている場合、UploadFile オブジェクトが作成され、基盤となるファイルにアクセスできます。

アプリケーション

スタートのStarletteアプリケーションは request.app 経由でアクセスできます。

状態

リクエストに追加の情報を保存したい場合は、request.state を使用して実装できます。

例えば:

request.state.time_started = time.time()