MultiPage Streamlit app with persistent widget states
Project description
MultiPage Streamlit
MultiPage Streamlit app with persistent widget states
Demo
Run the demo app: https://share.streamlit.io/crxi/multipage_streamlit/main/example/demo/app.py
Background
Recently I needed an app that supports multiple pages. However, Streamlit does not yet have such a feature. Not surprisingly, many innovative developers have came up with their own workarounds. Often it involves using the selectbox as a drop-down menu to offer pages. One such implementation that I like can be found here: https://towardsdatascience.com/creating-multipage-applications-using-streamlit-efficiently-b58a58134030. It structure each page as a separate module in a package directory, which leads to a nice modular design.
While that solution works, the pages generated do not remember their states when we switch pages. E.g. if I change a slider from default value of 0 to 10 on Page A and I moved to Page B to do something, then when I switch back to Page A, the slider is again at default 0. I thought saving the values into session_state will help, but frustratingly it does not. The reason is addressed here: https://github.com/streamlit/streamlit/issues/3925. By design, the values of widgets stored in session_state are removed if they no longer appear on the current page.
That same ticket implemented a solution to make the values persist. It does it by intercepting "on_change" so that it can save the value into a persistent dictionary in session_state. I thought it was pretty clever, although it does add some complexity if we want to use "on_change".
Then I came across this: https://github.com/streamlit/streamlit/issues/4338. The purposed solution (in the comment) had a different approach which does not involve using "on_change". While it did not work out-of-the-box for me as my app spanned different modules, it inspired me to come up with a different solution.
What's new here?
I combined the solutions and got something that worked for my purpose. And so I would like to share it with the Streamlit Community.
I added some other features:
- 3 different styles of multipage app: selectbox, expander and radio.
- allow setting of default value when declaring key name
- concept of namespace-prefix when saving states to avoid accidental reuse of key names (especially if the pages span multiple modules)
Installation
python -m pip install git+https://github.com/crxi/multipage_streamlit
Usage
Organize your pages as follows:
app.py
pages/
+- page_a.py
+- page_b.py
Your top level app.py:
import multipage_streamlit as mt
from pages import page_a, page_b
app = mt.MultiPage()
app.add("Page A", page_a.run)
app.add("Page B", page_a.run)
app.run_selectbox()
# alternatives: app.run_expander() or app.run_radio() if you prefer those
In each page.py:
import streamlit as st
from multipage_streamlit import State
def run():
state = State(__name__)
# the above line is required if you want to save states across page switches.
# you can provide your own namespace prefix to make keys unique across pages.
# here we use __name__ for convenience.
st.header("Page A")
x = st.slider("Value X", min_value=0, max_value=100, key=state("x", 50))
# here's the "magic": state(name, default, ...) returns the namespace-prefixed
# key name. if a previously saved state exist, the widget is set to it. if not,
# the widget is set to default if it is specified.
state.save() # MUST CALL THE ABOVE TO SAVE THE STATE!
See the demo for more examples.
Feedback
Your feedback is most welcomed. You can send via "Issues" or email to crxi.code@gmail.com.
Contributing
Interested in contributing? Check out the contributing guidelines. Please note that this project is released with a Code of Conduct. By contributing to this project, you agree to abide by its terms.
License
multipage_streamlit
was created by CRXi crxi.code@gmail.com.
It is licensed under the terms of the Apache License 2.0 license.
Credits
multipage_streamlit
was created with cookiecutter
and the py-pkgs-cookiecutter
template.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for multipage_streamlit-0.1.0.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 25f1450bfb84af1b15cf55a0e15db8c52c7a9a46cf0056c37f1cc897e4442f40 |
|
MD5 | 6a73f342f23f0a9976653682d3d068b2 |
|
BLAKE2b-256 | c983549a852adab9de9a6486496b31c6a03a73c74bd8d24a761acdd7d3088117 |
Hashes for multipage_streamlit-0.1.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d35314d7d1398eb65d038f6bed1812aff90325987b731fbd1b9939a1dd9266b8 |
|
MD5 | 8b4d11e379f7244d8071954b9730b815 |
|
BLAKE2b-256 | 39fd562c7b2997cd5ac850ead9a95959337800110fae99f6c2ae4e0e1e028712 |