microdot.multipart — análisis de multipart/form-data¶
Analiza los cuerpos de solicitud Content-Type: multipart/form-data: la codificación que usan los navegadores para los formularios que incluyen campos <input type="file">. Dos variantes de la API:
Un
FormDataIterde transmisión que produce los campos uno a la vez: útil cuando la aplicación tiene que gestionar cargas muy grandes pieza por pieza en un dispositivo con memoria limitada.Un decorador
with_form_data()que almacena en búfer todo y rellenarequest.form/request.files: la API cómoda para cargas de tamaño normal.
class FormDataIter¶
- class microdot.multipart.FormDataIter(request)¶
Iterador asíncrono sobre las partes del cuerpo multipart de request. Los valores producidos son tuplas
(name, value); value es unstrpara los campos normales y unFileUploadpara los campos de archivo.Se usa directamente cuando la memoria importa más que la ergonomía:
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'
Nota
Al iterar sobre los campos de archivo, el archivo debe consumirse (mediante
FileUpload.read()oFileUpload.save()) antes de la siguiente iteraciónasync for: el flujo subyacente se invalida cuando avanza la iteración.
class FileUpload¶
- class microdot.multipart.FileUpload(filename: str, content_type: str | None, read)¶
Un único archivo cargado. Las instancias son producidas por
FormDataItery recopiladas enrequest.filesporwith_form_data(). Las aplicaciones normalmente no construyenFileUploaddirectamente.- filename: str¶
El nombre original del archivo tal como lo envió el cliente (no fiable: no lo pase a
open()sin sanearlo).
- content_type: str | None¶
El tipo MIME del encabezado
Content-Typede la parte, oNonesi no se proporciona.
- max_memory_size: int¶
Atributo de clase. Umbral (en bytes) por encima del cual
copy()cambia del almacenamiento en búfer en memoria a un archivo temporal. Por defecto 1024.
- async save(path_or_file)¶
Guarda la carga en path_or_file, que puede ser una ruta del sistema de archivos o un objeto de archivo ya abierto.
- async copy(max_memory_size: int | None = None)¶
Almacena la carga en búfer (ya sea en RAM o en un archivo temporal, según
max_memory_size) para que el resto del cuerpo multipart pueda analizarse sin que el flujo original se invalide. El decoradorwith_form_data()llama a esto automáticamente.
- async close()¶
Libera cualquier archivo temporal creado por
copy(). Se llama automáticamente cuando la solicitud finaliza si la carga llegó arequest.filesmediantewith_form_data().
Decoradores a nivel de módulo¶
- microdot.multipart.with_form_data(f)¶
Decorador que analiza el cuerpo multipart por adelantado y rellena
request.formyrequest.filesantes de que se ejecute el controlador: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'
Las cargas de archivos se almacenan en búfer mediante
FileUpload.copy(), de modo que el controlador puede iterarrequest.filesyrequest.formlibremente. Los archivos temporales se limpian automáticamente cuando la solicitud finaliza.
Para cargas mayores que un par de megabytes, prefiera la API de transmisión FormDataIter; with_form_data() acumula toda la solicitud en memoria o en el sistema de archivos antes de que se ejecute el controlador.