FastAPI handles HTML form data (Form) and file uploads (File/UploadFile) — distinct from JSON bodies, since they use different content types (). Both are declared with special parameter types.
FastAPI handles HTML form data (Form) and file uploads (File/UploadFile) — distinct from JSON bodies, since they use different content types (). Both are declared with special parameter types.
multipart/form-datafrom fastapi import Form
@app.post("/login")
def login(username: str = Form(), password: str = Form()): # form fields, not JSON
# data comes as application/x-www-form-urlencoded or multipart/form-data
return {"username": username}
Use Form() to receive HTML form fields (e.g. a login form). Note: a route can use either a JSON body or form data, not both, since they're different content types. (Requires python-multipart installed.)
from fastapi import File, UploadFile
@app.post("/upload")
async def upload(file: UploadFile): # a single file
contents = await file.read() # read the file's bytes
file.filename # original name
file.content_type # MIME type
# save it:
with open(f"uploads/{file.filename}", "wb") as f:
f.write(contents)
return {"filename": file.filename, "size": len(contents)}
UploadFile is the recommended type — it's a spooled file (large files go to disk, not all in memory), with async methods (read, write, seek) and metadata. Use it over raw bytes for anything but tiny files.
@app.post("/upload-many")
async def upload_many(files: list[UploadFile]): # multiple files
return [f.filename for f in files]
@app.post("/profile")
async def profile(name: str = Form(), avatar: UploadFile = File()):
# combine form fields AND a file upload in one multipart request
...
if file.content_type not in ["image/jpeg", "image/png"]: # check type
raise HTTPException(400, "Invalid file type")
# also: limit file SIZE, sanitize filenames, scan content — uploads are untrusted input
Handling form data and file uploads is a common, practical need — login forms, profile picture uploads, document submissions, and file-processing APIs all require it, and it works differently from the JSON bodies FastAPI uses by default.
Understanding Form() for form fields and especially UploadFile for uploads (the recommended approach, since it spools large files to disk rather than loading everything into memory — important for handling big files without exhausting RAM) is necessary for these features.
Equally important is the security responsibility that comes with uploads: since uploaded files are untrusted input, validating their type and size, sanitizing filenames, and being careful how you store/serve them is essential to avoid vulnerabilities.
Knowing how to receive form fields, handle single and multiple file uploads, combine forms with files, and validate uploads safely is practical knowledge for building real-world APIs that accept user-submitted content.
A library of IT interview questions with detailed answers — from Junior to Senior.
Donate