How to Return a CSV File in FastAPI

Updated: March 19, 2023 By: Khue 3 comments

CSV stands for Comma Separated Values. It is a plain text file that stores data by delimiting data entries with commas. CSV files are popular in Python apps because they are easy to read and write using the built-in csv module. They are also useful for storing and processing large amounts of data efficiently.

This short article gives you two approaches to returning a CSV file in FastAPI.

Using FileResponse

This method is often used when your CSV file is already saved on the disk. The example below shows how to return a CSV file from a local path using FileResponse. It also sets the headers to indicate that it is an attachment with a filename and media type of text/csv.

The code:

from fastapi import FastAPI
from fastapi.responses import FileResponse

app = FastAPI()

@app.get("/data/", response_class=FileResponse)
async def read_data():
    file_path = "path/to/my_file.csv"
    response = FileResponse(file_path, media_type="text/csv")
    response.headers["Content-Disposition"] = "attachment; filename=downloaded_file.csv"
    return response

Sling Academy also uses this technique to serve sample datasets (for practicing purposes), like this one:

https://api.slingacademy.com/v1/sample-data/files/customers.csv

Using StreamingResponse

StreamingResponse allows you to send binary data as a stream without saving it to a file first. You can also modify the headers of the response to indicate that it is an attachment with a filename and media type of text/csv.

This example shows how to return a CSV file from a pandas dataframe using StreamingResponse:

import pandas as pd
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import io

app = FastAPI()


@app.get("/data/", response_class=StreamingResponse)
async def export_data():
    # Create a sample dataframe
    df = pd.DataFrame({'col1': [1, 2], 'col2': [3, 4]})
    stream = io.StringIO()
    df.to_csv(stream, index=False)
    response = StreamingResponse(
        iter([stream.getvalue()]), media_type="text/csv")
    response.headers["Content-Disposition"] = "attachment; filename=export.csv"
    return response

Sling Academy also uses the method you’ve seen in the example above to provide sample CSV datasets like this one:

https://api.slingacademy.com/v1/sample-data/files/employees.csv

The tutorial ends here. If you have any questions, please comment. We’re more than happy to hear your thoughts.

3 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments