microdot.multipart --- Penguraian multipart/form-data

Mengurai badan permintaan Content-Type: multipart/form-data -- pengkodean yang digunakan browser untuk form yang menyertakan field <input type="file">. Dua jenis API:

  • Sebuah FormDataIter streaming yang menghasilkan field satu per satu -- berguna saat aplikasi harus menangani unggahan yang sangat besar secara bertahap pada perangkat dengan memori terbatas.

  • Sebuah dekorator with_form_data() yang mem-buffer semuanya dan mengisi request.form / request.files -- API yang nyaman untuk unggahan berukuran normal.

class FormDataIter

class microdot.multipart.FormDataIter(request)

Iterator async atas bagian-bagian dari badan multipart request. Nilai yang dihasilkan adalah tuple (name, value); value adalah str untuk field biasa dan FileUpload untuk field file.

Digunakan langsung ketika memori lebih penting daripada kemudahan:

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'

Catatan

Saat mengiterasi field file, file harus dikonsumsi (melalui FileUpload.read() atau FileUpload.save()) sebelum iterasi async for berikutnya -- stream yang mendasarinya menjadi tidak valid saat iterasi maju.

buffer_size: int

Atribut kelas. Ukuran potongan yang digunakan saat membaca dari stream permintaan. Default 256 byte. Tingkatkan untuk throughput lebih tinggi dengan biaya RAM.

class FileUpload

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

Sebuah file yang diunggah. Instans dihasilkan oleh FormDataIter dan dikumpulkan ke dalam request.files oleh with_form_data(). Aplikasi biasanya tidak membuat FileUpload secara langsung.

filename: str

Nama asli file seperti yang dikirimkan klien (tidak tepercaya -- jangan berikan ke open() tanpa sanitasi).

content_type: str | None

Tipe MIME dari header Content-Type bagian tersebut, atau None jika tidak disediakan.

max_memory_size: int

Atribut kelas. Ambang batas (dalam byte) di atas mana copy() beralih dari buffering dalam memori ke file sementara. Default 1024.

async read(n: int = -1)

Baca hingga n byte dari stream unggahan. -1 membaca sampai akhir.

async save(path_or_file)

Simpan unggahan ke path_or_file, yang dapat berupa jalur filesystem atau objek file yang sudah dibuka.

async copy(max_memory_size: int | None = None)

Buffer unggahan (baik dalam RAM atau file temp, tergantung pada max_memory_size) agar sisa badan multipart dapat diurai tanpa stream asli menjadi tidak valid. Dekorator with_form_data() memanggil ini secara otomatis.

async close()

Lepaskan file sementara yang dibuat oleh copy(). Dipanggil secara otomatis ketika permintaan selesai jika unggahan mencapai request.files melalui with_form_data().

Dekorator tingkat modul

microdot.multipart.with_form_data(f)

Dekorator yang mengurai badan multipart di depan dan mengisi request.form dan request.files sebelum handler berjalan:

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'

Unggahan file di-buffer melalui FileUpload.copy(), sehingga handler dapat mengiterasi request.files dan request.form dengan bebas. File sementara dibersihkan secara otomatis ketika permintaan berakhir.

Untuk unggahan yang lebih besar dari beberapa megabyte, lebih baik gunakan API FormDataIter streaming; with_form_data() mengumpulkan seluruh permintaan dalam memori atau di filesystem sebelum handler berjalan.