microdot.multipart — parsing di multipart/form-data¶
Esegue il parsing dei corpi di richiesta Content-Type: multipart/form-data – la codifica che i browser utilizzano per i form che includono campi <input type="file">. Due varianti di API:
Un
FormDataIterin streaming che restituisce i campi uno alla volta – utile quando l’applicazione deve gestire upload molto grandi pezzo per pezzo su un dispositivo con memoria limitata.Un decoratore
with_form_data()che bufferizza tutto e popolarequest.form/request.files– l’API comoda per gli upload di dimensioni normali.
class FormDataIter¶
- class microdot.multipart.FormDataIter(request)¶
Iteratore asincrono sulle parti del corpo multipart di request. I valori restituiti sono tuple
(name, value); value è unastrper i campi regolari e unFileUploadper i campi file.Utilizzato direttamente quando la memoria conta più dell’ergonomia:
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
Quando si itera sui campi file, il file deve essere consumato (tramite
FileUpload.read()oFileUpload.save()) prima della successiva iterazioneasync for– lo stream sottostante viene invalidato quando l’iterazione avanza.
class FileUpload¶
- class microdot.multipart.FileUpload(filename: str, content_type: str | None, read)¶
Un singolo file caricato. Le istanze vengono restituite da
FormDataItere raccolte inrequest.filesdawith_form_data(). Le applicazioni normalmente non costruisconoFileUploaddirettamente.- filename: str¶
Il nome originale del file così come inviato dal client (non attendibile – non passarlo a
open()senza sanitizzarlo).
- content_type: str | None¶
Il tipo MIME dall’header
Content-Typedella parte, oppureNonese non fornito.
- max_memory_size: int¶
Attributo di classe. Soglia (in byte) oltre la quale
copy()passa dal buffering in memoria a un file temporaneo. Predefinito 1024.
- async save(path_or_file)¶
Salva l’upload in path_or_file, che può essere un percorso del filesystem oppure un oggetto file già aperto.
- async copy(max_memory_size: int | None = None)¶
Bufferizza l’upload (in RAM oppure in un file temporaneo, a seconda di
max_memory_size) in modo che il resto del corpo multipart possa essere analizzato senza che lo stream originale venga invalidato. Il decoratorewith_form_data()lo chiama automaticamente.
- async close()¶
Rilascia qualsiasi file temporaneo creato da
copy(). Chiamato automaticamente al termine della richiesta se l’upload ha raggiuntorequest.filestramitewith_form_data().
Decoratori a livello di modulo¶
- microdot.multipart.with_form_data(f)¶
Decoratore che esegue il parsing del corpo multipart in anticipo e popola
request.formerequest.filesprima dell’esecuzione dell’handler: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'
Gli upload di file vengono bufferizzati tramite
FileUpload.copy(), in modo che l’handler possa iterare liberamenterequest.fileserequest.form. I file temporanei vengono ripuliti automaticamente al termine della richiesta.
Per upload più grandi di un paio di megabyte, preferisci l’API in streaming FormDataIter; with_form_data() accumula l’intera richiesta in memoria o sul filesystem prima dell’esecuzione dell’handler.