How to Save Uploaded Files in FastAPI
Step-by-step guide to receive files and save them locally

The topic for today is on saving images or text files that users have uploaded to your FastAPI server locally in disk. If you have used Flask before, you should know that it comes with its own built-in file.save function for saving files. Unfortunately, such feature is not present in FastAPI at the time of this writing. In this tutorial, you will learn to implement this functionality based on your own use cases.
Single File
For your information, the bare minimum code for a simple FastAPI server that accepts an image or a file uploaded via FormData is as follows:
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
@app.post("/image")
async def image(image: UploadFile = File(...)):
return {"filename": image.filename}Python multipart
In order to receive the uploaded files, you need to install python-multipart. Run the following command in your terminal if you have to install it in your virtual environment.
pip install python-multipartFastAPI UploadFile
UploadFile uses Python SpooledTemporaryFile object which means that it is will be stored in memory as long the file size is within the size limit. Otherwise, it will be stored in disk once it exceeded the size limit.
Since it inherits from Starlette, it has the following attributes:
filename— Name of the file. It is based on the original file name uploaded.content_type— Content type of the file. For example, an JPEG image file should beimage/jpeg.file— Python file object.
In addition, UploadFile also comes with four additional async functions. Normally, you should call them together using await in a normal async function. In FastAPI, async methods are designed to run the file methods in a threadpool and it will await them. Hence, you can call these functions without await syntax.
write(data)— Writes data to the file. Accepts either string or bytes.read(size)— Reads n number of bytes or characters of the file based on the input parameter. Accepts an integer.seek(offset)— Moves to the byte or character position in the file. Usingseek(0)will go to the beginning of the file.close()— Closes the file
Saving File
Flask has a file.save wrapper function which allows you to save the uploaded file locally in your disk. The wrapper is based on the shutils.copyfileobj() function which is part of the Python standard library. However, there is no such implementation for FastAPI yet at the time of this writing.
You can easily implement it inside FastAPI server. First, you need to import the shutil module.
import shutilThe basic structure and code looks something like this.
with open("destination.png", "wb") as buffer:
shutil.copyfileobj(image.file, buffer)Simply call it inside your FastAPI methods. Have a look at the following code snippet.
async def image(image: UploadFile = File(...)):
with open("destination.png", "wb") as buffer:
shutil.copyfileobj(image.file, buffer)
return {"filename": image.filename}Re-run your FastAPI server and submit a form with a file attached to it from your front-end code. You should see a new file being generated based on the path that you have specified.
Multiple Files
For handling multiple files upload, you need to import the following statement
from typing import ListNext, modify the FastAPI method which take in a List of UploadFile.
async def image(images: List[UploadFile] = File(...)):Simply loop it using for loop and implement the save logic inside it.
for image in images:
with open(image.filename, "wb") as buffer:
shutil.copyfileobj(image.file, buffer)For more information on FastAPI, it is highly recommended to read the following articles:
- Migrate From Flask to FastAPI Smoothly
- 4 Useful Advanced Features in FastAPI
- Metadata and Additional Responses in FastAPI
Conclusion
Let’s recap what we have learned today.
We started off with a simple problem statement explaining the lack of wrapper function in FastAPI to save uploaded files.
Next, we explored in-depth on the fundamental concept behind UploadFile and how to use it inside FastAPI server.
We have also implemented a simple file saving functionality using the built-in shutil.copyfileobj method. Besides, we have also tried extending our server to handle multiple files upload.
Thanks for reading this piece. Hope to see you again in the next article!






