Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client-side state should be directly accessible #165

Closed
treuille opened this issue Sep 21, 2019 · 3 comments
Closed

Client-side state should be directly accessible #165

treuille opened this issue Sep 21, 2019 · 3 comments
Labels
type:enhancement Requests for feature enhancements or new features

Comments

@treuille
Copy link
Contributor

treuille commented Sep 21, 2019

Problem

We want to make stateful apps possible in Streamlit by making the client state directly accessible. This would enable, for example, the following two scenarios which using hypothetical notation (see Possible API Proposals for more possibilities).

Scenario 1: A Simple Counter

This is a classic React example is the counter:

# Initialize the state.
if 'counter' not in st.state:
    st.state['counter'] = 0

# Allow the user to change the state.
if st.button('Increment'):
    st.state['counter'] += 1

# Show the state.
st.write('counter:', counter)

Scenario 2: State Constraints Between Widgets

Suppose we have a "start date" and "end date," and wants to ensure that the former comes before the latter:

# Input the start and end dates.
start_date = st.date_input('start date')
end_date = st.date_input('end date')

# Enforce start_date <= end_date.
if start_date > end_date:
    st.state['start_date'] = end_date

Note

The feature request from the old repo has a lot more information.

Summary

The correct design has not been decided. Please indicate your use case for this feature as a comment below!

@treuille treuille added type:enhancement Requests for feature enhancements or new features spec needed labels Sep 21, 2019
@tvst
Copy link
Contributor

tvst commented Oct 14, 2019

For people who land here, see the Gist below for a prototype implementation of a SessionState module that solves this issue:
https://gist.github.com/tvst/036da038ab3e999a64497f42de966a92

Usage:

import SessionState
state = SessionState.get(position=0)
# Do something with state.position now! It will persist on a per user basis.

Please note: the SessionState object above is just one proposal among many we're considering! I'm just posting it here so people can be unblocked while we come up with a really beautiful solution 😉

@mbertschler
Copy link

I would like to use this feature in a script that runs report that takes a long time to complete. Because of this I can't rerun the report (remote data fetching and running statistical analysis) every time one of many input fields are changed.

Code Example

# multiple input fields and a "Run" button to execute the report
cfg = {}
cfg['start'] = st.date_input('Start date')
cfg['end'] = st.date_input('End date')
cfg['client'] = st.text_input('Client')
run = st.button('Run Report')

# update the stored config to the current inputs only
# when the "Run Report" button is clicked
if run:
    st.set_state('config', cfg)

report_config = st.get_state('config')
result = report(report_config)

# the long running report function that needs a
# stable input config for caching
@st.cache
def report(config):
    ...

If I would call report() directly with the input config, the caching would be invalidated every time one of the input files change. I would use this mechanism to only apply the inputs to the configuration when the button is clicked.

We currently have something like this implemented where the configuration is stored in a file. This only works for one user though. I would expect this functionality to have a separate state storage per browser tab.

@randyzwitch
Copy link
Contributor

Closing, as state management is actively being developed, and product discussion underway

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:enhancement Requests for feature enhancements or new features
Projects
None yet
Development

No branches or pull requests

4 participants