Sling Academy
Home/FastAPI/How to Return a CSV File in FastAPI

How to Return a CSV File in FastAPI

Last updated: March 19, 2023

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.

Next Article: 3 Ways to Get User’s IP Address in FastAPI

Previous Article: Getting the Request Body in FastAPI

Series: FastAPI Request & Response Tutorials

FastAPI

You May Also Like

  • Popular useful built-in Jinja filters you should know
  • How to remove consecutive whitespace in rendered Jinja pages
  • How to format large numbers with thousand separators in Jinja template
  • How to format date time in Jinja templates
  • FastAPI + Jinja: How to create custom filters
  • How to pass variables from Python (FastAPI) to Jinja
  • How to decode Jinja response to string
  • How to create and use macros in Jinja
  • How to use namespace in Jinja
  • How to use if/ else in Jinja
  • How to use loops in Jinja
  • FastAPI + SQLAlchemy: Using cursor-based pagination
  • FastAPI: How to use macros in Jinja templates
  • Fixing Common Swagger UI Errors in FastAPI
  • FastAPI Error: 307 Temporary Redirect – Causes and Solutions
  • FastAPI Error: Expected UploadFile, received ‘str’
  • Resolving FastAPI ImportError: No Known Parent Package
  • FastAPI Error: No module named ‘pydantic_core._pydantic_core’
  • Resolving FastAPI 422 Error: Value is not a valid dict