Skip to main content

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.

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

If you're not sure about the file name format, learn more about wheel file names.

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

  • Download URL: multipage_streamlit-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 5.0 kB
  • Tags: Python 3
  • 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-py3-none-any.whl
Algorithm Hash digest
SHA256 d35314d7d1398eb65d038f6bed1812aff90325987b731fbd1b9939a1dd9266b8
MD5 8b4d11e379f7244d8071954b9730b815
BLAKE2b-256 39fd562c7b2997cd5ac850ead9a95959337800110fae99f6c2ae4e0e1e028712

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page