microdot.multipart --- multipart/form-data の解析¶
Content-Type: multipart/form-data のリクエストボディ -- <input type="file"> フィールドを含むフォームでブラウザが使用するエンコーディング -- を解析します。2 種類の API があります:
フィールドを 1 つずつ生成するストリーミング型の
FormDataIter。メモリに制約のあるデバイス上で、アプリケーションが非常に大きなアップロードを少しずつ処理する必要がある場合に便利です。すべてをバッファリングして
request.form/request.filesを設定するwith_form_data()デコレータ。通常サイズのアップロードに便利な API です。
class FormDataIter¶
- class microdot.multipart.FormDataIter(request)¶
request の multipart ボディの各パートに対する非同期イテレータ。生成される値は
(name, value)タプルです。value は通常のフィールドではstr、ファイルフィールドではFileUploadです。使いやすさよりメモリが重要な場合に直接使用します:
from microdot.multipart import FormDataIter, FileUpload @app.post('/upload') async def upload(request): async for name, value in FormDataIter(request): if isinstance(value, FileUpload): await value.save('/sdcard/' + value.filename) else: print(name, '=', value) return 'ok'
注釈
ファイルフィールドを反復処理する際は、次の
async forの反復の前にファイルを(FileUpload.read()またはFileUpload.save()を介して)消費する必要があります。反復が進むと、基盤となるストリームは無効になります。
class FileUpload¶
- class microdot.multipart.FileUpload(filename: str, content_type: str | None, read)¶
アップロードされた 1 つのファイル。インスタンスは
FormDataIterによって生成され、with_form_data()によってrequest.filesに収集されます。通常、アプリケーションがFileUploadを直接構築することはありません。- async save(path_or_file)¶
アップロードを path_or_file に保存します。これはファイルシステムのパス、または既に開いているファイルオブジェクトのいずれかです。
- async copy(max_memory_size: int | None = None)¶
アップロードを(
max_memory_sizeに応じて RAM または一時ファイルに)バッファリングし、元のストリームを無効にすることなく multipart ボディの残りを解析できるようにします。with_form_data()デコレータはこれを自動的に呼び出します。
- async close()¶
copy()によって作成された一時ファイルがあれば解放します。アップロードがwith_form_data()を介してrequest.filesに到達した場合、リクエスト終了時に自動的に呼び出されます。
モジュールレベルのデコレータ¶
- microdot.multipart.with_form_data(f)¶
ハンドラが実行される前に multipart ボディを先に解析し、
request.formとrequest.filesを設定するデコレータ:from microdot import Microdot from microdot.multipart import with_form_data app = Microdot() @app.post('/upload') @with_form_data async def upload(request): print('fields:', dict(request.form)) for name, file in request.files.items(): await file.save('/sdcard/' + sanitize(file.filename)) return 'ok'
ファイルアップロードは
FileUpload.copy()を介してバッファリングされるため、ハンドラはrequest.filesとrequest.formを自由に反復処理できます。一時ファイルはリクエスト終了時に自動的にクリーンアップされます。
数メガバイトを超えるアップロードには、ストリーミング型の FormDataIter API を推奨します。with_form_data() は、ハンドラが実行される前にリクエスト全体をメモリまたはファイルシステム上に蓄積します。