Last modified: Dec 01, 2025 By Alexander Williams
FastAPI File Upload Download Tutorial
FastAPI makes file handling easy. It is a modern Python web framework. You can upload and download files fast. This guide shows you how.
You will learn to build file APIs. We cover single and multiple files. Security and best practices are also included.
This tutorial is for beginners. Basic Python knowledge is helpful. If you are new, start with a FastAPI Tutorial: Build Your First Python REST API.
Setting Up Your FastAPI Project
First, install FastAPI and an ASGI server. Use pip for installation. Ensure you have Python 3.7+.
pip install fastapi uvicorn python-multipart
The python-multipart package is key. It parses file uploads. If you face issues, see How to Install FastAPI in Python.
Create a new Python file. Name it main.py. Import FastAPI and other modules.
from fastapi import FastAPI, File, UploadFile
from fastapi.responses import FileResponse
import os
app = FastAPI()
# Directory to save uploaded files
UPLOAD_DIR = "uploads"
os.makedirs(UPLOAD_DIR, exist_ok=True)
We set up a basic app. An upload directory is created. Files will be saved there.
Uploading a Single File
Use the UploadFile class. It handles files efficiently. It stores data in memory or disk.
Create a POST endpoint. Use File(...) as a parameter. This reads the uploaded file.
@app.post("/upload/single/")
async def upload_single_file(file: UploadFile = File(...)):
"""
Upload a single file.
"""
file_location = os.path.join(UPLOAD_DIR, file.filename)
# Save the file
with open(file_location, "wb") as f:
content = await file.read()
f.write(content)
return {
"filename": file.filename,
"content_type": file.content_type,
"saved_at": file_location
}
The await file.read() gets file bytes. They are written to disk. Metadata is returned as JSON.
Test it with a client. Use curl or an API tool. Here is a curl example.
curl -X POST "http://localhost:8000/upload/single/" \
-F "file=@/path/to/your/image.jpg"
You should get a JSON response. It confirms the upload.
Uploading Multiple Files
FastAPI supports multiple files. Use a list of UploadFile. This is great for bulk uploads.
@app.post("/upload/multiple/")
async def upload_multiple_files(files: list[UploadFile] = File(...)):
"""
Upload multiple files at once.
"""
saved_files = []
for file in files:
file_location = os.path.join(UPLOAD_DIR, file.filename)
with open(file_location, "wb") as f:
content = await file.read()
f.write(content)
saved_files.append({
"filename": file.filename,
"location": file_location
})
return {"uploaded_files": saved_files}
The endpoint loops through each file. Each is saved individually. A list of results is returned.
Use curl to send multiple files. Specify each with a separate -F flag.
curl -X POST "http://localhost:8000/upload/multiple/" \
-F "[email protected]" \
-F "[email protected]"
Ensure the parameter name matches. Here it is "files".
Downloading Files
Downloading is simple. Use FileResponse. It streams the file to the client.
Create a GET endpoint. It takes a filename as a path parameter.
@app.get("/download/{filename}")
async def download_file(filename: str):
"""
Download a file by its filename.
"""
file_path = os.path.join(UPLOAD_DIR, filename)
# Check if file exists
if not os.path.exists(file_path):
return {"error": "File not found"}
return FileResponse(
path=file_path,
filename=filename,
media_type="application/octet-stream"
)
The FileResponse handles headers. It sets the correct content type. The file is sent as an attachment.
Access the endpoint in a browser. Or use curl to download.
curl -O -J "http://localhost:8000/download/myfile.pdf"
The file will save locally. The -O and -J flags help with naming.
Security and Best Practices
File uploads can be risky. Always validate inputs. Restrict file types and sizes.
Use FastAPI's built-in validation. Check the file size and extension.
from fastapi import HTTPException
ALLOWED_EXTENSIONS = {"jpg", "jpeg", "png", "pdf"}
MAX_FILE_SIZE = 5 * 1024 * 1024 # 5 MB
@app.post("/upload/secure/")
async def upload_secure_file(file: UploadFile = File(...)):
# Check file extension
file_ext = file.filename.split(".")[-1].lower()
if file_ext not in ALLOWED_EXTENSIONS:
raise HTTPException(400, detail="File type not allowed")
# Check file size by reading first
content = await file.read()
if len(content) > MAX_FILE_SIZE:
raise HTTPException(400, detail="File too large")
# Reset file cursor for saving
await file.seek(0)
file_location = os.path.join(UPLOAD_DIR, file.filename)
with open(file_location, "wb") as f:
f.write(content)
return {"message": "File uploaded securely"}
Validation is critical. It prevents malicious uploads. Always limit size and type.
Store files outside the web root. Use environment variables for paths. Never trust user input.
For database operations, combine with ORMs. Learn more in the FastAPI SQLAlchemy CRUD Guide.
Handling Large Files Efficiently
Large files need care. Reading them all into memory can crash your app. Use streaming instead.
FastAPI's UploadFile can stream to disk. Use file.file to get a file-like object.
@app.post("/upload/large/")
async def upload_large_file(file: UploadFile = File(...)):
file_location = os.path.join(UPLOAD_DIR, file.filename)
# Stream the file to disk in chunks
with open(file_location, "wb") as f:
while chunk := await file.read(8192): # 8KB chunks
f.write(chunk)
return {"message": "Large file uploaded via streaming"}
This reads the file in 8KB chunks. Memory usage stays low. It is safe for very large files.
For downloads, FileResponse also streams. It does not load the entire file.
Common Issues and Fixes
You might face import errors. Ensure FastAPI is installed correctly. If you see "No module named FastAPI", follow the guide on Fix Python ImportError: No Module Named FastAPI.
File uploads might fail. Check the python-multipart installation. It is required for form data.
Permissions can cause errors. Ensure the upload directory is writable. Use absolute paths for clarity.
To remove FastAPI, use pip uninstall. See How to Uninstall FastAPI in Python for details.
Conclusion
FastAPI simplifies file handling. Uploads and downloads are straightforward. You learned to manage single and multiple files.
Security practices are essential. Always validate and limit files. Use streaming for large files.
Combine these skills with database operations. Build robust web applications. FastAPI is powerful and fast.
Start building your file API today. Experiment with the code examples. Happy coding!