# fossasia/visdom architecture

> Architecture diagram of the GitHub repository fossasia/visdom, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-21). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/fossasia/visdom
- Repository: https://github.com/fossasia/visdom

## Overview

1. **What this repository is**
   - Visdom is a dual-runtime visualization system: a **Python package** that exposes the user-facing API, and a **browser UI** that renders and manages visualizations.
   - The core architectural goal is to let Python code stream plots, images, text, and interactive widgets into a **persistent, shareable dashboard server**.

2. **Top-level runtime split**
   - The main backend lives under `py/visdom/server` and runs as the `visdom` command / `python -m visdom.server`.
   - The frontend lives under `js/` and is bundled into static assets served by the Python server.
   - The Python client API is in `py/visdom`, which is what user code imports to send visualization commands.

3. **Primary data flow**
   - User code calls the Python client (`Visdom`) to create/update windows.
   - Those requests are sent to the server over HTTP and, when callbacks are enabled, a socket channel is used for frontend-to-backend events.
   - The server stores window state in an environment model, then serves that state back to the browser UI as JSON-like window data.

4. **Server-side responsibilities**
   - `py/visdom/server/app.py` and `handlers/` define the HTTP and socket boundaries.
   - `web_handlers.py` serves pages and static UI assets, while `socket_handlers.py` handles interactive event traffic.
   - `run_server.py` and `__main__.py` wire up startup, command-line flags, host/port/base URL selection, and optional login mode.

5. **Persistent environment model**
   - The key state unit is the **environment** (`env`), which groups windows and survives across sessions.
   - Environments are serialized to disk under the user’s visdom directory, with `env_path` controlling where state is loaded from.
   - The UI can save, fork, clear, delete, and reload envs; these are not just view-only artifacts but the durable backing store for dashboards.

6. **Views versus environments**
   - Environments hold the actual windows and data; **views** capture layout state such as window positions and sizes.
   - The view subsystem is managed in the frontend and persisted separately, so users can switch between visual organization schemes without changing the underlying data.
   - This separation matters architecturally: content state and layout state are related but stored and restored independently.

7. **Frontend application structure**
   - `js/main.js` is the application entrypoint for the browser UI.
   - The UI is organized around a top bar, modals, and a set of pane types that render specific content kinds.
   - The frontend is built from reusable modules such as `Pane`, specialized panes, event plumbing, and controls for filtering, env switching, and view management.

8. **Pane-based rendering model**
   - Each visualization appears as a **pane/window** in the UI.
   - Specialized pane classes include `PlotPane`, `ImagePane`, `TextPane`, `PropertiesPane`, `NetworkPane`, `EmbeddingsPane`, and comparison/image variants.
   - This is the main presentation boundary: the backend stores generic window data, and the frontend chooses a pane implementation based on content type.

9. **Interactive callback loop**
   - The repo supports frontend-generated events such as close, keypress, property updates, image clicks, and lasso selections.
   - These events are routed back to Python through registered event handlers, which lets user code react to UI interactions.
   - This makes Visdom not just a renderer, but a live bidirectional interaction system.

10. **Plotting and content types**
    - The API supports several content families: images, text, audio, video, SVG, properties, embeddings, network graphs, and a broad set of Plotly-backed charts.
    - Plotly is a major rendering dependency for charts; Matplotlib, audio/video codecs, and image encoding are additional content-specific dependencies.
    - The server is effectively a content router and state manager, while the frontend adapts each content type to a suitable pane.

11. **Authentication, read-only mode, and offline/logging behavior**
    - The server can run with optional login, secure cookie handling, and bind-local restrictions.
    - Read-only mode disables mutation paths, which changes the server’s role from interactive dashboard manager to viewer.
    - The Python client also supports offline logging and replay, which introduces a second execution mode where commands are recorded locally rather than sent live.

12. **Build, packaging, and static asset delivery**
    - JavaScript is bundled via Webpack (`webpack.*.js`) and served from `py/visdom/static/js`.
    - Python packaging includes both server code and built frontend assets, so installation from pip delivers a self-contained app.
    - The repo also includes TypeScript-like typing support artifacts (`py.typed`, `.pyi`) and release/update workflows that keep Python and JS build outputs in sync.

13. **Testing and verification boundaries**
    - Cypress tests under `cypress/` exercise the browser UI end to end, validating pane behavior, exports, modals, screenshots, and environment interactions.
    - Example scripts under `example/` serve as integration samples for the Python API.
    - The architecture is therefore validated at both layers: Python client/server behavior and browser rendering/interaction behavior.

Main entry points: [`js/main.js`](https://github.com/fossasia/visdom/blob/dev/js/main.js) (Main UI), [`py/visdom/__init__.py`](https://github.com/fossasia/visdom/blob/dev/py/visdom/__init__.py) (Visdom API), [`py/visdom/server/app.py`](https://github.com/fossasia/visdom/blob/dev/py/visdom/server/app.py) (Server app), [`py/visdom/server/handlers/socket_handlers.py`](https://github.com/fossasia/visdom/blob/dev/py/visdom/server/handlers/socket_handlers.py) (Socket events)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_grp_python["Python runtime"]
  node_node_client_api["Visdom API<br/>Python client<br/>[__init__.py]"]
  node_node_offline["Offline log<br/>record/replay<br/>[__init__.py]"]
  node_node_server_app["Server app<br/>Tornado app<br/>[app.py]"]
  node_node_server_run["Startup<br/>boot/config<br/>[run_server.py]"]
  node_node_http_handlers["HTTP handlers<br/>request boundary<br/>[web_handlers.py]"]
  node_node_socket_handlers["Socket events<br/>interactive boundary<br/>[socket_handlers.py]"]
  node_node_env_model[("Env state<br/>persistent model<br/>[defaults.py]")]
  node_node_server_utils["Server utils<br/>storage/helpers<br/>[server_utils.py]"]
  node_node_static_assets["Static UI<br/>served assets<br/>[index.html]"]
end

subgraph group_grp_js["Browser runtime"]
  node_node_main_js["Main UI<br/>frontend entry<br/>[main.js]"]
  node_node_event_system["Event system<br/>ui plumbing<br/>[EventSystem.js]"]
  node_node_topbar["Top bar<br/>ui controls<br/>[EnvControls.js]"]
  node_node_modals["Modals<br/>ui dialogs<br/>[EnvModal.js]"]
  node_node_panes["Panes<br/>window rendering<br/>[Pane.js]"]
  node_node_plot_pane["Plot pane<br/>chart pane<br/>[PlotPane.js]"]
  node_node_media_panes["Media panes<br/>content panes<br/>[ImagePane.js]"]
  node_node_build["Frontend build<br/>webpack packaging<br/>[webpack.prod.js]"]
end

subgraph group_grp_qa["Validation"]
  node_node_examples["Examples<br/>sample apps<br/>[demo.py]"]
  node_node_cypress["Cypress tests<br/>e2e validation<br/>[basic.js]"]
end

node_node_client_api -->|"HTTP commands"| node_node_server_app
node_node_client_api -->|"callbacks"| node_node_socket_handlers
node_node_offline -.->|"replay"| node_node_client_api
node_node_server_run -->|"launches"| node_node_server_app
node_node_server_app -->|"routes"| node_node_http_handlers
node_node_server_app -->|"sockets"| node_node_socket_handlers
node_node_http_handlers -->|"reads/writes"| node_node_env_model
node_node_socket_handlers -->|"updates"| node_node_env_model
node_node_env_model -->|"persistence"| node_node_server_utils
node_node_http_handlers -->|"serves"| node_node_static_assets
node_node_static_assets -->|"loads"| node_node_main_js
node_node_main_js -->|"dispatches"| node_node_event_system
node_node_main_js -->|"composes"| node_node_topbar
node_node_main_js -->|"opens"| node_node_modals
node_node_main_js -->|"renders"| node_node_panes
node_node_panes -->|"specializes"| node_node_plot_pane
node_node_panes -->|"specializes"| node_node_media_panes
node_node_event_system -->|"emits events"| node_node_socket_handlers
node_node_client_api -.->|"demonstrates"| node_node_examples
node_node_cypress -->|"verifies"| node_node_main_js
node_node_build -->|"bundles"| node_node_static_assets

click node_node_client_api "https://github.com/fossasia/visdom/blob/dev/py/visdom/__init__.py"
click node_node_offline "https://github.com/fossasia/visdom/blob/dev/py/visdom/extra_deps/__init__.py"
click node_node_server_app "https://github.com/fossasia/visdom/blob/dev/py/visdom/server/app.py"
click node_node_server_run "https://github.com/fossasia/visdom/blob/dev/py/visdom/server/run_server.py"
click node_node_http_handlers "https://github.com/fossasia/visdom/blob/dev/py/visdom/server/handlers/web_handlers.py"
click node_node_socket_handlers "https://github.com/fossasia/visdom/blob/dev/py/visdom/server/handlers/socket_handlers.py"
click node_node_env_model "https://github.com/fossasia/visdom/blob/dev/py/visdom/server/defaults.py"
click node_node_server_utils "https://github.com/fossasia/visdom/blob/dev/py/visdom/utils/server_utils.py"
click node_node_static_assets "https://github.com/fossasia/visdom/blob/dev/py/visdom/static/index.html"
click node_node_main_js "https://github.com/fossasia/visdom/blob/dev/js/main.js"
click node_node_event_system "https://github.com/fossasia/visdom/blob/dev/js/EventSystem.js"
click node_node_topbar "https://github.com/fossasia/visdom/blob/dev/js/topbar/EnvControls.js"
click node_node_modals "https://github.com/fossasia/visdom/blob/dev/js/modals/EnvModal.js"
click node_node_panes "https://github.com/fossasia/visdom/blob/dev/js/panes/Pane.js"
click node_node_plot_pane "https://github.com/fossasia/visdom/blob/dev/js/panes/PlotPane.js"
click node_node_media_panes "https://github.com/fossasia/visdom/blob/dev/js/panes/ImagePane.js"
click node_node_examples "https://github.com/fossasia/visdom/blob/dev/example/demo.py"
click node_node_cypress "https://github.com/fossasia/visdom/blob/dev/cypress/integration/basic.js"
click node_node_build "https://github.com/fossasia/visdom/blob/dev/webpack.prod.js"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_node_client_api,node_node_offline,node_node_server_app,node_node_server_run,node_node_http_handlers,node_node_socket_handlers,node_node_env_model,node_node_server_utils,node_node_static_assets toneBlue
class node_node_main_js,node_node_event_system,node_node_topbar,node_node_modals,node_node_panes,node_node_plot_pane,node_node_media_panes,node_node_build toneAmber
class node_node_examples,node_node_cypress toneMint
```

## Components

### Python runtime

Client library and server-side application code

- [Visdom API](https://github.com/fossasia/visdom/blob/dev/py/visdom/__init__.py): Python client · User-facing package imported by applications to send visualization commands and register callbacks. · `py/visdom/__init__.py`
- [Offline log](https://github.com/fossasia/visdom/blob/dev/py/visdom/extra_deps/__init__.py): record/replay · Local command logging and replay mode when the client is not talking to a live server. · `py/visdom/extra_deps/__init__.py`
- [Server app](https://github.com/fossasia/visdom/blob/dev/py/visdom/server/app.py): Tornado app · Backend application entrypoint that assembles routes, handlers, and runtime configuration. · `py/visdom/server/app.py`
- [Startup](https://github.com/fossasia/visdom/blob/dev/py/visdom/server/run_server.py): boot/config · Command-line and process startup wiring for host, port, base URL, login, and read-only modes. · `py/visdom/server/run_server.py`
- [HTTP handlers](https://github.com/fossasia/visdom/blob/dev/py/visdom/server/handlers/web_handlers.py): request boundary · Web and base request handling for pages, assets, auth, and environment mutations. · `py/visdom/server/handlers/web_handlers.py`
- [Socket events](https://github.com/fossasia/visdom/blob/dev/py/visdom/server/handlers/socket_handlers.py): interactive boundary · Bidirectional event channel for callbacks and front-end generated interactions. · `py/visdom/server/handlers/socket_handlers.py`
- [Env state](https://github.com/fossasia/visdom/blob/dev/py/visdom/server/defaults.py): persistent model · Durable environment and window state that survives sessions and is serialized to disk. · `py/visdom/server/defaults.py`
- [Server utils](https://github.com/fossasia/visdom/blob/dev/py/visdom/utils/server_utils.py): storage/helpers · Shared backend helpers for environment paths, persistence, and server-side state operations. · `py/visdom/utils/server_utils.py`
- [Static UI](https://github.com/fossasia/visdom/blob/dev/py/visdom/static/index.html): served assets · Built HTML, CSS, and bundled JavaScript files served by the Python server. · `py/visdom/static/index.html`

### Browser runtime

UI application and pane rendering

- [Main UI](https://github.com/fossasia/visdom/blob/dev/js/main.js): frontend entry · Browser application entrypoint that bootstraps the dashboard UI and top-level state. · `js/main.js`
- [Event system](https://github.com/fossasia/visdom/blob/dev/js/EventSystem.js): ui plumbing · Front-end event propagation and callback plumbing for user interactions. · `js/EventSystem.js`
- [Top bar](https://github.com/fossasia/visdom/blob/dev/js/topbar/EnvControls.js): ui controls · Environment switching, filtering, connection status, and view management controls. · `js/topbar/EnvControls.js`
- [Modals](https://github.com/fossasia/visdom/blob/dev/js/modals/EnvModal.js): ui dialogs · Environment and view dialogs used for save, fork, reload, and layout management. · `js/modals/EnvModal.js`
- [Panes](https://github.com/fossasia/visdom/blob/dev/js/panes/Pane.js): window rendering · Shared pane abstraction that renders each visualization window in the dashboard. · `js/panes/Pane.js`
- [Plot pane](https://github.com/fossasia/visdom/blob/dev/js/panes/PlotPane.js): chart pane · Visualization pane for plots and chart-like content, including Plotly-backed renderings. · `js/panes/PlotPane.js`
- [Media panes](https://github.com/fossasia/visdom/blob/dev/js/panes/ImagePane.js): content panes · Specialized panes for images, text, properties, embeddings, and networks. · `js/panes/ImagePane.js`
- [Frontend build](https://github.com/fossasia/visdom/blob/dev/webpack.prod.js): webpack packaging · JavaScript bundling pipeline that produces the static assets shipped with the Python package. · `webpack.prod.js`

### Validation

Examples and end-to-end tests

- [Examples](https://github.com/fossasia/visdom/blob/dev/example/demo.py): sample apps · Python scripts demonstrating the client API and content families. · `example/demo.py`
- [Cypress tests](https://github.com/fossasia/visdom/blob/dev/cypress/integration/basic.js): e2e validation · Browser end-to-end tests covering panes, exports, modals, screenshots, and environment flows. · `cypress/integration/basic.js`

## Connections

- Visdom API → Server app: HTTP commands · The Python client sends visualization updates and queries to the backend over HTTP.
- Visdom API → Socket events: callbacks · Registered event handlers receive interactive events from the browser through the socket channel.
- Offline log → Visdom API: replay · Offline mode records the same client commands for later replay.
- Startup → Server app: launches · Startup code configures and starts the server application.
- Server app → HTTP handlers: routes · The app mounts HTTP endpoints for pages, assets, auth, and mutations.
- Server app → Socket events: sockets · The app attaches interactive event handlers for browser-to-backend communication.
- HTTP handlers → Env state: reads/writes · Requests load, update, save, clear, and delete environment state.
- Socket events → Env state: updates · Interactive events can mutate the environment and window state.
- Env state → Server utils: persistence · Persistence helpers locate storage paths and serialize environment data.
- HTTP handlers → Static UI: serves · The backend serves the browser application and built assets.
- Static UI → Main UI: loads · The browser bootstraps from the bundled JavaScript entrypoint.
- Main UI → Event system: dispatches · UI events are routed through the front-end event system.
- Main UI → Top bar: composes · The main app mounts connection, filter, environment, and view controls.
- Main UI → Modals: opens · The main app manages dialogs for environment and view operations.
- Main UI → Panes: renders · The app creates panes for each window in the current environment.
- Panes → Plot pane: specializes · Charts and plots use a dedicated rendering path.
- Panes → Media panes: specializes · Non-chart content is handled by specialized pane implementations.
- Event system → Socket events: emits events · Interactive UI actions flow back to Python through the socket channel.
- Visdom API → Examples: demonstrates · Example scripts show the intended API usage and content types.
- Cypress tests → Main UI: verifies · End-to-end tests exercise the browser UI and pane behavior.
- Frontend build → Static UI: bundles · Webpack produces the browser bundle shipped by the Python package.
