Open maximlt opened 1 year ago
The problem with pn.state.served
is also that you need panel imported. I have many examples where I don't need panel imported unless the document is served. Then I import Panel, do pn.extension
and some more things. So in many places I stick to if __name__.startswith("bokeh"):
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.
Will reopen, to document this properly.
The problem with pn.state.served is also that you need panel imported. I have many examples where I don't need panel imported unless the document is served. Then I import Panel, do pn.extension and some more things. So in many places I stick to if name.startswith("bokeh"):
I struggle seeing this as a problem. pn.state.served
is there for convenience and readability, if you don't import Panel you can't expect that convenience.
Therefore there is no meaning to
pn.state.served
outside the context of the application module.
I get what you mean,pn.state.served
will be False
if accessed from the top-level context of an imported module. But shouldn't we expand it to return True
if pn.state.curdoc is not None
? To cover cases like the following:
# app.py
import panel as pn
from util import import_debug
def script_debug(event):
print(f'{pn.state.served}')
b1 = pn.widgets.Button(name='Script debug')
b1.on_click(script_debug)
b2 = pn.widgets.Button(name='Import debug')
b2.on_click(import_debug)
pn.Row(b1, b2).servable()
# Clicking b1 will print True, b2 will print False.
with
# util.py
import panel as pn
def import_debug(event):
print(f'{pn.state.served}')
I think pn.state.curdoc is None
is not a sufficient condition for served
to be true, no. Specifically that would mean:
# util.py
import panel as pn
if pn.state.served:
some_side_effect()
would be treated as True
but then never re-execute causing potentially very hard to catch issues because in a testing setup everything looks fine but as soon as you load the app a second time the side-effects wouldn't re-run. pn.state.served
specifically is designed to detect that you are inside the served app module and should be explained like that. I have no objection to adding a separate pn.state.in_session_context
which internally just evaluates pn.state.curdoc is not None
.
To be very clear pn.state.served
could (and maybe should?) have been pn.state.in_served_app_module
.
Thanks for the clarification, that's a gotcha! I definitely need to check some internal code, I could have easily introduced some bug using pn.state.served
from outside the main module.
As if pn.state.served
is meant to be used somewhat in place of the traditional if __name__ == '__main__'
, it could have been been named pn.state.in_main_served
.
I could have easily introduced some bug using pn.state.served from outside the main module.
Doesn't seem super likely since whatever statement you guarded would never have executed which you presumably would have noticed. The real danger really would have been if it were True
the first time.
Should
pn.state.served
be limited to returningTrue
only if it's accessed from the served file? I see it more as a context value that should beTrue
wherever I access it from, be it in the served file or one of its imported modules. However, its implementation suggests it's limited to the served file:Motivated by https://discourse.holoviz.org/t/how-do-i-know-if-im-in-serve-context-outside-main-module/6177/2