microdot.multipart — Parsen von multipart/form-data¶
Parst Anfrage-Bodies vom Typ Content-Type: multipart/form-data – die Kodierung, die Browser für Formulare mit <input type="file">-Feldern verwenden. Zwei Varianten der API:
Ein streamender
FormDataIter, der die Felder einzeln liefert – nützlich, wenn die Anwendung sehr große Uploads stückweise auf einem speicherbeschränkten Gerät verarbeiten muss.Ein
with_form_data()-Dekorator, der alles puffert undrequest.form/request.filesfüllt – die bequeme API für Uploads normaler Größe.
class FormDataIter¶
- class microdot.multipart.FormDataIter(request)¶
Asynchroner Iterator über die Teile des Multipart-Bodys von request. Die gelieferten Werte sind
(name, value)-Tupel; value ist einstrfür reguläre Felder und einFileUploadfür Dateifelder.Wird direkt verwendet, wenn Speicher wichtiger ist als Ergonomie:
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'
Bemerkung
Beim Iterieren über Dateifelder muss die Datei (über
FileUpload.read()oderFileUpload.save()) vollständig gelesen werden, bevor die nächsteasync for-Iteration erfolgt – der zugrunde liegende Stream wird ungültig, sobald die Iteration fortschreitet.
class FileUpload¶
- class microdot.multipart.FileUpload(filename: str, content_type: str | None, read)¶
Eine einzelne hochgeladene Datei. Instanzen werden von
FormDataItergeliefert und vonwith_form_data()inrequest.filesgesammelt. Anwendungen erzeugenFileUploadnormalerweise nicht direkt.- filename: str¶
Der ursprüngliche Name der Datei, wie der Client ihn gesendet hat (nicht vertrauenswürdig – nicht ohne Bereinigung an
open()übergeben).
- content_type: str | None¶
Der MIME-Typ aus dem
Content-Type-Header des Teils oderNone, falls nicht angegeben.
- max_memory_size: int¶
Klassenattribut. Schwellenwert (in Bytes), oberhalb dessen
copy()von der Pufferung im Speicher auf eine temporäre Datei umschaltet. Standard 1024.
- async save(path_or_file)¶
Speichert den Upload in path_or_file, was ein Dateisystempfad oder ein bereits geöffnetes Dateiobjekt sein kann.
- async copy(max_memory_size: int | None = None)¶
Puffert den Upload (entweder im RAM oder in einer temporären Datei, abhängig von
max_memory_size), sodass der Rest des Multipart-Bodys geparst werden kann, ohne dass der ursprüngliche Stream ungültig wird. Derwith_form_data()-Dekorator ruft dies automatisch auf.
- async close()¶
Gibt jede von
copy()erstellte temporäre Datei frei. Wird automatisch aufgerufen, wenn die Anfrage abgeschlossen ist, sofern der Upload überwith_form_data()inrequest.filesgelangt ist.
Dekoratoren auf Modulebene¶
- microdot.multipart.with_form_data(f)¶
Dekorator, der den Multipart-Body vorab parst und
request.formundrequest.filesfüllt, bevor der Handler ausgeführt wird: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'
Datei-Uploads werden über
FileUpload.copy()gepuffert, sodass der Handler frei überrequest.filesundrequest.formiterieren kann. Temporäre Dateien werden automatisch bereinigt, wenn die Anfrage endet.
Bevorzuge für Uploads, die größer als ein paar Megabyte sind, die streamende FormDataIter-API; with_form_data() sammelt die gesamte Anfrage im Speicher oder im Dateisystem an, bevor der Handler ausgeführt wird.