Communication between a notebook and an application

Hello,

I am new to both this forum and the (apparently great) holoviz ecosystem. Apologies if I’m posting to the wrong category (please let me know in this case and I will update the post accordingly).

I am looking for a way to do the following:

I have a Panel app able to plot data that are generated by Python functions. For now these functions are defined on the server side (i.e. the panel app), but I would like that the user can interactively provide her own custom Python functions to this app.

One way to do it would be to allow the user to define a custom function in a jupyter notebook, e.g.:

def f(x):
    return 2 * x

Then having a way to send this function definition from the notebook to the Panel app with a syntax like:

send_function(app_url='localhost:5006', function_to_send=f)

The function f would be serialized, sent to the app, and deserialized on the server side, such that the panel app can generate data using f.

Any idea on how I could achieve this?

Thanks a lot!

1 Like

HI @clement-moulin-frier

Welcome to the community.

The core problem

  • to get access to the code
  • execute the code

To get access the code, the user could upload the notebook via a FileInput widget or just copy the code into the Ace editor widget. If the user uploads a notebook there are python packages that can convert it into a code string.

To execute the code string you can use exec.

Below I provide an example using the Ace editor widget. It would need some more error handling to be robust.

Please note executing user code on your server enables the user to take over or mess with your server!.

import panel as pn

pn.extension("ace", sizing_mode="stretch_width", template="fast", theme="dark")
pn.state.template.title="Code Editor"

CODE = """\
import pandas as pd
import hvplot.pandas

def plot(x):
    return pd.DataFrame({
        "x": range(x),
        "y": [y+x for y in range(x)]
    }).hvplot(x="x", y="y")
"""

code = pn.widgets.Ace(value=CODE, language='python', theme="monokai")
x = pn.widgets.IntSlider(name="x", value=5, start=0, end=10, step=1)

@pn.depends(x, code)
def plot(x, code):
    d={}
    exec(code,d)
    if "plot" in d:
        return d["plot"](x)
    else:
        return "plot(x) function not defined"

pn.Column("## Code", code, "## Interactive Plot", x, plot).servable()
panel serve script.py

code-editor-speedup

You could use panel convert ... to convert your app to run in the users browser. Then the users could not execute dangerous code on your server.

1 Like

Thanks a lot for your reply, @Marc

Using the Ace editor widget looks like an interesting option. However, i’d like the user to edit the code outside of the server (such as she can e.g. debug it before sending it to the server).

Actually I’m just thinking I could reformulate my question in a more general way. What I am looking for in general is the ability to send data from a client (which in my use case is a jupyter notebook) to the server (which is a Panel application). The data can be for instance numpy arrays ; or functions.

So I am wondering if Panel (or another holoviz lib) is able to handle this natively? Or should I instead encapsulate the Panel app within web server such as Flask? In the second case, is there a web server library which is recommend to be used with the holoviz ecosystem? (e.g. Flask?).

Thanks you :slight_smile:

One way to go about loading data to a Panel app is add a REST API to your app.

You can find inspiration in Panel v0.10 blog post and Panel with Tranquilizer REST API (github.com).

Unfortunately there is no official documentation. Only a request to Document REST API functionality · Issue #2867

As an alternative you can embed Panel in Flask, Django and FastAPI. For inspiration check out FastAPI — Panel

1 Like

I was actually looking at the Panel v0.10 blog post just before you sent your message :slight_smile:

I think that solves my problem, thanks a lot for your help @Marc !

1 Like

That is great.

If you have troubles feel free to open a new post. If you succeed we would love to see the results and some minimum, reproducible code :smile:

Maybe this?

hrbigelow/streamvis: Write custom Bokeh interactive visualizations that receive streaming data from your application (github.com)

Seems like it allows you to send chart layout & data from client.

Hi,

Sorry I reply just now. Just for info, the best way I found to exchange data between the client and the server is the grpc librairy: https://grpc.io/

I found it much easier to use than a REST API. It works great on a local network, I’m not sure if it also works between machine on different networks, to check.