Hi,
I am developing an application, which infer an AI model when RUN button is pressed. How can i disable/hide this RUN button while model is running.
Here’s a toy example:
import streamlit as st
import time
def run():
st.session_state.run = True
def clear():
st.session_state.result = None
def expensive_process():
with st.spinner('Inference running...'):
time.sleep(5)
st.session_state.run = False
st.session_state.result = 'Done!'
if 'run' not in st.session_state:
st.session_state.run = False
st.session_state.result = None
st.button('Run inference', on_click=run, disabled=st.session_state.run)
if st.session_state.run:
expensive_process()
# Include rerun if you want the Run Inference button to be clickable as soon
# as the inference is done.
# st.experimental_rerun()
if st.session_state.result is not None:
st.write(st.session_state.result)
st.button('Clear', on_click=clear)
I created a feature request for a method to simplify this common scenario. Feel free to vote on it here or check out the linked, related feature requests.
opened 08:39PM - 27 May 23 UTC
type:enhancement
### Problem
When expensive processes are initiated, a lot of care must be taken… to disable widgets to prevent a user taking action during the process. This can apply to the widget initiating the process or even other widgets on the page, including "shadow widgets."
### Solution
It would be nice to have some function like `st.lock()` that makes Streamlit ignore all click events. This could be in the form of iterating through all widgets it has in memory to override their `disabled` argument to `True` (directly or via some hidden, dominant attribute) or a higher-level act in JavaScript ignore click events in general. The locked state should end when the page completely loads (including via `st.stop`) or when a companion method is called (e.g. `st.unlock()` or `st.lock(end=True)`).
**MVP:** If `st.lock` is required to be called before the first widget loads on the page, Streamlit could jump ahead to iterate through all widgets in memory to disable them on the front end (taking care of shadow widgets), then proceed with the script. Then with `st.lock` being active during a page load, all widgets could get silently passed an extra, dominant keyword argument `force_disabled=True` so the widgets continue to be disabled as Streamlit executes their functions. When Streamlit gets to the end of this "locked" page load (whether actually getting to the end or calling `st.stop()`), Streamlit would automatically rerun the page (erroring if it encountered `st.lock` again). With this "normal" page load the widgets would no longer be receiving the `force_disabled=True` kwarg and thus be restored to the proper state as specified in their functions.
It would thus be natural to call `st.lock` as the first thing in a callback, since a rerun after a callback-prefixed load would automatically not include the callback function containing the lock.
**Alt MVP:** `st.lock` silences all JavaScript click events within the app body. Getting to the end or calling `st.unlock` undoes that silence.
**Possible additions:** Options could be added to include/exclude naviagation links from the lock, or to lock main body widgets independently of sidebar widgets. Widgets could also all be given an kwarg `lock='exempt'` to flag a specific widget as exempt from an app lock.
### Additional context
https://github.com/streamlit/streamlit/issues/156
https://github.com/streamlit/streamlit/issues/6415
---
Community voting on feature requests enables the Streamlit team to understand which features are most important to our users.
**If you'd like the Streamlit team to prioritize this feature request, please use the 👍 (thumbs up emoji) reaction in response to the initial post.**