How to initialize session-state variables regardless of which page is loaded first?

I’m looking for a way to initialize some config data into session-state in a multi-page app without repeating the initialization code on every page. In a multi-page, a user may first load any page by going to URL myapp/page5 for example, so we can’t predict where to put the initialization code.

Is there any type of __init__ style initialization function that Streamlit runs on new session creation where I can put such state initialization code just once?

I tried to put the code in a module and import that module in every page_x.py, but that doesn’t work because, I believe, Python will only import the module once per program run, not per session, so only the first user gets the session-state variables. And this method still requires repeating the import line on every page.

Currently my solution is to do this on every page:

from my_session_module import init_session
init_session()

Does anyone know of a more elegant solution that doesn’t require repeating code on every page?

streamlit always start at main page. Whatever it is in your int_session() save it in session_state so that it can be accessed in the pages files as well.

Hi @ferdy,

This doesn’t seem to be the case.

If I remove init_session() from page.py, and only include it in the main.py, and then point my browser directly to myapp/page, I get `KeyError: ‘st.session_state has no key…’ when trying to recall a session-state variable.

However, then if I browse to the main page at myapp/, then back to myapp/page, the variables are initialized and the error is gone.

Based on this it seems the code in the main page is not executed when a sub-page is loaded first.

Am I missing something / testing incorrectly?

Example, after running, press page1 and there is no error on the page, and you can access the value of ss with key “a”.

session_module.py

import streamlit as st

def init_session():
    if 'a' not in st.session_state:
        st.session_state.a = 1

main.py

import streamlit as st
from session_module import init_session

st.write('main page')
init_session()

pages/page1.py

import streamlit as st

st.write(f'from page 1, value of ss with key "a" is {st.session_state.a}')

Thank for taking the time with that example @ferdy

However, I still see a different behavior. I wonder if it’s a difference of environment?

I’m running Streamlit on a remote Linux host, and browsing to it from Chrome on Windows.

Running Streamlit with the basic: streamlit run main.py

I replicated your example exactly. If I first browse to linuxhost:8501/ then press page1, it works as described. I see the expected from page 1, value of ss with key "a" is 1

However, if while on page1 I hit reload in my browser, or browse directly to linuxhost:8501/page1 in a new tab (thus creating a new session I presume) I get:

AttributeError: st.session_state has no attribute "a". Did you forget to initialize it? More info: https://docs.streamlit.io/library/advanced-features/session-state#initialization

When you say “after running, press page1” does that imply you already loaded to the main page? Maybe you have some environment that automatically brings up the app in a browser on the main page when it is run?

AFAIK there is no other solution.

Reloading a page is a totally different matter as it changes the session id thereby losing the previous session states.

To not crash on page reloads you can apply a switch page to the page where the init_session was called from the start.

Example.

pages/page1.py

import streamlit as st

# If there is page reload, switch to a page where init_session was called.
if 'a' not in st.session_state:
    st.switch_page('main.py')

st.write(f'from page 1, value of ss with key "a" is {st.session_state.a}')

Thanks @ferdy. That would be another approach, but goes back to having to repeat some code on every page that I was trying to get away from.

@Goyo thanks for confirming. Maybe a feature for the future as it seems useful to be able to initialize some sort of config for an app as a whole regardless of which page is accessed first.

And thanks to everyone who contributes to this project. It’s great.