My app is constituted of a main and several auxiliary modules. In the main file, an App object is instantiated.
In the main file,
True, but it’s also
True within the scope of the App object only if the class is defined within the same module. If it’s imported, then it’s
False. Note that the
pn.state object does point to the same location in memory regardless.
In other words this prints
import panel as pn
But this prints
import panel as pn
from other_module import Something
This is annoying for test purposes, because there are some commands that I can’t do outside of a server context (e.g. using
pn.state.notifications) so I need to know if I have to avoid them.
I don’t know if there are ways to do this other than passing
pn.state.served to the App constructor and all other objects downwards.
Looking at the code the served property is just inspecting the current module’s name attribute for the bokeh app prefix.
You should be able to access pn.state functions normally in submodules without issue.
Thanks @gib for your response.
I see that
.served is a property so that explains why it gives different results based on the module from which it is called.
There must be a reason why it’s not a standard attribute of the
_state class, but that way it would be set once and for all (allowing for its use everywhere).
As for the pn.state methods, yes I did not realise that the only reason why
pn.state.notifications did not work in my test setting was that I did not set
pn.extension('notifications')… Thanks again!
Hmm this is surprising to me to! I’d expect
served to be
True wherever you call it from, be it from the served file or one of its imported modules. I opened an issue `pn.state.served` value when accessed from outside of the served file? · Issue #5623 · holoviz/panel · GitHub.
There is a good reason for this, which is that the
served property only ever makes sense in the context of the served application module. Any module you import inside an application will only ever be evaluated once (on the first import) and any subsequent import will simply load the cached module. Therefore there is no meaning to
pn.state.served outside the context of the application module.
I realize that session contexts and how application modules vs. imported modules work is a major gap in our documentation (as well as Bokeh’s). Once you understand that the application modules are created per session but anything you import is effectively global then that starts giving you a deeper insight into how session state vs global state works. We will need a proper background/explanation section on this.
My main question is what the
Something() in your mock code is actually doing? My suspicion is that whatever it is likely would not have worked correctly and the fact that it didn’t saved you from doing something that may have worked in testing but would break in production because the second time the app is loaded
Something() would not have been re-evaluated.
Many thanks @philippjfr for your response
It is quite clear when working with bokeh and panel that the app module is per-session while other modules are imported once and shared across sessions. For instance, that allowed for the use of a shared cache between users before the built-in panel cache feature was added.
To answer your question, in my case the
Something() is the actual app object, and in turn it imports viewable components from other modules. In one of these modules I have to access
pn.state.curdoc.session_context (to read cookies) but that cannot work in a test setting. One way to go is to check whether
None before proceeding, but it would be cleaner to use
Anyway, even if a module is imported only once, if the
pn.state.served statement is not put at module-level but within the scope of a function/object (which is the case for me), it will be evaluated each time that function/object is used. In this regard, maybe having
state.served as a standard attribute set once and for all at session initialisation would make sense.
Yes I think there’s three useful variables:
- Are we currently in an application module, this is currently
- Is the entire process running in the context of
- Are we currently in the context of a session, i.e. a shortcut for
Context of code executed from
--setup can also be useful.