Downloading two csv files using Download button

build a Streamlit app where the end result is two Pandas dataframes that I want the user to download as separate csv files. However, it seems the Download button in Streamlit only allows the downloading of one file. One way of “combining” them is to put them as separate tabs in an Excel file, but that is unacceptable to the ideal workflow.

I then created two download buttons for them, one for each file. However, clicking on the first Download button will cause the whole application to be rerun. After some Googling, there doesn’t seem a way to disable this behavior.

I then looked into creating a Zip file, using the ‘zipfile’ package:

               with zipfile.ZipFile('my_test.zip', 'x') as csv_zip:
                    csv_zip.writestr("data1.csv", pd.DataFrame(data1).to_csv())
                    csv_zip.writestr("data2.csv", pd.DataFrame(data2).to_csv())
                        
                    
                with open("my_test.zip", "rb") as file:
                    st.download_button(
                        label = "Download zip",
                        data = file,
                        file_name = "mydownload.zip",
                        mime = 'application/zip'
                
                    )

However, when tested locally, this creates ‘my_test.zip’ in the same directory where my .py codes are. The file would persist even after I end the app. My question:

  1. If I deploy the Streamlit app by hosting it somewhere, would ‘my_test.zip’ still be created somewhere? Where?
  2. Is there a way to enable the download of a zip file without first creating a zip file in a directory somewhere?

Thanks

You can pass a file-like object (like BytesIO) to ZipFile instead of a path.

Your code would become something like this (not tested):

buf = io.BytesIO()

with zipfile.ZipFile(buf, "x") as csv_zip:
    csv_zip.writestr("data1.csv", pd.DataFrame(data1).to_csv())
    csv_zip.writestr("data2.csv", pd.DataFrame(data2).to_csv())

st.download_button(
    label="Download zip",
    data=buf.getvalue(),
    file_name="mydownload.zip",
    mime="application/zip",
)
2 Likes

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.