Yeah I’m trying to find a way to include a download button for a pdf using Streamlit too.
Thank you so much for the solution! Is there any way we can download zip files? In that case, we can just compress all the stuff before downloading it and do not need to specify any format. Thanks!
Hey @wshuyi, welcome to the community.
I remember downloading a zip folder has been covered here : How to download local folder?
Fanilo
Thank you so much for the reply, Fanilo!
I’m still not able to download the image. What exactly is the object predicted_img? I tried inputting a wordcloud and a axessubplot, none of them worked.
I wrote a generic downloader that should work for any type of file that’s stored on your disk.
Though some developers may whine that this is not the right/optimal thing to do, well, who cares
So here you go.
The function:
import os
import base64
def get_binary_file_downloader_html(bin_file, file_label='File'):
with open(bin_file, 'rb') as f:
data = f.read()
bin_str = base64.b64encode(data).decode()
href = f'<a href="data:application/octet-stream;base64,{bin_str}" download="{os.path.basename(bin_file)}">Download {file_label}</a>'
return href
Usage:
st.markdown(get_binary_file_downloader_html('photo.jpg', 'Picture'), unsafe_allow_html=True)
st.markdown(get_binary_file_downloader_html('data.csv', 'My Data'), unsafe_allow_html=True)
st.markdown(get_binary_file_downloader_html('2g1c.mp4', 'Video'), unsafe_allow_html=True)
hi!
I get runtime error when I’m trying to download csv over 50 mb. Please help
Worked for me. Thanks a lot!
Hello GokulNC, this is a very nice job. I was wondering if your code could work for downloading a power point file ? Do you have any idea ? Thank you !
Yes ofcourse. It should work for any filetype.
But for large static files (say above 50MB), it might be better to upload it somewhere online and link it.
I use minio for such big downloads task, upload the file from streamlit to minio and add a hyperlink to it in your app. In addition you can use presigned objects with expiration time to make your download links more secure.
Super, I’ll try it and let you know how it goes.
Hi, can u get an example, please)
def get_minio_link(buffer, filename, content_type, bucket_name):
minio_client.put_object(
bucket_name,
filename,
data=buffer,
length=len(buffer.getvalue()),
content_type=content_type,
)
download_url = minio_client.presigned_get_object(
bucket_name,
filename)
return download_url
You can use it like this
csv_bytes = df.to_csv().encode("utf-8")
csv_buffer = BytesIO(csv_bytes)
filename = "mydf.csv"
content_type = "application/csv"
uri = get_minio_link(buffer=csv_buffer, filename=filename, content_type=content_type, bucket_name="my-bucket")
st.markdown(
f"""
<a href='{uri}' download>Click to Download {filename}</a>
""",
unsafe_allow_html=True,
)
Its untested but it should work if you feed a proper minio_client.
Psst. by default link will be available for 7 days. I would change expire to something less. https://docs.min.io/docs/python-client-api-reference.html#presigned_get_object
Hope it helps !
It worked for me with a PDF file. Thanks!
great!!! thanks very much!!
You can return this HTML to display a button instead of a link:
return f'<a href="data:file/txt;base64,{b64}" download="{download_filename}"><input type="button" value="Download"></a>'
Hi @sgoede,
I think you can try something with minio if you want more control over the file access. Refer to this answer, How to download file in streamlit
Hope it helps!
Hi @Bernardo_tod,
I’m using the same function. If i click the link that has been generated and displayed through markdown. the file not getting downloaded. can you help me with it?
Hi @Chad_Mitchell , thanks for the solution. It works great on my Windows 10 machine. I uploaded the script to a Ubuntu 16.04 server, but the text file I download has encoded base64 characters. Something like this:
"ZW1wbG95ZXIgcGxhbgpncmFuZGZhdGhlcmVkIGhlYWx0aCBwbGFuCm5ldyBjZW50ZXIgc3RhbXBpbmcKdG90YWwgaGVhbHRoIGNhcmUKcGxhbiBhZG1pbmlzdHJhdG9yCmh"
Any idea how I can download normal text? Not sure why it is happening only on my server though. Thanks in advance for your support!
Update:
I fixed it by making this change:
from
return f'<a href="data:file/txt;base64,{b64}" download="{download_filename}">{download_link_text}</a>'
to
return f'<a href="data:text/plain;base6 4,{object_to_download}" download="{download_filename}">{download_link_text}</a>'