Uploading Files
File uploads arrive as multipart/form-data: the client streams a binary payload with a filename. FastAPI reads uploads with the UploadFile parameter (which wraps the spooled file, giving you .filename, .content_type, and async read methods) and File parameters for plain form fields sent alongside.
Basic Upload
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
@app.post("/upload/")
async def upload(file: UploadFile):
content = await file.read()
return {
"filename": file.filename,
"content_type": file.content_type,
"size": len(content),
}
Upload it:
curl -X POST http://127.0.0.1:8000/upload/ \
-F "[email protected]"
Saving to Disk
Read in chunks so large files do not consume all memory, and write to a safe path (sanitize the filename):
import os
from pathlib import Path
UPLOAD_DIR = Path("uploads")
UPLOAD_DIR.mkdir(exist_ok=True)
@app.post("/upload/")
async def upload(file: UploadFile):
dest = UPLOAD_DIR / (file.filename or "upload.bin")
with open(dest, "wb") as f:
while chunk := await file.read(1024 * 1024):
f.write(chunk)
return {"saved": str(dest)}
Multiple Files
@app.post("/upload-many/")
async def upload_many(files: list[UploadFile]):
return [
{"filename": f.filename, "size": len(await f.read())}
for f in files
]
Files with Form Fields
from fastapi import File, Form, UploadFile
@app.post("/profile/")
async def profile(avatar: UploadFile, nickname: str = Form()):
content = await avatar.read()
return {"nickname": nickname, "avatar_bytes": len(content)}
Summary
Declare UploadFile parameters to receive multipart file uploads, read them in chunks with await file.read(), sanitize filenames before writing to disk, and use list[UploadFile] for multiple files. Plain form fields travel alongside files via File()/Form() parameters.