Skip to content

Avoid double download buttons by using new data callback function #16

Description

@prihoda

Problem Statement

Streamlit now supports passing a function to st.download_button(data=...) so we don't have to use the double download button approach that first uses a regular button and then the confirm_download_button, such as done here for example:

def download_descriptor_table(filename, design_ids, descriptor_keys=None, key="default", width="content"):
if st.button(
"Download descriptor table" if len(design_ids) > 1 else "Download descriptors",
key=f"prepare_descriptors_{key}",
width=width,
):
with st.spinner("Preparing descriptor table..."):
# Get raw dataframe with single header, columns named with descriptor keys ("pipeline|tool_key|descriptor")
df = get_wide_descriptor_table(
design_ids=design_ids, descriptor_keys=descriptor_keys, nested=False, human_readable=False
)
excel_bytes = export_design_descriptors_excel(df)
confirm_download_button(
data=excel_bytes.getvalue(),
file_name=f"{filename}.xlsx",
mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
key=f"download_descriptors_{key}",
)

Proposed Solution

One limitation is that the data callback function cannot have any arguments. But it's possible to overcome using a lambda function. Minimal working example.

import streamlit as st
import time

def export_example(a, foo):
    return f"a,foo\n{a},{foo}".encode("utf-8")

def download_example(a):
    st.download_button(
        label="Download report",
        data=lambda: export_example(a, foo="bar"),
        file_name="report.csv",
        mime="text/csv",
        key=a,
    )

download_example('A')

download_example('B')

All functions calling confirm_download_button should now use this approach instead.

The data function should not call any streamlit functions such as st.spinner (the button already shows a spinner), they should just generate the data.

Alternatives Considered

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions