microdot.multipart — parsarea multipart/form-data

Parsează corpurile cererilor Content-Type: multipart/form-data – codificarea pe care browserele o folosesc pentru formularele care includ câmpuri <input type="file">. Două variante de API:

  • Un FormDataIter de tip streaming care furnizează câmpurile pe rând – util când aplicația trebuie să gestioneze încărcări foarte mari bucată cu bucată pe un dispozitiv cu memorie limitată.

  • Un decorator with_form_data() care stochează totul în tampon și populează request.form / request.files – API-ul convenabil pentru încărcări de dimensiuni normale.

class FormDataIter

class microdot.multipart.FormDataIter(request)

Iterator asincron peste părțile corpului multipart al cererii request. Valorile furnizate sunt tupluri (name, value); value este un str pentru câmpurile obișnuite și un FileUpload pentru câmpurile de fișiere.

Folosit direct atunci când memoria contează mai mult decât 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'

Notă

La iterarea peste câmpurile de fișiere, fișierul trebuie consumat (prin FileUpload.read() sau FileUpload.save()) înainte de următoarea iterație async for – fluxul subiacent este invalidat când iterația avansează.

buffer_size: int

Atribut de clasă. Dimensiunea fragmentului folosită la citirea din fluxul cererii. Implicit 256 de octeți. Mărește-o pentru un debit mai mare cu prețul memoriei RAM.

class FileUpload

class microdot.multipart.FileUpload(filename: str, content_type: str | None, read)

Un singur fișier încărcat. Instanțele sunt furnizate de FormDataIter și colectate în request.files de with_form_data(). Aplicațiile nu construiesc în mod normal FileUpload direct.

filename: str

Numele original al fișierului așa cum l-a trimis clientul (nesigur – nu îl transmite către open() fără să îl igienizezi).

content_type: str | None

Tipul MIME din antetul Content-Type al părții sau None dacă nu este furnizat.

max_memory_size: int

Atribut de clasă. Pragul (în octeți) peste care copy() comută de la stocarea în memorie la un fișier temporar. Implicit 1024.

async read(n: int = -1)

Citește până la n octeți din fluxul de încărcare. -1 citește până la sfârșit.

async save(path_or_file)

Salvează încărcarea în path_or_file, care poate fi o cale din sistemul de fișiere sau un obiect fișier deja deschis.

async copy(max_memory_size: int | None = None)

Stochează încărcarea în tampon (fie în RAM, fie într-un fișier temporar, în funcție de max_memory_size) astfel încât restul corpului multipart să poată fi parsat fără ca fluxul original să fie invalidat. Decoratorul with_form_data() apelează acest lucru automat.

async close()

Eliberează orice fișier temporar creat de copy(). Apelat automat când cererea se încheie dacă încărcarea a ajuns în request.files prin with_form_data().

Decoratori la nivel de modul

microdot.multipart.with_form_data(f)

Decorator care parsează corpul multipart în avans și populează request.form și request.files înainte de a rula handlerul:

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'

Încărcările de fișiere sunt stocate în tampon prin FileUpload.copy(), astfel încât handlerul poate itera liber peste request.files și request.form. Fișierele temporare sunt curățate automat când cererea se încheie.

Pentru încărcări mai mari de câțiva megaocteți, preferă API-ul de tip streaming FormDataIter; with_form_data() acumulează întreaga cerere în memorie sau în sistemul de fișiere înainte de a rula handlerul.