question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Feature request: confirm_button

See original GitHub issue

Problem

A very natural idea in Streamlit would be to write a username / password UI like this:

username = st.text_input('username')
password = st.text_input('password')
if st.button('Authenticate'):
    if authenticate(username, password):
        do_something()
    else:
        st.error('The username or password you have entered is invalid.')

But this doesn’t work as the user hopes! The problem is that if do_something() draws widgets, those widgets will dissapear as soon as they’re changed because st.button('Authenticate') will flip back to False.

More general statement

This password example is actually a specific case of a much more general (and natural) use-case where the user has some input widgets, then performs some computation on them but only after the user hits the confirm button, and then provides more widgets for further computation.

Unholy Workaround

There is a workaround which works in Streamlit 0.35. You first have to copy-paste confirm_button() as defined in this gist. Then you can do:

username = st.text_input('username')
password = st.text_input('password')

confirmed = confirm_button('Authenticate', authenticate, username, password)

if confirmed == confirm_button.CONFIRMED_TRUE:
    do_something()
elif confirmed == confirm_button.CONFIRMED_FALSE:
    st.error('The username or password you have entered is invalid.')
elif confirmed == confirm_button.UNCONFIRMED:
    pass # the user has not pressed the button
else:
    raise RuntimeError('Invalid return value.')

Unfortunately, the problems with this solution is that:

  1. It uses some pretty nasty hacks involving st.cache. Eventually, a better (and much more general) solution will be possible when we give users direct access to client state.
  2. Because it uses st.cache is is not isolated per user.
  3. It this ugly ternary return value.

Solution

It would be nice if we had the following built-in function:

def confirm_button(label, confirm_func, *func_args):
    ...

with the following semantics:

  • Execution halts at confirm_button() until it is clicked.
  • When the button is clicked, it grays out and returns confirm_func(*func_args).
  • The return value of confirm_func is memoized so that in needn’t be re-called.
  • The confirm button reappears if *func_args changes.

This lets the user write much prettier code:

username = st.text_input('username')
password = st.text_input('password')

if st.confirm_button('Authenticate', authenticate, username, password):
    do_something()
else:
    st.error('The username or password you have entered is invalid.')

NOTE: This solution is less general than the unholy solution in that it prescribes a particular course of action when the button isn’t pressed, namely halting execution.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:11
  • Comments:14 (4 by maintainers)

github_iconTop GitHub Comments

12reactions
treuillecommented, Sep 22, 2019

Even Better Solution

This is another workaround called cache_on_button_press, which I define in this gist:

@cache_on_button_press('Authenticate')
def authenticate(username, password):
    return username == "buddha" and password == "s4msara"

username = st.text_input('username')
password = st.text_input('password')

if authenticate(username, password):
    st.success('You are authenticated!')
    st.write(st.slider('Test widget')) # <- just to show that widgets work here
else:
    st.error('The username or password you have entered is invalid.')

image

When you get the answer right you see:

image

I like this solution even better because:

  1. It uses decorators instead of callbacks.
  2. It requires less code.
  3. It’s simpler to understand once you already grok @st.cache.
9reactions
markopycommented, Nov 4, 2019

@treuille : An example would be a ML model evaluation or training which has multiple input parameters mapped to streamlit widgets (several sliders, for example). The key part is that running the model takes a long time so for a good experience the users wants to adjust all sliders to the desired values before running the model.

At the moment moving one slider would instantly trigger an expensive and pointless model run which interrupts the user experience. The better experience would be for the user to adjust all sliders to their desired values and then only run the model with the press of a button.

I think a very generic solution to this kind of problem would be to just have an option on input widgets to make them not trigger a script rerun when their value changes.

Read more comments on GitHub >

github_iconTop Results From Across the Web

[Feature Request] ElMessageBox confirm button style #8213
Existing Component Yes Component Name el-message-box Description Hello, I learned that this is not a bug, but now the product department ...
Read more >
Button Confirmation - Request a Feature - Glide Community
Hello, I just want to request a button with a confirmation pop up. Use cases: Delete button - Confirm to delete? Submit Button...
Read more >
Confirmation Box when Creating New Link
The confirm() method displays a dialog box with a specified message, along with an OK and a Cancel button. A confirm box is...
Read more >
Feature request: Confirm on quit (#575) · Issues · GNOME / meld
Hi, what do you think about adding a confirmation request to the closing ... distraction or fatigue, it happens to click the main...
Read more >
Inline Editing without need for pop up and confirm button
Inline Editing without need for pop up and confirm button · Feature Requests · uiux-live-app, tables, good-idea, duplicate, usability, low-impact.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found