Interact with Widgets and Forms

Hi all :wave: !

I am currently writing a Streamlit dashboard, where I first want to fetch data from different sources and afterwards want to interactively analyze it. For the data downloading part I use st.from so that my dashboard does not get refreshed on every change. However, combining the form with other interactive widgets seem to reset the dashboard every time. Is there a way around this? Here is some example snippet of my current approach:

import streamlit as st

DATA_SOURCES = {
    'Postgres': [1, 2, 3, 4, 5],
    'MySQL': [4, 2, 4, 2],
    'Snowflake': [5, 4, 3, 2, 1]
}

def download():
    with st.sidebar.form('download_form'):
        source = st.selectbox('Select Data Source', ['Postgres', 'MySQL', 'Snowflake'])

        if st.form_submit_button('Download Data'):
            return DATA_SOURCES[source]

def multiplicator(vals):
    multiplicator = st.radio('Select sampling', list(range(1, 5)))

    return [val*multiplicator for val in vals]

if __name__=='__main__':
    st.sidebar.header('Config Zone')
    data = download()

    st.header('Analyzing Zone')

    if data:
        new_data = multiplicator(data)
        st.write(f'Initial data: {data}')
        st.write(f'Multiplied data: {new_data}')

This is the current behaviour:

streamlit_question

Hi again :wave: !

After a bit more research, code refactoring and and playing around with st.experimental_memo and st.session_state, I found a working solution for me. Here is the code:

import streamlit as st

DATA_SOURCES = {
    'Postgres': [1, 2, 3, 4, 5],
    'MySQL': [4, 2, 4, 2],
    'Snowflake': [5, 4, 3, 2, 1]
}

def select_source():
    with st.sidebar.form('download_form'):
        source = st.selectbox('Select Data Source', ['Postgres', 'MySQL', 'Snowflake'])

        if st.form_submit_button('Download Data'):
            return source

@st.experimental_memo
def download(source):
    return DATA_SOURCES[source]

def multiplicator(vals):
    multiplicator = st.radio('Select sampling', list(range(1, 5)))

    return [val*multiplicator for val in vals]

if __name__=='__main__':
    st.sidebar.header('Config Zone')
    source = select_source()

    if not source and 'source' in st.session_state:
        source = st.session_state['source']

    if source:
        st.session_state['source'] = source
        data = download(source)

        st.header('Analyzing Zone')

        new_data = multiplicator(data)
        st.write(f'Initial data: {data}')
        st.write(f'Multiplied data: {new_data}')