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。请求结束时临时文件会被自动清理。
对于大于几兆字节的上传,建议使用流式的 FormDataIter API;with_form_data() 会在处理程序运行之前将整个请求累积在内存中或文件系统上。