BudiBadu Logo
Samplebadu

FastAPI by Example: File Response Handling

FastAPI 0.100+

Serving files efficiently is a common requirement. This sample code shows how to use `FileResponse` to stream files from the server to the client asynchronously.

Code

from fastapi import FastAPI
from fastapi.responses import FileResponse
import os

app = FastAPI()

# Create a dummy file for the example
file_path = "example.txt"
with open(file_path, "w") as f:
    f.write("This is a sample file content.")

@app.get("/download")
async def download_file():
    return FileResponse(
        path=file_path, 
        filename="downloaded_file.txt",
        media_type="text/plain"
    )

@app.get("/image")
async def get_image():
    # Assuming you have an image file
    # If filename is not provided, it uses the file's name
    return FileResponse("logo.png")

Explanation

The FileResponse class is the standard way to send files from the server to the client in FastAPI. Unlike returning a large bytes object, which loads the entire file into memory, FileResponse streams the file in chunks. This approach is highly memory-efficient and allows your application to serve large files (like videos or datasets) without crashing the server or spiking RAM usage.

One of the key features of FileResponse is its ability to manage HTTP headers automatically. It calculates and sets the Content-Length header so the client knows the file size, and it attempts to guess the correct Content-Type based on the file extension. You can also explicitly control the Content-Disposition header using the filename parameter, which forces the browser to download the file instead of attempting to display it inline.

Under the hood, FastAPI runs file operations in a separate thread pool to ensure they do not block the main event loop. This means that even if a file takes a long time to read from a slow disk, your API remains responsive to other incoming requests. For even better performance with massive concurrency, you can install aiofiles, which allows FastAPI to use true asynchronous file I/O.

Code Breakdown

14
FileResponse(path=...) initiates the file transfer. The path must point to a valid file on the server's filesystem.
16
filename="downloaded_file.txt" sets the Content-Disposition header to attachment, forcing a download dialog in the browser.
17
media_type manually sets the MIME type. While FastAPI can guess it, being explicit prevents security issues like MIME sniffing.
24
If filename is omitted, the browser will try to display the file inline (e.g., opening a PDF or showing an image) instead of saving it.