
์น ์ ํ๋ฆฌ์ผ์ด์ ์์ ํ์ผ ์ ๋ก๋๋ ์ ํ ๊ธฐ๋ฅ์ด ์๋๋ค.
ํ๋กํ ์ด๋ฏธ์ง, ์ฒจ๋ถ ํ์ผ, ๋ฌธ์ ์ ๋ก๋, ์ด๋ฏธ์ง ๋ถ์, ๋จธ์ ๋ฌ๋ ๋ฐ์ดํฐ ์์ง๊น์ง ํ๋ ์น ์๋น์ค์ ๊ฑฐ์ ๋ชจ๋ ์์ญ์์ ์ฌ์ฉ๋๋ค.
์ด๋ฒ ๊ธ์์๋ FastAPI์์ ํ์ผ ์ ๋ก๋๊ฐ ์ด๋ป๊ฒ ๋์ํ๋์ง, ์ UploadFile์ ์จ์ผ ํ๋์ง, ๊ทธ๋ฆฌ๊ณ ์ค๋ฌด์์ ๋ฐ๋์ ์์์ผ ํ ํต์ฌ ๊ฐ๋ ๋ง ์ ๋ฆฌํ๋ค.
ํ์ผ ์ ๋ก๋๋ ๋จ์ํ โ๋ฐ์ดํฐ ํ๋ ๋ณด๋ด๊ธฐโ๊ฐ ์๋๋ค.
ํ์ผ์ ๋ค์๊ณผ ๊ฐ์ ํน์ง์ ๊ฐ์ง๋ค.
๊ทธ๋์ ํ์ผ ์ ๋ก๋๋ JSON์ด๋ Query Parameter๋ก ์ฒ๋ฆฌํ ์ ์๋ค.
FastAPI์์ ํ์ผ ์ ๋ก๋๋ฅผ ์ฒ๋ฆฌํ๋ ค๋ฉด python-multipart ํจํค์ง๊ฐ ํ์๋ค.
pip install python-multipart
์ด ํจํค์ง๋ ์์ฒญ์ ๋ค์์ฒ๋ผ ์ฒ๋ฆฌํ๋ค.
FastAPI๋ ํ์ผ์ ๋ฐ๋ ๋ฐฉ์์ ์๋์ ์ผ๋ก ๋ ๊ฐ์ง ์ ๊ณตํ๋ค.
from typing import Annotated
from fastapi import FastAPI, File
app = FastAPI()
@app.post("/files/")
async def create_file(
file: Annotated[bytes, File()]
):
return {"file_size": len(file)}
์ด ๋ฐฉ์์ ํน์ง์ ๋ช ํํ๋ค.
from fastapi import FastAPI, UploadFile
app = FastAPI()
@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
return {"filename": file.filename}
์ด ๋ฐฉ์์ด ์ค๋ฌด ํ์ค!
| ๊ตฌ๋ถ | bytes | UploadFile |
|---|---|---|
| ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ | ํ์ผ ์ ์ฒด | ํ์ํ ๋งํผ๋ง |
| ๋์ฉ๋ ํ์ผ | โ ์ํ | โ ์์ |
| ๋ฉํ๋ฐ์ดํฐ | ์์ | ํ์ผ๋ช , ํ์ ์ ๊ณต |
| ์ค๋ฌด ์ ํฉ์ฑ | ๋ฎ์ | ๋งค์ฐ ๋์ |
ํ์ผ ์ ๋ก๋ ์์ฒญ์ ๋ด๋ถ์ ์ผ๋ก ์ด๋ ๊ฒ ํ๋ฌ๊ฐ๋ค.
[๋ธ๋ผ์ฐ์ ํ์ผ ์ ํ]
โ
POST ์์ฒญ: Content-Type: multipart/form-data
โ
python-multipart ํ์ฑ
โ
ํ์ผ / ํ
์คํธ ๋ถ๋ฆฌ
โ
FastAPI ํ๋ผ๋ฏธํฐ ์ฃผ์
์ด๋ ์ค์ํ ๊ท์น์ด ํ๋ ์๋ค.
์ด๊ฑด FastAPI ์ ์ฝ์ด ์๋๋ผ HTTP ํ๋กํ ์ฝ ๊ท์น
@app.post("/upload/")
async def upload(file: UploadFile):
print(file.filename)
print(file.content_type)
print(file.file)
| ์์ฑ | ์ค๋ช |
|---|---|
| filename | ์๋ณธ ํ์ผ๋ช |
| content_type | MIME ํ์ (image/png, application/pdf ๋ฑ) |
| file | SpooledTemporaryFile ๊ฐ์ฒด |
๋ชจ๋ ๋ฉ์๋๋ async๋ค.
@app.post("/upload/")
async def upload(file: UploadFile):
contents = await file.read()
await file.seek(0)
contents_again = await file.read()
await file.close()
| ๋ฉ์๋ | ์ญํ |
|---|---|
| read() | ํ์ผ ์ฝ๊ธฐ |
| seek(0) | ์ฝ๊ธฐ ์์น ์ด๊ธฐํ |
| close() | ํ์ผ ๋ซ๊ธฐ |
@app.post("/upload/")
async def upload(file: UploadFile | None = None):
if not file:
return {"message": "ํ์ผ์ด ์์ต๋๋ค"}
return {"filename": file.filename}
ํต์ฌ์ ๋ ๊ฐ์ง๋ค.
| None โ ํ์
ํํธ= None โ ๊ธฐ๋ณธ๊ฐ@app.post("/uploadfiles/")
async def upload_files(files: list[UploadFile]):
return {
"filenames": [file.filename for file in files]
}
HTML์์๋ multiple ์์ฑ์ด ํ์ํ๋ค.
<input type="file" name="files" multiple>
Form Data๋ ๋ค์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์กด์ฌํ๋ค.
๊ทธ๋์ HTTP๋ ํ์ผ ์ ์ก์ ์ํด multipart/form-data๋ผ๋ ์ธ์ฝ๋ฉ ๋ฐฉ์์ ์ ๊ณตํ๋ค.
ํ์ผ ์ ๋ก๋๊ฐ ํฌํจ๋ ์์ฒญ์ ๋ด๋ถ์ ์ผ๋ก ๋ค์ ์์๋ก ์ฒ๋ฆฌ๋๋ค.
[ํด๋ผ์ด์ธํธ (๋ธ๋ผ์ฐ์ )]
โ
โ ํ์ผ ์ ํ
โผ
POST ์์ฒญ
Content-Type: multipart/form-data
โ
โผ
python-multipart
(์์ฒญ ํ์ฑ)
โ
โโ ํ
์คํธ ํ๋
โโ ํ์ผ ๋ฐ์ดํฐ
โ
โผ
FastAPI
(File / UploadFile)