출처: https://fastapi.tiangolo.com/tutorial/request-files/
출처: https://fastapi.tiangolo.com/tutorial/request-forms-and-files/
아래의 내용은 공식 사이트의 내용을 제 경험과 생각을 추가하여 다시 정리한 것 입니다.
File, UploadFile
fastapi는 파일 요청을 처리 하기 위해 File
과 UploadFile
을 제공합니다.
클라이언트에서 업로드 한 파일을 받기 위해서는 python-multipart
가 필요합니다. pip install python-multipart
로 설치 할 수 있습니다.
# File과 UploadFile import
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
# file은 기본값이 없으므로 필수 매개변수입니다.
# file은 클라이언트로 부터 업로드 된 파일을 나타냅니다.
# file 매개변수는 File() 유형이며 파일의 내용은 바이트(bytes) 형태로 제공됩니다.
@app.post("/files/")
async def create_file(file: bytes = File()):
return {"file_size": len(file)}
# file은 기본값이 없으므로 필수 매개변수입니다.
# file은 클라이언트로 부터 업로드 된 파일을 나타냅니다.
# file 매개변수는 UploadFile 유형이며 파일의 내용은 바이트(bytes) 형태로 제공됩니다.
@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
return {"filename": file.filename}
테스트를 위해 HTML 화면을 만드는 코드를 추가 합니다.
# 기존에서 추가된 import
from fastapi import FastAPI, File, UploadFile, Form
from fastapi.responses import HTMLResponse
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}
### 기존 코드 ###
### 테스트를 위해 HTML 화면을 만드는 코드를 추가 ###
@app.get("/", response_class=HTMLResponse)
async def get_upload_form():
return """
<html>
<head>
<title>Upload File</title>
</head>
<body>
<h1>Upload File</h1>
<form action="/files/" method="post" enctype="multipart/form-data">
<label for="file">Upload File (bytes):</label>
<input type="file" name="file" id="file">
<input type="submit" value="Upload">
</form>
<form action="/uploadfile/" method="post" enctype="multipart/form-data">
<label for="uploadfile">Upload File (UploadFile):</label>
<input type="file" name="file" id="uploadfile">
<input type="submit" value="Upload">
</form>
</body>
</html>
"""
테스트
http://localhost:8000/
위의 URL로 접속하면 아래와 같은 화면이 나옵니다.
업로드 할 파일을 선택합니다.
- 먼저 bytes 형태로 업로드 된 파일을 처리하는 /files/를 테스트 합니다.
Upload 버튼을 클릭하면 업로드 된 file의 size를 확인 할 수 있습니다.
- 두번째로 UploadFile 형태로 업로드 된 파일을 처리하는 /uploadfile/를 테스트 합니다.
Upload 버튼을 클릭하면 업로드 된 file의 이름을 확인 할 수 있습니다.
File, UploadFile 차이점
- File
- 파일의 내용을 바이트(bytes) 형태로 직접 받습니다.
- 업로드된 파일은 메모리에 저장됩니다. 이 방식은 작은 파일을 다룰 때 적합합니다.
- File을 사용하는 경우, 파일에 대한 추가적인 정보(예: 파일명, MIME 타입 등)에 접근하기 어렵습니다.
- UploadFile
- UploadFile은 비동기 방식으로 파일을 읽고 쓸 수 있는 메서드를 제공합니다. 이를 통해 FastAPI의 비동기 프로그래밍 모델과 잘 호환됩니다.
- 대용량 파일을 처리할 때, UploadFile은 파일을 메모리에 전부 저장하지 않고, 디스크에 임시 파일을 생성합니다. 이는 메모리 사용을 최소화하고, 큰 파일도 효율적으로 처리할 수 있게 해줍니다.
- UploadFile은 업로드된 파일과 관련된 추가 정보를 제공합니다. 예를 들어, file.filename은 업로드된 파일의 원래 이름을, file.content_type은 MIME 타입을 나타냅니다.
- 주요 메서드
- await file.read(size: int): 파일에서 지정된 크기만큼의 데이터를 비동기적으로 읽습니다.
- await file.write(data: bytes): 파일에 데이터를 비동기적으로 씁니다 (일반적으로는 사용되지 않음).
- await file.seek(offset: int): 파일의 지정된 위치로 포인터를 이동합니다.
- await file.close(): 파일을 닫습니다. 파일 작업을 마친 후에 호출하는 것이 좋습니다.
폼 데이터와 함께 파일 업로드
File
과 Form
을 사용하여 폼 데이터와 함께 파일을 업로드 할 수 있습니다.
File(File, UploadFkoe)과 폼 데이터
# File과 UploadFile, Form import
from fastapi import FastAPI, File, Form, UploadFile
app = FastAPI()
@app.post("/files/")
async def create_file(
# file은 bytes 형태로 업로드 된 파일
# fileb는 UploadFile 형태로 업로드 된 파일
# token은 폼 데이터
file: bytes = File(), fileb: UploadFile = File(), token: str = Form()
):
return {
"file_size": len(file),
"token": token,
"fileb_content_type": fileb.content_type,
}
테스트를 위해 HTML 화면을 만드는 코드를 추가 합니다.
# 기존에서 추가된 import
from fastapi import FastAPI, File, Form, UploadFile, Response
from fastapi.responses import HTMLResponse
app = FastAPI()
@app.post("/files/")
async def create_file(
file: bytes = File(), fileb: UploadFile = File(), token: str = Form()
):
return {
"file_size": len(file),
"token": token,
"fileb_content_type": fileb.content_type,
}
### 기존 코드 ###
### 테스트를 위해 HTML 화면을 만드는 코드를 추가 ###
@app.get("/", response_class=HTMLResponse)
async def get_upload_form():
return """
<html>
<head>
<title>Upload File</title>
</head>
<body>
<h1>Upload File</h1>
<form action="/files/" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="file" name="fileb">
<input type="text" name="token" placeholder="Token">
<input type="submit" value="Upload">
</form>
</body>
</html>
"""
테스트
http://localhost:8000/
위의 URL로 접속하면 아래와 같은 화면이 나옵니다.
업로드 할 파일 2개을 선택하고 폼 데이터(token)을 입력합니다.
Upload
버튼을 클릭하면 업로드 된 bytes file의 size와 UploadFile의 content_type, 그리고 폼 데이터(token)을 확인 할 수 있습니다.
'웹 프레임워크 > FastAPI' 카테고리의 다른 글
FastAPI - 13 (JSON 호환 인코더 / 본문 업데이트) (0) | 2023.12.19 |
---|---|
FastAPI - 12 (파일 업로드 / 파일 다운로드) (0) | 2023.12.19 |
FastAPI - 10 (폼 데이터 - Form Data) (0) | 2023.12.18 |
FastAPI - 09 (응답 상태 코드 - Response Status Code) (0) | 2023.12.18 |
FastAPI - 08 (응답 모델: Response Model) (0) | 2023.12.18 |