Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using if session to only run code when session has initialised fails #1327

Closed
pieterjanvc opened this issue Apr 23, 2024 · 2 comments
Closed

Comments

@pieterjanvc
Copy link

Hello,

Let me show the issue using a very simple reprex:

Issue

from shiny.express import session

if session:
    print("The session ID is:" + str(session.id))

Generates the error

RuntimeError:
The session attribute `id` is not yet available for use. Since this code
will run again when the session is initialized, you can use `if session:` to
only run this code when the session is established

And as you can see I implemented exactly the solution the error message recommended and got the exact same error

Workaround

It took me a long time to find a workaround which is not documented anywhere so I'm sure it's more of a hack:

from shiny.express import session

if hasattr(session, "_process_ui"):  
    print("The session ID is:" + str(session.id))

It's still pretty clean, so if you think this would be a good general solution, you can just update the error message so others know how to fix this issue too :)

Kind regards

@wch
Copy link
Collaborator

wch commented Apr 23, 2024

It looks like that error message needs to be fixed.

An explanation of what's happening:

  • With Shiny Express apps, the code in the .py file is run once at startup to generate the UI (which is saved and served each time someone connects), and once for each new user session.
  • For the first, UI-generating pass, the shiny.express.session is not a real Session object, but instead a ExpressMockSession object. This is the object which throws errors when you try to access the .id member.
  • For the user sessions, shiny.express.session is a Sesssion object, and accessing members of it will work fine.

I think it would make sense to add a method to ExpressMockSession and Session, which reports whether it is a real session object.

For the moment your workaround should be OK. Or you can use this, which is slightly less hacky:

from shiny.session import Session
from shiny.express import session

if isinstance(session, Session):
    print("The session ID is:" + str(session.id))

@wch
Copy link
Collaborator

wch commented Apr 26, 2024

In #1331, we added a new method .is_stub_session(). So with the development version of shiny, you should be able to do:

from shiny.express import session

if not session.is_stub_session():
    print("The session ID is:" + str(session.id))

@wch wch closed this as completed Apr 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants