microdot.multipart — parsování multipart/form-data

Parsuje těla požadavků Content-Type: multipart/form-data – kódování, které prohlížeče používají pro formuláře obsahující pole <input type="file">. Dvě varianty API:

  • Proudový FormDataIter, který poskytuje pole po jednom – užitečné, když aplikace musí zpracovávat velmi velké nahrávané soubory po částech na zařízení s omezenou pamětí.

  • Dekorátor with_form_data(), který vše ukládá do bufferu a naplňuje request.form / request.files – pohodlné API pro nahrávané soubory běžné velikosti.

class FormDataIter

class microdot.multipart.FormDataIter(request)

Asynchronní iterátor přes části multipartového těla request. Poskytované hodnoty jsou n-tice (name, value); value je str pro běžná pole a FileUpload pro souborová pole.

Používáno přímo, když záleží na paměti více než na ergonomii:

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'

Poznámka

Při iteraci přes souborová pole musí být soubor spotřebován (pomocí FileUpload.read() nebo FileUpload.save()) před další iterací async for – podkladový proud je při posunu iterace invalidován.

buffer_size: int

Atribut třídy. Velikost bloku používaná při čtení z proudu požadavku. Výchozí 256 bytů. Zvyšte pro vyšší propustnost na úkor RAM.

class FileUpload

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

Jeden nahraný soubor. Instance poskytuje FormDataIter a shromažďuje je do request.files funkce with_form_data(). Aplikace běžně nekonstruují FileUpload přímo.

filename: str

Původní název souboru, jak jej klient odeslal (nedůvěryhodný – nepředávejte jej do open() bez sanitizace).

content_type: str | None

Typ MIME z hlavičky Content-Type dané části, nebo None, pokud není poskytnut.

max_memory_size: int

Atribut třídy. Práh (v bytech), nad kterým copy() přepne z bufferování v paměti na dočasný soubor. Výchozí 1024.

async read(n: int = -1)

Přečte až n bytů z proudu nahrávání. -1 čte do konce.

async save(path_or_file)

Uloží nahraný soubor do path_or_file, což může být cesta v souborovém systému nebo již otevřený souborový objekt.

async copy(max_memory_size: int | None = None)

Uloží nahraný soubor do bufferu (buď v RAM, nebo v dočasném souboru, v závislosti na max_memory_size), aby bylo možné parsovat zbytek multipartového těla bez invalidace původního proudu. Dekorátor with_form_data() toto volá automaticky.

async close()

Uvolní jakýkoli dočasný soubor vytvořený funkcí copy(). Voláno automaticky při dokončení požadavku, pokud se nahraný soubor dostal do request.files prostřednictvím with_form_data().

Dekorátory na úrovni modulu

microdot.multipart.with_form_data(f)

Dekorátor, který parsuje multipartové tělo předem a naplňuje request.form a request.files před spuštěním handleru:

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'

Nahrané soubory jsou bufferovány pomocí FileUpload.copy(), takže handler může volně iterovat request.files a request.form. Dočasné soubory jsou automaticky uklizeny po skončení požadavku.

Pro nahrávané soubory větší než pár megabytů upřednostněte proudové API FormDataIter; with_form_data() akumuluje celý požadavek v paměti nebo v souborovém systému před spuštěním handleru.