Streamlit session mgmt with multiple buttons and functions

Summary

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

Steps to reproduce

Code snippet:

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

Debug info

streamlit 1.22

I saw your question on StackOverflow a couple weeks ago, so I’ll copy my reply here:

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 SO 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

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.