microdot.multipart — tolkning av multipart/form-data

Tolkar begäranskroppar av typen Content-Type: multipart/form-data – kodningen som webbläsare använder för formulär som innehåller <input type="file">-fält. Två varianter av API:

  • En strömmande FormDataIter som ger ett fält i taget – användbart när applikationen måste hantera mycket stora uppladdningar bit för bit på en minnesbegränsad enhet.

  • En dekorator with_form_data() som buffrar allt och fyller i request.form / request.files – det bekväma API:et för uppladdningar av normal storlek.

class FormDataIter

class microdot.multipart.FormDataIter(request)

Asynkron iterator över delarna av request:s multipart-kropp. De levererade värdena är (name, value)-tupler; value är en str för vanliga fält och en FileUpload för filfält.

Används direkt när minne är viktigare än ergonomi:

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'

Anteckning

När man itererar över filfält måste filen konsumeras (via FileUpload.read() eller FileUpload.save()) före nästa async for-iteration – den underliggande strömmen ogiltigförklaras när iterationen går vidare.

buffer_size: int

Klassattribut. Chunk-storlek som används vid läsning från begäranströmmen. Standard 256 byte. Öka för högre genomströmning på bekostnad av RAM.

class FileUpload

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

En enskild uppladdad fil. Instanser levereras av FormDataIter och samlas in i request.files av with_form_data(). Applikationer konstruerar normalt inte FileUpload direkt.

filename: str

Filens ursprungliga namn så som klienten skickade det (ej betrott – skicka det inte till open() utan att sanera det).

content_type: str | None

MIME-typen från delens Content-Type-huvud, eller None om den inte angetts.

max_memory_size: int

Klassattribut. Tröskelvärde (i byte) över vilket copy() växlar från buffring i minnet till en temporär fil. Standard 1024.

async read(n: int = -1)

Läs upp till n byte från uppladdningsströmmen. -1 läser till slutet.

async save(path_or_file)

Spara uppladdningen till path_or_file, som kan vara en filsystemsökväg eller ett redan öppnat filobjekt.

async copy(max_memory_size: int | None = None)

Buffra uppladdningen (antingen i RAM eller i en temporär fil, beroende på max_memory_size) så att resten av multipart-kroppen kan tolkas utan att den ursprungliga strömmen ogiltigförklaras. Dekoratorn with_form_data() anropar detta automatiskt.

async close()

Frigör eventuell temporär fil som skapats av copy(). Anropas automatiskt när begäran avslutas om uppladdningen nådde request.files via with_form_data().

Dekoratorer på modulnivå

microdot.multipart.with_form_data(f)

Dekorator som tolkar multipart-kroppen i förväg och fyller i request.form och request.files innan hanteraren körs:

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'

Filuppladdningar buffras via FileUpload.copy(), så hanteraren kan iterera request.files och request.form fritt. Temporära filer städas upp automatiskt när begäran avslutas.

För uppladdningar större än ett par megabyte, föredra det strömmande API:et FormDataIter; with_form_data() ackumulerar hela begäran i minnet eller på filsystemet innan hanteraren körs.