pip install python-multipart
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
@app.post("/files/")
async def create_file(file: bytes = File()):
return {"file_size": len(file)}
@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
return {"filename": file.filename}
- 클라이언트가 업로드한 파일들을 정의할 수 있다.
- File은 Form을 상속받은 클래스다.
- 파일들은 Form 데이터 형태로 업로드 된다.
- operation function 매개변수를 bytes로 선언한 경우 파일을 읽고 bytes 형태의 내용을 전달한다.
- UploadFile을 사용할 경우 bytes에 비해 몇가지 장점이 있다.
- Spool File 사용
- 최대 크기 제한까지만 메모리에 저장, 초과하는 경우 디스크에 저장
- 이미지, 동영상, 큰 이진코드 같은 대용량 파일을 많은 메모리를 소모하지 않고 처리하기에 적합하다.
- 업로드 된 파일의 메타데이터를 얻을 수 있다.
- file-like async 인터페이스를 갖고있다.
- 다른 라이브러리에 직접적으로 전달할 수 있는 SpooledtemporaryFile 객체를 반환한다.
UploadFile
- attribute
- filename : 문자열로 업로드된 파일의 파일명
- content_type : 파일 형식(MIME type/media type)
- file : SpooledTemporaryFile 객체 -> 다른 라이브러리에 직접적으로 전달할 수 있는 파이선 파일
- write(data) : data(str or bytes)를 파일에 작성
- read(size) : 파일의 바이트 및 size를 읽는다.
- seek(offset) : 파일 내 offset 위치의 바이트로 이동
- await myfile.seek(0) 사용 시 파일 시작부분으로 이동
- await myfile.read() 사용 후 내용 다시 읽은 때 유용
- close() : 파일 닫기
contents = await myfile.read()
- async 경로 작동 함수의 내부에서 위 처럼 선언해서 내용을 가져올 수 있다.
- async method 사용 시 FastAPI는 스레드 풀에서 파일 메소드들을 실행하고 결과를 기다린다.
contents = myfile.read()
- HTML의
<form> </form>이 서버에 데이터를 전송하는 방식은 JSON과는 다른 특별한 인코딩을 사용한다.
- 파일이 포함되어 있지 않은 경우 일반적으로 미디어 유형으로
application/x-www-form-urlencoded를 사용해 인코딩 된다.
- 파일이 포함된 경우
multipart/form-data로 인코딩 된다.
다중 파일 업로드
from typing import List
from fastapi import FastAPI, File, UploadFile
from fastapi.responses import HTMLResponse
app = FastAPI()
@app.post("/files/")
async def create_files(files: List[bytes] = File()):
return {"file_sizes": [len(file) for file in files]}
@app.post("/uploadfiles/")
async def create_upload_files(files: List[UploadFile]):
return {"filenames": [file.filename for file in files]}
@app.get("/")
async def main():
content = """
<body>
<form action="/files/" enctype="multipart/form-data" method="post">
<input name="files" type="file" multiple>
<input type="submit">
</form>
<form action="/uploadfiles/" enctype="multipart/form-data" method="post">
<input name="files" type="file" multiple>
<input type="submit">
</form>
</body>
"""
return HTMLResponse(content=content)
- bytes의 list or UploadFile들을 전송받게 된다.