Skip to content

Contributors guide

As an application contributor you enhance an existing web application by UI contributions developed in Python. You implement a Python module that is consumed by (one of) the application's backend servers that implement the Chartlets REST API as described in the Contributors Guide.

Your module is supposed to export one or more instances of the chartlets.Extension class. An extension object is a container for your UI contributions. It groups contributions that logically belong together.

As an example, see my_extension of the demo.

To develop an extension, follow these steps:

  1. Create the extension object
  2. Create the contribution object
  3. Implement the contribution layout
  4. Implement the contribution callbacks
  5. Register the contribution

In the following the above steps are detailed further.

Create the extension object

Your contributions to the application are published using a chartlets.Extension object that is exported from your extension module.

from chartlets import Extension

ext = Extension("my_dashboard")

Create the contribution object

In a submodule you create a contribution object from an application specific contribution, e.g., a Panel from the Chartlets demo server. Application-specific contribution classes are always derived from chartlets.Contribution.

from server.contribs import Panel

panel = Panel(title="Click Statistics")

Implement the contribution layout

In the submodule

@panel.layout()
def get_layout(ctx):
  return Button(id="button", text="Click me")

Implement the contribution callback

In the submodule

from chartlets import Import, Output

@panel.callback(
  Input("button", "n_clicks"),
  Output("button", "text")
)
def on_button_click(ctx, n_clicks):
  n = n_clicks + 1
  s = {1: "st", 2: "nd", 3: "rd"}.get(n, "th")
  return f"Click me a {n}{s} time"

Register the contribution

In the extension module

from chartlets import Extension
from .stats_panel import panel as stats_panel

ext = Extension("my_dashboard")
ext.add(stats_panel)

How to report progress for long-lasting processes

For callbacks that may take a noticeable amount of time, add a progress component to the layout and declare its hidden property as one of the callback outputs.

from chartlets import Input, Output
from chartlets.components import Box, Button, CircularProgress, Typography

@panel.layout()
def get_layout(ctx):
    return Box(
        children=[
            Button(id="run_button", text="Run calculation"),
            CircularProgress(id="loading_progress", hidden=True),
            Typography(id="result_text", text=""),
        ]
    )

@panel.callback(
    Input("run_button", "clicked"),
    Output("loading_progress", "hidden"),
    Output("result_text", "text"),
)
def run_calculation(ctx, clicked):
    result = do_long_running_work()
    return True, result

The progress component starts hidden. When the callback is invoked, chartlets sees that the callback outputs to loading_progress.hidden and shows the progress component while the backend request is pending. When the callback returns, the first return value is applied to hidden; returning True hides the progress component again.

The progress output must remain part of the callback outputs. If it is removed, chartlets cannot know that this callback should show the progress component.