In the last post, Request Files, we uploaded a file on its own. But a real upload form rarely sends just a file. A profile picture comes with a username, a document comes with a title. You need text fields and a file in the same request. FastAPI handles that by letting you mix Form and File.
Form and File together
Declare your form fields with Form() and your file with File() or UploadFile, side by side in one function.
from typing import Annotatedfrom fastapi import FastAPI, File, Form, UploadFileapp = FastAPI()@app.post("/upload")async def upload( title: Annotated[str, Form()], file: Annotated[UploadFile, File()],): return {"title": title, "filename": file.filename}Let's review:
titleusesForm(), so it is read as a form field.fileusesUploadFile, so it is read as the uploaded file.Both arrive together as form data, and FastAPI sorts each to the right spot.
Same setup note as before: this needs python-multipart installed.
That is the whole idea. You can add as many form fields as you like, and even mix bytes and UploadFile files in the same endpoint.
Gotcha: you still cannot add a JSON Body field here. Once a request carries files, the whole body is encoded as multipart/form-data, not JSON, so the two cannot share an endpoint. If you need structured data alongside a file, pass it as form fields instead. That is an HTTP rule, not a FastAPI limit. 😁
