microdot.multipart — multipart/form-data 파싱

Content-Type: multipart/form-data 요청 본문 – 브라우저가 <input type="file"> 필드를 포함하는 폼에 사용하는 인코딩 – 을 파싱합니다. 두 가지 종류의 API가 있습니다:

  • 필드를 한 번에 하나씩 산출하는 스트리밍 FormDataIter – 애플리케이션이 메모리가 제한된 장치에서 매우 큰 업로드를 조각 단위로 처리해야 할 때 유용합니다.

  • 모든 것을 버퍼링하여 request.form / request.files 를 채우는 with_form_data() 데코레이터 – 일반적인 크기의 업로드에 편리한 API입니다.

class FormDataIter

class microdot.multipart.FormDataIter(request)

request 의 multipart 본문 부분(part)에 대한 비동기 반복자입니다. 산출되는 값은 (name, value) 튜플입니다. value 는 일반 필드의 경우 str, 파일 필드의 경우 FileUpload 입니다.

편의성보다 메모리가 더 중요할 때 직접 사용합니다:

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'

참고

파일 필드를 반복할 때, 다음 async for 반복 전에 파일을 (FileUpload.read() 또는 FileUpload.save() 를 통해) 소비해야 합니다. 반복이 진행되면 기반 스트림이 무효화됩니다.

buffer_size: int

클래스 속성. 요청 스트림에서 읽을 때 사용하는 청크 크기. 기본값 256바이트. RAM을 더 사용하는 대가로 처리량을 높이려면 늘리십시오.

class FileUpload

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

업로드된 단일 파일입니다. 인스턴스는 FormDataIter 에 의해 산출되며 with_form_data() 에 의해 request.files 로 수집됩니다. 애플리케이션은 보통 FileUpload 를 직접 생성하지 않습니다.

filename: str

클라이언트가 보낸 파일의 원래 이름(신뢰할 수 없음 – 정제하지 않고 open() 에 전달하지 마십시오).

content_type: str | None

부분(part)의 Content-Type 헤더에서 가져온 MIME 타입, 또는 제공되지 않은 경우 None.

max_memory_size: int

클래스 속성. copy() 가 인메모리 버퍼링에서 임시 파일로 전환되는 (바이트 단위) 임계값. 기본값 1024.

async read(n: int = -1)

업로드 스트림에서 최대 n 바이트를 읽습니다. -1 은 끝까지 읽습니다.

async save(path_or_file)

업로드를 path_or_file 에 저장합니다. 이는 파일 시스템 경로이거나 이미 열려 있는 파일 객체일 수 있습니다.

async copy(max_memory_size: int | None = None)

(max_memory_size 에 따라 RAM 또는 임시 파일에) 업로드를 버퍼링하여, 원래 스트림이 무효화되지 않고 multipart 본문의 나머지 부분을 파싱할 수 있게 합니다. with_form_data() 데코레이터가 이를 자동으로 호출합니다.

async close()

copy() 가 생성한 임시 파일을 해제합니다. 업로드가 with_form_data() 를 통해 request.files 에 도달한 경우 요청이 끝날 때 자동으로 호출됩니다.

모듈 수준 데코레이터

microdot.multipart.with_form_data(f)

핸들러가 실행되기 전에 multipart 본문을 미리 파싱하고 request.formrequest.files 를 채우는 데코레이터입니다:

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'

파일 업로드는 FileUpload.copy() 를 통해 버퍼링되므로, 핸들러는 request.filesrequest.form 을 자유롭게 반복할 수 있습니다. 임시 파일은 요청이 끝날 때 자동으로 정리됩니다.

몇 메가바이트보다 큰 업로드의 경우 스트리밍 FormDataIter API를 사용하십시오. with_form_data() 는 핸들러가 실행되기 전에 전체 요청을 메모리나 파일 시스템에 누적합니다.