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:
- Create the extension object
- Create the contribution object
- Implement the contribution layout
- Implement the contribution callbacks
- 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.