Using lifecycle hooks with panel.serve

Hello!

I would like to use the on_server_loaded-method for a panel app. My understanding is that I need to use the directory format and specify the lifecycle hooks in the app_hooks.py file as described in the bokeh documentation… This works fine if I use the panel serve command, however I would like to serve my app inside a python file using the panel.serve method, as I need to perform some initialization first… And this does not trigger the hooks what I can see, should this be working?

If so, I can definitely create a small example. If not, do I have any other options?

Best regards,
Johan

1 Like

Hi @johan

If you need to perform some initialization before starting the server I believe you can just run that code before pn.serve. If you need to perform some initialization before each session starts I believe you can take a look at pn.state.on_session_created.

Hope that helps. Otherwise try to add some more specific information on what you are trying to achieve.

Thanks.

Thank you @Marc,

I am well aware that the architecture of this system is not the best but the issue is that I would like to download a relatively large data set from an FTP server on startup, it takes 5-10min, and I would like to have this data available for the users on the first session request. I host the app on azure as a container so when running the code before pn.serve I needed to increase the start-up time out limit, and it cannot be set to more than 15min. Because of this I wanted to perform the download after the app is loaded, as I am able to with the lifecycle hooks…(at least I assume that this is a solution)

I am also planning to have the app restart once a day to download any updated data and as a temporary work around for some memory leakage issues…

I assume one workaround could be to use the command line argument panel serve, from within a python script, to launch the app in directory format?..

Br,
Johan

@johan

I use lifecyle hooks in my panel and/or native bokeh server apps, but only use the command-line mechanism to run the server following the directory structure and naming requirements outlined in the bokeh documentation.

With that caveat, I think the following example might work using panel.serve. I did not arrive at this solution from any documentation, but rather by poking around in the panel.state information and trial-and-error experimentation with the syntax to register the hooks.

I hope this helps.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
"""
import sys
import panel as pn

def on_server_loaded():
    print("server loaded")
    print("")
    sys.stdout.flush()

def on_session_created(session_context):
    print("session created")
    print("")
    sys.stdout.flush()
  
pn.state.onload(callback=on_server_loaded)
pn.state.on_session_created(callback=on_session_created)

pn.serve(pn.pane.JSON({'abc': 123}))
1 Like

Thanks a lot, @_jm,

My understanding of the onload-callback, though, is that it is triggered on session start and not on server start (ref. Deploy and Export — Panel 0.11.3 documentation). However, I while working on this I also realized that I was chasing the wrong solution with the lifecycle hooks. I needed to have the server returning something while I was downloading the data, but the on_server_loaded-method is run before the server is available to accept requests, so I will need to find some other solutions (which includes not performed the full data download on server start…) :slight_smile:

Best regards,
Johan

1 Like

Yes. The documentation makes it appear that way…

However experimentation makes it seem like the onload method behaves like the on_server_loaded lifecycle hook in the core bokeh solution.

With the trivial example included above in the thread, the sequence of printouts confirms this and upon a user revisiting the URL from a different browser shows the distinction between when the onload method is called and when on_session_created hook is executed.

Just mentioning this for future reference in case someone needs to use these hooks but has constraints on either the command-line approach and/or the bokeh server directory format.

I don’t use Azure and don’t have a complete feel for your actual use case, so don’t have any helpful concrete additional recommendations. However, I will say that I use Redis in memory stores to communicate large data files for analysis to my apps hosted on a platform-as-a-service (Heroku).

If you need to have the server communicating something, perhaps the bokeh/panel server keep-alive pings in combination with some threading (or bokeh periodic callbacks or whatever) to handle the time-intensive downloads could work.