Multi step form- access to variables and values throughout the steps

Hey All.

The solution to do multi-step forms in Streamlit works really well, thank you Profile - blackary - Streamlit for setting this up. But additional question:

How can we access values that are set through the different forms steps?

For instance in one of the steps we do a call to OpenAI to generate something based on a previous value that has been set in a previous step.

We also want to use that OpenAI Response in a later step.

How would we implement this? Sorry if it’s obvious but I tried a couple of things and it looks like the form is scoping the variables…is this correct?

Because I would expect the below to set the session_state[“name”] and be able to access it later on. But- it does not work like this?

The code I have so far below:


import streamlit as st

if "name" not in st.session_state:
    st.session_state["name"] = ""

def goto_level_3():
    st.session_state["stage"] = "level_3"

def goto_level_2():
    st.session_state["stage"] = "level_2"

def goto_level_1():
    st.session_state["stage"] = "level_1"

if "stage" not in st.session_state:
    st.session_state["stage"] = "level_3"

if st.session_state["stage"] == "level_3":
    with st.form("level_3_form"):
        st.caption("Level 3")
        name = st.text_input("name", st.session_state['name'] )
        st.session_state['name'] = name
        
        submitted = st.form_submit_button(
            "Generate level 2", on_click=goto_level_2
        )

if st.session_state["stage"] == "level_2":
    with st.form("level_2_form"):
        st.caption("Level 2")
        st.write(st.session_state['name'])
        b = st.text_input("lastname")
        
        submitted = st.form_submit_button(
            "Generate level 1", on_click=goto_level_1
        )
if st.session_state["stage"] == "level_1":
    with st.form("level_1_form"):
        st.caption("Level 1")
        submitted = st.form_submit_button(
            "Back to 3", on_click=goto_level_3
        )

Thank you so much

Take a closer look at this part:

if st.session_state["stage"] == "level_3":
    with st.form("level_3_form"):
        st.caption("Level 3")
        name = st.text_input("name", st.session_state['name'] )
        st.session_state['name'] = name
        
        submitted = st.form_submit_button(
            "Generate level 2", on_click=goto_level_2
        )

When a widget (st.text_input) is in a form, it will not output a user-defined value (name) until submitted. However, when submitted in this case, the stage is changed in the callback and this block is not re-executed. Hence, the user-defined value is never output and never assigned to st.session_state.name.

You can fix this by:

  1. Don’t use forms. Just using the staging concept and a normal st.button. That way you can assign the output of widgets to keys in Session State in the manner above.

  2. Assign keys to your widgets and update your callbacks to not only change the stage, but harvest values from your form widgets. This gets a little messy since keys assigned to widgets get deleted when the widget disappears. (See Widget Behavior.) You’d have to basically copy widget values from one key to another in the callback. I can write this out, but the first solution would be simpler.