Add a web UI with Panel (intermediate)

Audience: Users who want to communicate between the Lightning App and Panel.

Prereqs: Must have read the Panel basic guide.


Interact with the Component from Panel

The PanelFrontend enables user interactions with the Lightning App using widgets. You can modify the state variables of a Lightning Component using the AppStateWatcher.

For example, here we increase the count variable of the Lightning Component every time a user presses a button:

# app_panel.py

import panel as pn
from lightning.app.frontend import AppStateWatcher

pn.extension(sizing_mode="stretch_width")

app = AppStateWatcher()

submit_button = pn.widgets.Button(name="submit")

@pn.depends(submit_button, watch=True)
def submit(_):
    app.state.count += 1

@pn.depends(app.param.state)
def current_count(_):
    return f"current count: {app.state.count}"

pn.Column(
    submit_button,
    current_count,
).servable()
# app.py

import lightning as L
from lightning.app.frontend import PanelFrontend

class LitPanel(L.LightningFlow):
    def __init__(self):
        super().__init__()
        self.count = 0
        self.last_count = 0

    def run(self):
        if self.count != self.last_count:
            self.last_count = self.count
            print("Count changed to: ", self.count)

    def configure_layout(self):
        return PanelFrontend("app_panel.py")


class LitApp(L.LightningFlow):
    def __init__(self):
        super().__init__()
        self.lit_panel = LitPanel()

    def run(self):
        self.lit_panel.run()

    def configure_layout(self):
        return {"name": "home", "content": self.lit_panel}


app = L.LightningApp(LitApp())
Panel Lightning App updating a counter from the frontend

Panel Lightning App updating a counter from the frontend


Interact with Panel from a Component

To update the PanelFrontend from any Lightning Component, update the property in the Component. Make sure to call the run method from the parent component.

In this example, we update the count value of the Component:

# app_panel.py

import panel as pn
from lightning.app.frontend import AppStateWatcher

app = AppStateWatcher()

pn.extension(sizing_mode="stretch_width")

def counter(state):
    return f"Counter: {state.count}"

last_update = pn.bind(counter, app.param.state)

pn.panel(last_update).servable()
# app.py

from datetime import datetime as dt
from lightning.app.frontend import PanelFrontend

import lightning as L


class LitPanel(L.LightningFlow):
    def __init__(self):
        super().__init__()
        self.count = 0
        self._last_update = dt.now()

    def run(self):
        now = dt.now()
        if (now - self._last_update).microseconds >= 250:
            self.count += 1
            self._last_update = now
            print("Counter changed to: ", self.count)

    def configure_layout(self):
        return PanelFrontend("app_panel.py")


class LitApp(L.LightningFlow):
    def __init__(self):
        super().__init__()
        self.lit_panel = LitPanel()

    def run(self):
        self.lit_panel.run()

    def configure_layout(self):
        tab1 = {"name": "home", "content": self.lit_panel}
        return tab1

app = L.LightningApp(LitApp())
Panel Lightning App updating a counter from the component

Panel Lightning App updating a counter from the Component


Tips & Tricks

  • Caching: Panel provides the easy to use pn.state.cache memory based, dict caching. If you are looking for something persistent try DiskCache its really powerful and simple to use. You can use it to communicate large amounts of data between the components and frontend(s).

  • Notifications: Panel provides easy to use notifications. You can for example use them to provide notifications about runs starting or ending.

  • Tabulator Table: Panel provides the Tabulator table which features expandable rows. The table is useful to provide for example an overview of you runs. But you can dig into the details by clicking and expanding the row.

  • Task Scheduling: Panel provides easy to use task scheduling. You can use this to for example read and display files created by your components on a scheduled basis.

  • Terminal: Panel provides the Xterm.js terminal which can be used to display live logs from your components and allow you to provide a terminal interface to your component.

Panel Lightning App running models on github

Panel Lightning App running models on GitHub