Skip to content

cetic/pyplet_examples

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pyplet Example Apps

Pyplet couples a Tornado backend with Pyodide-powered clients so you can write full-stack apps in pure Python. The micro apps in this repository showcase how Pyplet bridges browser DOM APIs, plotting libraries, and WebSockets to build interactive experiences quickly.

Each example ships as a pair of <name>_client.py and <name>_server.py files plus a shared config.py. The client code runs in Pyodide, the server in Tornado, and the packaging hooks allow Pyplet to bundle, serve, and bootstrap everything dynamically.

To run these apps you need Pyplet installed in your environment (for example from the main Pyplet repository or a future package distribution). Point Pyplet’s apps root to this folder and start the server:

# From a project that has Pyplet installed
PYPLET_APPS=/path/to/pyplet_examples pyplet start

If you vendor this repository inside another project (for instance under apps/pyplet_examples), you can use a relative apps root:

PYPLET_APPS=apps/pyplet_examples pyplet start

These examples are independent of any particular “template” project: you can wire them into any Pyplet-powered application by configuring the apps root appropriately.

Included apps

Chat (chat_client.py, chat_server.py)

  • Real-time multi-user chat driven entirely by async WebSocket loops.
  • Demonstrates server-side user pooling and broadcast messaging plus DOM updates directly from Python.
  • chat_client.py:26 decodes the initial handshake so the UI can announce the assigned username.
  • chat_client.py:31 wraps the DOM change event with create_proxy to send WebSocket messages straight from Python.
  • chat_server.py:35 repackages incoming text and chat_server.py:42 fan-outs the payload to every connected peer.

Dashboard (dashboard_client.py, dashboard_server.py)

  • Live monitoring panel that charts connection counts from other example services.
  • Highlights streaming JSON over WebSockets into Matplotlib figures rendered in the browser.
  • dashboard_client.py:17 draws historical series into Matplotlib lines before the figure is mounted inside the DOM.
  • dashboard_client.py:28 streams live JSON updates, mutating line data and rescaling the axes (dashboard_client.py:32).
  • dashboard_server.py:23 samples connection counts from other services, while dashboard_server.py:45 keeps a background task pushing updates.

Desktop (desktop_client.py, desktop_server.py)

  • Simulates a desktop environment with detachable windows loading the main site.
  • Mixes pyplet.dom primitives with jQuery UI dialogs to show interop with existing JS widgets.
  • desktop_client.py:8 builds a dialog with an iframe mounted via pyplet.dom, reproducing desktop-like windows.
  • desktop_client.py:27 renders the Pyplet DOM tree into the browser and wires on_load for each popup.
  • desktop_client.py:31 hands control to jQuery UI dialogs, and desktop_client.py:44 strips navigation chrome from the embedded page.

Frontend Only (frontend_only_client.py, frontend_only_server.py)

  • Fully client-side demo that leverages NumPy and Matplotlib via Pyodide.
  • Shows how to package additional libraries with client_libraries without needing a Python server loop.
  • frontend_only_client.py:6 composes the page entirely with pyplet.dom from the browser context.
  • frontend_only_client.py:12 and frontend_only_client.py:14 use NumPy plus Matplotlib in Pyodide to plot locally.
  • frontend_only_server.py:1 declares the extra client libraries so the bundle ships scientific tooling without a Python backend.

NumPy Stream (numpy_client.py, numpy_server.py)

  • Streams random matrices from the server and draws them as heatmaps.
  • Illustrates binary data transfer over WebSockets and live figure updates.
  • numpy_client.py:12 deserializes np.load buffers from WebSocket frames and numpy_client.py:14 seeds a live imshow.
  • numpy_client.py:18 updates the image in-place for smooth animation as data arrives.
  • numpy_server.py:15 creates random matrices each second and numpy_server.py:18 streams the raw bytes to clients.

Sync NumPy (sync_numpy_client.py, sync_numpy_server.py)

  • Broadcast version of the NumPy stream where every viewer shares the same feed.
  • Uses a background task to push frames to all connected clients, demonstrating fan-out patterns.
  • sync_numpy_client.py:1 reuses the regular NumPy client loop to stay in sync with the shared feed.
  • sync_numpy_server.py:17 launches a background task that continually generates frames for all viewers.
  • sync_numpy_server.py:24 iterates active sockets safely, removing disconnected clients during broadcast.

Sync Slider (sync_slider_client.py, sync_slider_server.py)

  • Mirrors a jQuery UI slider across every connected browser through a shared WebSocket loop.
  • Highlights how to wrap DOM callbacks with asyncio.create_task without blocking Pyodide.
  • sync_slider_client.py:24 forwards slider moves asynchronously via create_proxy_with_this.
  • sync_slider_server.py:32 handles closing_message to drop peers, while sync_slider_server.py:36 fans out updates with asyncio.gather.

Gradient Descent Playground (gradient_descent_playground_client.py, gradient_descent_playground_server.py)

A tiny 1D optimization playground that runs entirely in the browser via Pyodide. It demonstrates how to pair rich canvas rendering, interactive controls, and optimizer implementations within a Pyplet micro app.

App anatomy

  • gradient_descent_playground_client.py — browser logic (UI, state, animation, rendering, events)
  • gradient_descent_playground_server.py — minimal server glue (route for the app)

The client runs in Pyodide. DOM is built with pyplet.dom and events are wired through Pyodide proxies so JavaScript can call back into Python.

Client lifecycle

  1. Pyplet loads the module in the browser and discovers client_init().
  2. client_init() constructs GradientDescentPlaygroundApp and awaits setup().
  3. setup() builds the DOM, registers event proxies, samples the objective, and initializes state.
  4. When the page unloads, cleanup() removes listeners and destroys proxies.

See gradient_descent_playground_client.py:1160 (client_init) and gradient_descent_playground_client.py:1136 (cleanup).

UI & controls

  • Function: choose an objective from the sidebar
  • Optimizer: GD, Momentum, Adam
  • Hyperparameters: sliders for lr, beta, beta1, beta2, eps
  • Transport: Play, Pause, Step, Reset
  • Canvas interactions:
    • Click sets the current x position
    • Mouse wheel zooms
    • Middle-button drag pans
  • Diagnostics readout removed so the sidebar now focuses entirely on the controls described above.

Implementation outline

  • Layout & wiring: render_layout, setup_canvas, setup_controls (see gradient_descent_playground_client.py)
  • State: hyperparameters + iterate, reset_state, resample, evaluate_state
  • Animation: play, pause, step_once, on_animation_frame
  • Rendering: draw + helpers (draw_grid, draw_axes, coordinate transforms)

Extending the playground

Add a new objective function:

  1. Create a new entry in the FUNCTIONS dictionary with a unique key and label (gradient_descent_playground_client.py:92).
  2. Provide a radio option in the layout if you want it selectable (gradient_descent_playground_client.py:243).

Add a new optimizer:

  1. Implement its update rule in apply_optimizer_step(...) (gradient_descent_playground_client.py:974).
  2. Initialize/reset accumulators in reset_optimizer_state(...) (gradient_descent_playground_client.py:654).
  3. Add a radio button to the Optimizer group in render_layout(...) (gradient_descent_playground_client.py:255).
  4. Add slider(s) in setup_controls(...) and update on_hyperparameter_change(...) (gradient_descent_playground_client.py:362, gradient_descent_playground_client.py:523).

Tips

  • Autograd NumPy is imported as anp. Use it for differentiable math.
  • Keep app-specific assets in this folder for packaging simplicity.
  • If you tweak domain, gradient_clip, or convergence thresholds, the canvas auto-scales unless the user has panned/zoomed.

Validation

No automated test suite yet. Run the server, interact with the UI, and watch for console errors. Confirm sliders, optimizer selection, and canvas rendering work as expected.

Troubleshooting

  • Nothing renders: ensure the server route is correct and the app URL matches the folder path.
  • Events not firing: check proxies are created and not garbage-collected; see setup_controls and setup_canvas in gradient_descent_playground_client.py.

These samples are meant to be launched through Pyplet’s packaging machinery (config.py). Start from any of them to explore how Pyplet keeps Python code running fluidly on both sides of the wire.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages