Hey Streamlit Fam! 👋
Say hello to a notable new feature in the 0.88.0 release:
st.download_button. Now your viewers can download data right from your Streamlit apps!
In this post, we'll go into more detail about the new download button and other updates.
✨ Release Highlight
⬇️ Download Button
Before this release, you had to hack your way to the download functionality within Streamlit. None of the hacks were great. And they didn't play well with the Streamlit Cloud platform.
st.download_button you can use the download functionality both locally and within our cloud platform.
Curious how it's built?
streamlit.download_button(label, data, file_name=None, mime=None, key=None, help=None, on_click=None, args=None, kwargs=None)
This will display a button for your viewers so they can download data locally to their machines.
str) – A short label explaining to the user what this button is for.
file) – The contents of the file to be downloaded.
str) - An optional string to use as the name of the file to be downloaded, eg. 'my_file.csv'. If file_name is not specified, a name will be automatically generated.
None) – The MIME type of the data. If data=str and MIME is unspecified, then MIME defaults to “text/plain”. If data=bytes and MIME is unspecified, then MIME defaults to “application/octet-stream”.
str) – An optional string to use as the unique key for the widget. If you omit this, a key will be generated for the widget based on its content. Multiple widgets of the same type may not share the same key.
str) – An optional tooltip that gets displayed when the button is hovered over.
callable) – An optional callback invoked when this button is clicked.
tuple) – An optional tuple of args to pass to the callback.
- kwargs (
dict) – An optional dict of kwargs to pass to the callback.
If the button was clicked on the last run of the app, it will be True. Otherwise, it will be False. Additionally, the return type is
# Text files text_contents = ''' Foo, Bar 123, 456 789, 000 ''' # Different ways to use the API st.download_button('Download CSV', text_contents, 'text/csv') st.download_button('Download CSV', text_contents) # Defaults to 'text/plain' with open('myfile.csv') as f: st.download_button('Download CSV', f) # Defaults to 'text/plain' # --- # Binary files binary_contents = b'whatever' # Different ways to use the API st.download_button('Download file', binary_contents) # Defaults to 'application/octet-stream' with open('myfile.zip', 'rb') as f: st.download_button('Download Zip', f, file_name='archive.zip') # Defaults to 'application/octet-stream' # You can also grab the return value of the button, # just like with any other button. if st.download_button(...): st.write('Thanks for downloading!')
🧩 Other notable updates
Below are some other notable updates on this release:
- 🛑 We made changes to improve the redacted exception experience on Streamlit Cloud. When
client.showErrorDetails=trueexceptions display the Error Type and Traceback, the actual error text will be redacted to prevent data leaks. 
- 🖥️ Macs are set to verify SSL in Python. If certificates aren't installed, a
SSL: CERTIFICATE_VERIFY_FAILEDerror propagates. We removed HTTPS in order to solve this issue. 
- 🔑 Integers can now also be used as keys in widget declarations. This helps community members who use integers for keys. This change ensures integer keys are converted to strings. 
Click here to check out all updates.
🏁 Wrapping up
Feel free to let us know in the comments below if you have any questions. We're looking forward to hearing what you think about the new download button!
Happy Streamliting. 🎈