microdot.multipart --- multipart/form-data 解析¶
解析 Content-Type: multipart/form-data 請求主體 —— 瀏覽器用於包含 <input type="file"> 欄位之表單的編碼方式。提供兩種形式的 API:
串流式的
FormDataIter,逐一產生各欄位 —— 當應用程式必須在記憶體受限的裝置上逐塊處理極大型上傳時相當有用。with_form_data()裝飾器,會緩衝所有內容並填入request.form/request.files—— 適用於一般大小上傳的便利 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)¶
單一個已上傳的檔案。實例由
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。暫存檔會在請求結束時自動清理。
對於大於數 MB 的上傳,建議優先使用串流式的 FormDataIter API;with_form_data() 會在處理常式執行前,將整個請求累積於記憶體或檔案系統中。