Remote Interface¶
pgwidgets can be controlled from a Python server over WebSocket using the pgwidgets-python package. The browser page connects to the server, which sends JSON messages to create widgets, call methods, and receive callbacks.
Setup¶
Install the Python remote package:
pip install pgwidgets-python
Synchronous Example¶
from pgwidgets.sync import Application
app = Application()
@app.on_connect
def setup(session):
W = session.get_widgets()
top = W.TopLevel(title="Remote App", resizable=True)
top.resize(400, 300)
vbox = W.VBox(spacing=8)
btn = W.Button("Click me")
status = W.Label("Ready")
btn.on("activated", lambda: status.set_text("Clicked!"))
vbox.add_widget(btn, 0)
vbox.add_widget(status, 1)
top.set_widget(vbox)
top.show()
app.run()
Async Example¶
import asyncio
from pgwidgets.async_ import Application
app = Application()
@app.on_connect
async def setup(session):
W = session.get_widgets()
top = await W.TopLevel(title="Async App", resizable=True)
await top.resize(400, 300)
vbox = await W.VBox(spacing=8)
btn = await W.Button("Press me")
label = await W.Label("Waiting...")
btn.on("activated", lambda: label.set_text("Pressed!"))
await vbox.add_widget(btn, 0)
await vbox.add_widget(label, 1)
await top.set_widget(vbox)
await top.show()
asyncio.run(app.run())
How It Works¶
The Python server starts a WebSocket server.
The browser page includes
Widgets.jsand connects via theRemoteInterfaceclass.The Python side sends JSON commands (
create,call,destroy) and the browser executes them.When a widget fires a callback, the browser sends the event back over the WebSocket to the Python server.
The protocol is language-agnostic – any WebSocket client that speaks the JSON protocol can drive the UI.
Session Persistence and Reconnection¶
Sessions on the Python side persist independently of browser connections. The Python process is the source of truth for all widget state. When a browser disconnects (page refresh, network drop) and reconnects, the server replays the entire widget tree so the UI reappears in its current state.
The browser stores the session ID and security token (received via a
session-info message after the handshake). On reconnection, the
browser sends these back in the ack message so the server can match
it to the existing session. The RemoteInterface on the JS side
handles reconstruct-start / reconstruct-end brackets to suppress
callback echo during reconstruction.
Multi-Browser Synchronization¶
Multiple browsers can connect to the same session by navigating to the
session URL. When one browser triggers a state change (slider move, tab
switch, text edit, etc.), the Python server pushes the update to all
other connected browsers using silent calls. When a call includes
"silent": true, the RemoteInterface sets a _syncing flag so
the JS side executes the method but suppresses callback dispatch,
preventing infinite feedback loops.