jackhammer013
jackhammer013

Reputation: 2295

Output CSV file for download without saving the csv in the server

I am working on a api end-point that will be available for public use using Python's Fast API framework. It is already done and working but the way it works is I will create it, then save to the local directory of the server then read that file and return a csv file as a response to the user.

My question is, how do I just return the csv file directly to the user without saving it in the server's directory. My code is like this right now

def export_client_invoice(client_id):

    invoice_doc = client_docs_db.view("client_invoice/by_client_id", key=int(client_id), include_docs=True)

    data = ["value %d" % i for i in range(1,4)]

    with open("./file.csv", 'w', newline='') as myfile:
    wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
    wr.writerow(data)

    file_like = open("./file.csv", mode="rb")
    response = StreamingResponse(file_like, media_type="text/csv")
    response.headers["Content-Disposition"] = "attachment; filename=export.csv"
    
return response

Upvotes: 1

Views: 2364

Answers (2)

Tho Bui Ngoc
Tho Bui Ngoc

Reputation: 835

@jackhammer013, You can using this code to return csv file with FastAPI

from fastapi.responses import StreamingResponse
... 
    return StreamingResponse(iter([file_like.getvalue()]),
                                             status_code=status.HTTP_200_OK,
                                             headers={
                                                 "Content-Disposition": f"attachment; filename=test.csv"
                                             },
                                             media_type="text/csv")

Upvotes: 0

Durtal
Durtal

Reputation: 1028

I cannot test it with fastapi, so you may have to adopt this a bit to make it work in your context.

from io import BytesIO
import csv
import codecs

data = ['value %d' % i for i in range(1,4)]

StreamWriter = codecs.getwriter('utf-8')
file_like = StreamWriter(BytesIO())

wr = csv.writer(file_like, quoting=csv.QUOTE_ALL)
wr.writerow(data)

print(file_like.getvalue())
# b'"value 1","value 2","value 3"\r\n'

response = StreamingResponse(file_like, media_type="text/csv")

Upvotes: 1

Related Questions