A multipart form is a type of HTML form that allows you to send multiple parts of data in a single HTTP request. Each part can have its own content type, such as text/plain for text fields and image/jpeg for image files. The parts are separated by a boundary, which is specified in the request headers.
File uploads involve sending a file from a client (usually a web browser) to a server. In the context of FastAPI, the server needs to receive the file, validate it, and potentially store it in a suitable location.
First, make sure you have Python installed on your system. Then, create a virtual environment and install FastAPI and Uvicorn (a server for running FastAPI applications).
# Create a virtual environment
python -m venv myenv
# Activate the virtual environment
# On Windows
myenv\Scripts\activate
# On Linux/Mac
source myenv/bin/activate
# Install FastAPI and Uvicorn
pip install fastapi uvicorn
Let’s start by creating a simple FastAPI application that can handle a multipart form with text fields.
from fastapi import FastAPI, Form
app = FastAPI()
@app.post("/submit-form/")
async def submit_form(name: str = Form(...), age: int = Form(...)):
return {"name": name, "age": age}
In this code:
FastAPI
and Form
from the fastapi
library./submit-form/
that expects two form fields: name
and age
.Form(...)
indicates that these fields are required.To run the application, use the following command:
uvicorn main:app --reload
You can test the form using a tool like curl
or Postman. Here’s an example using curl
:
curl -X POST "http://127.0.0.1:8000/submit-form/" -H "Content-Type: multipart/form-data" -F "name=John" -F "age=30"
Now, let’s see how to handle file uploads in FastAPI.
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
@app.post("/upload-file/")
async def upload_file(file: UploadFile = File(...)):
contents = await file.read()
# Here you can save the file to a specific location
# For example, to save it in the current directory:
with open(file.filename, "wb") as f:
f.write(contents)
return {"filename": file.filename}
In this code:
File
and UploadFile
from the fastapi
library./upload-file/
that expects a single file upload.UploadFile
is a class that represents an uploaded file. It has methods like read()
to read the file contents.To test the file upload using curl
:
curl -X POST "http://127.0.0.1:8000/upload-file/" -H "Content-Type: multipart/form-data" -F "file=@path/to/your/file.txt"
Always validate the input received from forms and file uploads. For text fields, you can use Python’s built-in validation or third - party libraries like pydantic
. For file uploads, validate the file type, size, and other relevant properties.
from fastapi import FastAPI, File, UploadFile
from fastapi.exceptions import HTTPException
app = FastAPI()
@app.post("/upload-validated-file/")
async def upload_validated_file(file: UploadFile = File(...)):
if file.content_type not in ["image/jpeg", "image/png"]:
raise HTTPException(status_code=400, detail="Invalid file type. Only JPEG and PNG are allowed.")
contents = await file.read()
# Save the file
with open(file.filename, "wb") as f:
f.write(contents)
return {"filename": file.filename}
Properly handle errors that may occur during form submissions or file uploads. Return meaningful error messages to the client.
Use asynchronous operations when reading or writing files, especially in a high - traffic application. This helps to avoid blocking the event loop and improves the overall performance of the application.
In this blog post, we’ve covered the fundamental concepts of creating multipart forms and handling file uploads with FastAPI. We’ve seen how to set up a FastAPI project, create simple multipart forms, handle file uploads, and discussed common and best practices. By following these guidelines, you can build robust and secure web applications that can handle user input and file uploads effectively.