St.session_state behaving strangely in some cases

Streamlit, version 1.12.2
Python 3.10.6 - 64bit
Windows 11

Below is an example script where a user interface is dynamically updated to display and handle an arbitrary number of widgets. Session_state is used to store information about the configured widgets between each time the script runs.

It normally functions as intended, but in some situations a bug appear.
To reproduce the bug, do the following (the st.writes are there for debugging purposes):

  1. Without typing anything into the text input, press the ā€œAdd data sourceā€ button.
    image

  2. Now, writhe anything into the upper text input. As soon as you press enter, the lower input gets updated as well.
    image

  3. The same happens if you type anything into the lower input.

  4. Now, add another data source, and delete one of the two already added.

  5. The application now functions as intended, and both the widgets and the session_state are correctly updated.

import streamlit as st

data_source_param = {
    'url' : '',
    'delete_btn': False,
    'query_btn': False
}


if 'data_sources' not in st.session_state:
    st.session_state['data_sources'] = [data_source_param]

def add_input():
    st.session_state['data_sources'].append(data_source_param)
    
def delete_input(source_ndx):
    st.session_state['data_sources'].pop(source_ndx)

def update_url(source_ndx):
    st.session_state['data_sources'][source_ndx]['url'] = st.session_state['url_' + str(source_ndx)]

def update_user_interface():
    st.write("Number of data sources: " + str(len(st.session_state['data_sources'])))
    source_ndx = 0
    for source in st.session_state['data_sources']:
        with st.container():
            col1, col2, col3 = st.columns([15, 5, 5])
            col1.text_input('API url', value= st.session_state['data_sources'][source_ndx]['url'], key= 'url_' + str(source_ndx), on_change=update_url, args= (source_ndx,), placeholder='Insert url' )
            col2.write('')
            col2.write('')
            col2.button('-', key='btn_' + str(source_ndx), on_click=delete_input, args=(source_ndx,))
        source_ndx += 1
            
st.set_page_config(page_title="UI tests", page_icon="šŸ“ˆ")

st.markdown("# UI Tests")
st.write(
    """Dynamic user interface test"""
)

st.write(st.session_state)
update_user_interface()
st.button('Add data source', on_click= add_input)
st.write(st.session_state)

Any idea why this happens?

1 Like

I found the bug, and it was in my codeā€¦
I had forgotten to copy the dict when appending to the list it in the add_input function, hence the same reference was just duplicated in the list.
Why the same didnā€™t happen for the third list element, I still donā€™t know (point 4 and 5 in the test sequence in the original post).

1 Like

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