I’m writing a functionality where a user provides a URL, and presses the analyze button. On pressing the button do_something function is triggered. If it is successful the user is presented with a text box to start a chat. When the user submits input to the chat the ans function is executed and output should be written to the screen
import streamlit as st from streamlit_chat import message import logging # Custom functions logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) st.markdown("<h1>VTest</h1>", unsafe_allow_html=True) st.sidebar.header("Input parameter") def do_something(url): st.write("Calc Length") slen = len(url) return slen def get_text(): input_text = st.text_area("You:") return input_text def ans(len,user_input): return user_input+" Test "+str(len) if "analyze" not in st.session_state: st.session_state["analyze"] = False if "submit" not in st.session_state: st.session_state["submit"] = False with st.sidebar.form(key="my_form"): URL = st.text_input("Enter URL :") analyze_button = st.form_submit_button(label="Analyze") if str(URL) == "": st.warning("Awaiting URL input in sidebar for chat.") if analyze_button: st.session_state["analyze"] = not st.session_state["analyze"] if str(URL) != "": with st.spinner( "Patience ..." ): slen = do_something(URL) if slen>0 and st.session_state["analyze"]: user_input = get_text() submit = st.button("Submit") if user_input: with st.form(key='my_form'): submit_button = st.form_submit_button('Submit') if submit_button: response = ans(len,user_input) st.write(response) else: st.warning("Enter your question above") else: st.error( f"The greatest teacher, failure is...\n" ) else: st.sidebar.warning("Please provide URL ") raise Exception("You must provide a URL !") Expected behavior:
When the user clicks the submit button ans should execute and the response should be printed on the screen
Actual behavior:
The whole page reloads, the screen goes blank. The do_something is executed again, which should not happen
1 Answer
Buttons do not retain state. They return True on the page load resulting from their click and then immediately go back to False. As such nesting widgets inside of a button is not going to give desirable results in almost all cases.
When the submit button is clicked, the page reloads and now the analyze button is false. Hence, all that content conditioned upon the analyze button goes away (including the submit button and everything thereafter).
You can have the buttons set values in session state and condition your code on the session state values instead of the buttons directly.
Blog post describing button behavior and common strategies
Other posts about nested buttons:
creating a selectbox/file_uploader with a button in streamlit app
Why is my streamlit app's second radio disappearing when I change the default answer?
Values disappear after using button in streamlit
Comment: Stack Exchange is not letting me post the links because of "bad code format" so sorry for all the edits.