Last time, in Form Models, we grouped form fields into a Pydantic model. Forms often carry more than text, though. Think a profile picture or a document upload. For that, FastAPI gives you two tools: File and UploadFile.
The quick way: bytes
For a small file, declare the parameter as bytes with File(), and FastAPI hands you the raw contents.
from typing import Annotatedfrom fastapi import FastAPI, Fileapp = FastAPI()@app.post("/upload-bytes")async def upload_bytes(file: Annotated[bytes, File()]): return {"file_size": len(file)}Let's review:
File()tells FastAPI the value is an uploaded file, sent as form data.With type
bytes, FastAPI reads the whole file and gives you its contents directly.The catch: the entire file sits in memory. Fine for small files, risky for large ones.
Files need python-multipart installed, the same package as forms. Install it once with pip install python-multipart.
The better way: UploadFile
For anything bigger, use UploadFile. It streams to disk past a size limit and exposes useful metadata.
from fastapi import FastAPI, UploadFileapp = FastAPI()@app.post("/upload")async def upload(file: UploadFile): contents = await file.read() return {"filename": file.filename, "size": len(contents)}Let's review:
UploadFiledoes not needFile()in the default, just the type is enough.It gives you metadata like
file.filenameandfile.content_type.await file.read()reads the contents. It is async, so remember theawait.It is memory-friendly: a spooled file that moves to disk for large uploads, so big images and videos do not eat your RAM.
Multiple files
To accept several files at once, type the parameter as a list of UploadFile.
@app.post("/upload-many")async def upload_many(files: list[UploadFile]): return {"filenames": [f.filename for f in files]}You get a list back, one UploadFile per uploaded file. Loop over them as needed.
Reach for UploadFile over bytes for anything that is not tiny. The bytes approach loads the entire file into memory, so a few large uploads can knock your server over. UploadFile spools to disk and stays light. When unsure, pick UploadFile.
