Is there any support for apps that have multiple pages? My use case is a 3-part workflow that I’d like to separate into three separate views with state carried across them.
Stages generally are: 1- overview of data and category specification, 2- model refinement with active learning, and 3- overview of trained model results).
Is this use case out of scope for streamlit, something that’s possible now, or something that’s planned?
There are ways of doing this based on a modification of the SessionState gist and the rerun() gist. My method uses a stack of state objects to provide the navigation. I built this handling into a “StreamlitPage” base class and subclass all my pages from it. I use a long if … elif … to do the dispatch (as the navigation varies with each page) but the dict method could be made to work as well.
I shared the modified SessionState (it’s attached to one of the Issues on Github). I haven’t shared the base class as: a) it will need rework once Streamlit finalize their approach; b) there are still some glitches which should be fixed when we get to upgrading to the 0.54+ releases and the latest SessionState implementation; and c) there are also several other application services (configuration, logging) built into the class that are specific to our environment and I need to refactor to take those out.
I’ve build pages into classes and I’ve made a manager than verify choice options with ‘st.ratio’, I’ve created a dictionary and return the options.
look the code:
import streamlit as st
from posting import Posting
from tables import Tables
pages = {'tables':Tables,'posting':Posting}
choice = st.sidebar.radio("Choice your page: ",tuple(pages.keys()))
pages[choice]()
Another option I have used is to leverage the file system to save the stateful aspect of your app and save it / load it.
import os
import pickle
import streamlit as st
class State:
def __init__(self, path='state.pickle', default_state_class=dict):
self.path = path
self.default_state_class = default_state_class
def load(self):
if os.path.exists(self.path):
with open(self.path, 'rb') as inf:
self.state = pickle.load(inf)
else:
self.state = self.default_state_class()
def get_state(self):
return self.state
def save(self):
with open(self.path, 'wb') as outf:
pickle.dump(self.state, outf)
def rerun():
raise st.script_runner.RerunException(st.script_request_queue.RerunData(None))
def app():
store = State()
store.load()
name = store.get_state().get('name', None)
if name:
st.text(f'Hello {name}')
else:
st.text(f'Please enter your name')
name_input = st.text_input('your name')
name = name_input
if name != '':
store.get_state()['name'] = name
store.save()
next_page = st.button('Next page')
if next_page:
rerun()
if __name__ == "__main__":
app()
I have followed the example from @Vojaganto so far and works very well.However, I ran into the problem that Reload ® does not take into account changes made on subpages. What is the reason for it and is there any way to fix it?
Hello @chris_klose, you’d need some session state to keep changes between subpages.
I’ve made a topic on this covering specifically the case of a multi-page app with a settings page here:
Hey Peeps,
I don’t want the values added in the app itself to be saved.
My problem is, that if I change the code itself and rerun (by pressing R) the app, the changes made in the code do not become active. I have to start the app again (Streamlit run app.py) so they get active.
So I’d like to know if there is a workaround to solve that. Any ideas?
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.