Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

multipage_streamlit-0.1.0.tar.gz (4.6 kB view details)

Uploaded Source

Built Distribution

multipage_streamlit-0.1.0-py3-none-any.whl (5.0 kB view details)

Uploaded Python 3

File details

Details for the file multipage_streamlit-0.1.0.tar.gz.

File metadata

  • Download URL: multipage_streamlit-0.1.0.tar.gz
  • Upload date:
  • Size: 4.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.13 CPython/3.8.10 Linux/5.13.0-35-generic

File hashes

Hashes for multipage_streamlit-0.1.0.tar.gz
Algorithm Hash digest
SHA256 25f1450bfb84af1b15cf55a0e15db8c52c7a9a46cf0056c37f1cc897e4442f40
MD5 6a73f342f23f0a9976653682d3d068b2
BLAKE2b-256 c983549a852adab9de9a6486496b31c6a03a73c74bd8d24a761acdd7d3088117

See more details on using hashes here.

File details

Details for the file multipage_streamlit-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for multipage_streamlit-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d35314d7d1398eb65d038f6bed1812aff90325987b731fbd1b9939a1dd9266b8
MD5 8b4d11e379f7244d8071954b9730b815
BLAKE2b-256 39fd562c7b2997cd5ac850ead9a95959337800110fae99f6c2ae4e0e1e028712

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page