Why session state is not persisting between refresh?


I’m trying to persist the authentication token of my app in a session state, but this gets lost when the browser rerun.

Steps to reproduce

Apologies if the code is not exactly as the one in writing, but I’m doing this by heart.

Code snippet:

If 'token' is not in st.session_state:
   st.session_state.token = something

   # use the session state value

There is of course much more logic in my code, but on the browser refresh, I was expecting token to be in the state hence the else condition block to be executed.

I’ve seen a couple of posts suggesting a variable to be initialised with the st.empty() but I’m not sure that is pointing me in the right direction.

So I wonder if I have completely misunderstood the session state mechanism.

Thanks for clarifying.

Refreshing the browser ends your session and creates a new one, so session_state is refreshed too, as well as the widgets state.

1 Like

As Goyo mentioned, session state is linked to each individual “session”.
When you refresh the browser you start a new session.

Is the token for each individual user, or one token for all users (for example, an API token that should be shared between users to all access the data)?

Tokens is a Google ouath one which has to be refreshed periodically too.

Thanks both for clarifying the session bit. Coming more from the coding perspective where a session ends only by inactivity, this is very confusing.

I think somehow this should be mentioned in this page

Perhaps you could try the memo streamlit function?

Set the ttl to the period you want the Google auth token to refresh.
For example, if the token refreshes every 24 hours, then set

ttl = 24 times 60 times 60 (since it is in seconds).

In this way, only once every 24 hours streamlit app will call the token.
Please let us know how you get on!

EDIT: Had to change * to “times” since it just made stuff italic!
Also changed memo to singleton.
Now changed back to memo since singleton does not have ttl.

As far as I know the OAuth from google does not allow you to specify any TTL. All tokens are expiring one hours after as per the returned expires_in object.

But that’s not going to be a problem as far as I can tell. Given Streamlit logic to run the full app from the beginning, it’s just a case to call in for a refresh at every execution?
The only downside, is that I’ve done it but I don’t see my access_token being refreshed when done in the webapp.
The same principle with a command line POST returns a new one, so I’m now sure I’m eventually getting the token refreshed.

Ah sorry, that wasn’t too clear.
I mean you can set ttl in the streamlit function st.experimental_memo - Streamlit Docs.

If you set this ttl to one hour (i.e. ttl = 1 times 60 times 60) then the function that you use in your Python code to call the OAuth will only update every 1 hour.
i.e. the token you get from OAuth will be stored in a cache and every time you run the app it will be served to you (without contacting Google), until after 1 hour it will again call the function and get the new token from Google.

Perhaps it is worthwhile reading the link above, or even the old cache function

I understand what you mean, but I doubt it will work. Unless refreshed, the OAuth2 token will expire anyway.
But I think I have figured out how to make it.

How did you end up solving this? I am in a similar situation.

The problem of making state persist across sessions can be solved in two ways:

  • Using streamlit cache, experimental_memo or experimental_singleton, as suggested above.
  • Using an external storage solution that you can control, like a database.

If you have a problem specific to Google OAuth tokens, I can’t be of any help without more details, because I don’t know how or when they need to be refreshed.