microdot.multipart --- Phân tích cú pháp multipart/form-data

Phân tích nội dung yêu cầu Content-Type: multipart/form-data -- mã hóa mà trình duyệt sử dụng cho các form bao gồm các trường <input type="file">. Có hai loại API:

  • FormDataIter phát trực tuyến, trả về từng trường một lần -- hữu ích khi ứng dụng phải xử lý các lượt tải lên rất lớn từng phần trên thiết bị bị hạn chế bộ nhớ.

  • Decorator with_form_data() đệm tất cả và điền vào request.form / request.files -- API thuận tiện cho các lượt tải lên kích thước thông thường.

class FormDataIter

class microdot.multipart.FormDataIter(request)

Iterator bất đồng bộ trên các phần của nội dung multipart trong request. Các giá trị được trả về là các bộ tuple (name, value); valuestr cho các trường thông thường và FileUpload cho các trường tệp.

Sử dụng trực tiếp khi bộ nhớ quan trọng hơn tiện lợi:

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'

Ghi chú

Khi lặp qua các trường tệp, tệp phải được tiêu thụ (qua FileUpload.read() hoặc FileUpload.save()) trước lần lặp async for tiếp theo -- luồng cơ bản sẽ bị vô hiệu hóa khi quá trình lặp tiến lên.

buffer_size: int

Thuộc tính lớp. Kích thước chunk được sử dụng khi đọc từ luồng yêu cầu. Mặc định là 256 byte. Tăng lên để có thông lượng cao hơn với chi phí RAM.

class FileUpload

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

Một tệp được tải lên đơn lẻ. Các phiên bản được trả về bởi FormDataIter và được thu thập vào request.files bởi with_form_data(). Các ứng dụng thường không khởi tạo FileUpload trực tiếp.

filename: str

Tên gốc của tệp như client đã gửi (không đáng tin cậy -- không truyền vào open() mà không kiểm tra vệ sinh).

content_type: str | None

Loại MIME từ header Content-Type của phần, hoặc None nếu không được cung cấp.

max_memory_size: int

Thuộc tính lớp. Ngưỡng (tính bằng byte) mà trên đó copy() chuyển từ đệm trong bộ nhớ sang tệp tạm thời. Mặc định là 1024.

async read(n: int = -1)

Đọc tối đa n byte từ luồng tải lên. -1 đọc đến cuối.

async save(path_or_file)

Lưu lượt tải lên vào path_or_file, có thể là đường dẫn hệ thống tệp hoặc một đối tượng tệp đã mở.

async copy(max_memory_size: int | None = None)

Đệm lượt tải lên (trong RAM hoặc trong tệp tạm thời, tùy thuộc vào max_memory_size) để phần còn lại của nội dung multipart có thể được phân tích mà không bị vô hiệu hóa luồng gốc. Decorator with_form_data() gọi điều này tự động.

async close()

Giải phóng bất kỳ tệp tạm thời nào được tạo bởi copy(). Được gọi tự động khi yêu cầu kết thúc nếu lượt tải lên đã đến request.files qua with_form_data().

Decorator cấp mô-đun

microdot.multipart.with_form_data(f)

Decorator phân tích nội dung multipart trước và điền vào request.formrequest.files trước khi handler chạy:

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'

Các lượt tải lên tệp được đệm qua FileUpload.copy(), vì vậy handler có thể lặp qua request.filesrequest.form tự do. Các tệp tạm thời được dọn dẹp tự động khi yêu cầu kết thúc.

Đối với các lượt tải lên lớn hơn vài megabyte, hãy ưu tiên API phát trực tuyến FormDataIter; with_form_data() tích lũy toàn bộ yêu cầu trong bộ nhớ hoặc trên hệ thống tệp trước khi handler chạy.