Skip to main content
Version: 0.3.1

07: Signal input

A button click that emits a signal with a payload ({n_clicks, random_number}); a separate callback receives the payload and updates a label. The canonical producer/consumer signal pattern.

The script

import random
from dash import html
from dash_extensions.enrich import Output, Input
from weaverlet.base import SignalOutput, SignalInput, WeaverletComponent, WeaverletApp, Identifier
from weaverlet.components import SignalComponent


class SignalInputComponent(WeaverletComponent):

trigger_button_id = Identifier()
label_p_id = Identifier()

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.signal_component = SignalComponent()

def get_layout(self):
return html.Div(
[
self.signal_component(), # child component
html.Button('Click to trigger signal with input',
id=self.trigger_button_id),
html.P(id=self.label_p_id)
]
)

def register_callbacks(self, app):

@app.callback(
SignalOutput(self.signal_component),
Input(self.trigger_button_id, 'n_clicks')
)
def button_click(n_clicks):
return {'n_clicks': n_clicks, 'random_number': random.random()}

@app.callback(
Output(self.label_p_id, 'children'),
SignalInput(self.signal_component)
)
def label_update(signal_input):
return f'Signal triggered! Signal input: {signal_input}'


signal_trigger_component = SignalInputComponent()

wapp = WeaverletApp(root_component=signal_trigger_component)
wapp.app.run(port=8089)

Expected output

  • The page shows a button and an empty paragraph.
  • Each click updates the paragraph with the current n_clicks and a new random number.

Notes

  • SignalComponent is a dcc.Store underneath, exposed as a class-level Weaverlet object so producers and consumers reference it via self.<signal> instead of a string ID.
  • SignalOutput(self.signal_component) is the emit-side adapter; the producer callback must return a dict.
  • SignalInput(self.signal_component) is the receive-side adapter; the consumer callback receives the dict as its argument.
  • The signal must be rendered in the layout via self.signal_component(): otherwise the underlying dcc.Store doesn't exist in the DOM and the callbacks never fire.
  • Multiple consumers can listen to the same signal. Each consumer fires on every emission.

Try it locally

pip install weaverlet
python signal_input_app.py

See also