Dashboard development in a .py file

Trying a panel dashboard over a streamlit dashboard as I got stuck at support for bokeh 2.4.2 · Issue #4639 · streamlit/streamlit · GitHub

I would like to understand how to replicate my development steps of streamlit with panel.

In streamlit I was working out of a .py file (in vscode) and once I ran streamlit run script.py if I made any changes to the .py file I would get prompted on the dashboard that the source has changed and do I want to re-run (or always re-run). I would select always re-run for fast development and to stay away from the terminal.

If I am to replicate this with panel (although I know panel is more jupyter friendly for development with the extension). I run panel serve script.py --show (just thinking out loud: should --show be default?). Also if I kill it i’ll have to bump the port number (panel serve script.py --show --port 5007) as the previous command won’t work (in streamlit the ports are bumped each call which I prefer as a lazy developer). Is there a way the dashboard can be updated after calling panel server script.py and changing script.py without launching the server command again?

Last question: Is .servable() required after every element I want to show? (for .py development).

Sorry there are a few comments/questions in here. Looking forward to becoming more familiar with all dashboarding tools (one can aspire to be @Marc!). Thanks for everyone’s work on this project.

Getting Started — Panel v0.13.0 says

You can edit your Panel code as a .py file in any text editor, marking the objects you want to render as .servable()

This answered my question of

Is .servable() required after every element I want to show? (for .py development).

1 Like

I hope you would find the .py development experience using panel serve name_of_script.py --autoreload --show and marking whatever you want to server as .servable very easy. That is the intention.

Please share suggestions for improvements as you go along.

Here is an example using an api similar to Streamlits

import panel as pn
import networkx as nx

from bokeh.models import Circle, MultiLine
from bokeh.plotting import figure, from_networkx

pn.extension(sizing_mode="stretch_width", template="fast")

color = pn.widgets.ColorPicker(value="darkblue", name="Color").servable(area="sidebar")

def create_plot(color):
    G = nx.karate_club_graph()

    edge_attrs = {}

    for start_node, end_node, _ in G.edges(data=True):
        edge_color = (
            if G.nodes[start_node]["club"] == G.nodes[end_node]["club"]
            else DIFFERENT_CLUB_COLOR
        edge_attrs[(start_node, end_node)] = edge_color

    nx.set_edge_attributes(G, edge_attrs, "edge_color")

    plot = figure(
        x_range=(-1.2, 1.2),
        y_range=(-1.2, 1.2),
        title="Graph Interaction Demo",
        tooltips="index: @index, club: @club",
    plot.grid.grid_line_color = None

    graph_renderer = from_networkx(G, nx.spring_layout, scale=1, center=(0, 0))
    graph_renderer.node_renderer.glyph = Circle(size=15, fill_color=color)
    graph_renderer.edge_renderer.glyph = MultiLine(
        line_color="edge_color", line_alpha=0.8, line_width=1.5
    return plot


pn.state.template.param.update(title="Bokeh Network graph")


Yes marking the objects you want to serve with .servable() and using --autoreload is the way.

As for:

although I know panel is more jupyter friendly for development with the extension

I wouldn’t really say Panel is more Jupyter friendly, with autoreload developing an app from a python files is pretty good. But if you like (I personally do), you can also develop your app or bits of your app in a notebook.


Thanks for the feedback @Marc and @maximlt. Made a (very) small doc PR here: DOC: mention --autoreload by raybellwaves · Pull Request #3451 · holoviz/panel · GitHub