Skip to main content

boro

author and compose mosaic clients as anywidgets

install

uv add boro

what

mosaic is an architecture for interactive linked views over millions of rows: clients publish queries, a coordinator manages and cross-filters them against a data source (e.g., duckdb).

vgplot is how you usually author custom mosaic-based visualizations, a bundle with its own grammar and layout. boro is the same client/coordinator architecture, but each client is a standalone anywidget.

primitives

three anywidgets:

  • Coordinator — owns a DataSource and the js-side mosaic engine. brokers queries over arrow ipc. headless.
  • Selection — wraps a mosaic Selection. value syncs the array of clauses (sql predicates) to python.
  • Client — base class. Required coord; conventional filter_by (read side) and target (publish side) selection slots, both boro.SelectionTrait. Subclasses can declare further selection slots with boro.SelectionTrait().

The base accepts a unified selection= shortcut covering all four shapes:

Histogram(c, ..., selection=sel)              # crossfilter (both slots = sel)
Histogram(c, ..., selection=(scope, detail))  # asymmetric pair
Histogram(c, ..., selection=(sel, None))      # read-only (filter only)
Histogram(c, ..., selection=(None, sel))      # publish-only

Explicit filter_by= / target= kwargs override the shortcut.

each client is its own _esm and DOM. the mosaic engine and js deps live once, in the coordinator; clients reach it via host.getWidget(...).

hello world

import boro
import duckdb

con = duckdb.connect()
con.execute("CREATE TABLE flights AS SELECT * FROM read_parquet('flights.parquet')")

c = boro.Coordinator.connect(con)
sel = boro.Selection.crossfilter(c)
Histogram(c, table="flights", column="delay", selection=sel)
Scatter(c, table="flights", x="distance", y="delay", selection=sel)
>>> sel.value
[{'value': [5, 30], 'sql': '"delay" BETWEEN 5 AND 30', 'meta': {...}, 'source': '...'}]

writing a client

import boro
import traitlets


class RowCounter(boro.Client):
    _esm = """
    export default {
      async render({ model, host, signal, el }) {
        el.style.cssText = "font: 14px ui-sans-serif; padding: 6px 8px;";
        el.textContent = "…";
        const coord = await host.getWidget(model.get("coord"));
        const { Query, msql, createClient } = coord.exports;
        const ctx = await createClient({ model, host, signal });
        ctx.liveQuery({
          filterBy: ctx.filterBy,
          query: (filter) =>
            Query.from(model.get("table"))
              .select({ n: msql.count() })
              .where(filter ?? []),
          onResult: (result) => {
            if (!result.isSuccess) {
              return;
            }
            const n = Number(result.data.toColumns().n[0]);
            el.textContent = `${n.toLocaleString()} rows`;
          },
        });
      },
    };
    """
    table = traitlets.Unicode().tag(sync=True)

    def __init__(self, coord: boro.Coordinator, table: str, **kwargs):
        super().__init__(coord=coord, table=table, **kwargs)


RowCounter(c, table="flights", selection=sel)

coord.exports provides Query / msql (mosaic-sql), mc (mosaic-core), and createClient. createClient({ model, host, signal }) returns a ctx that exposes:

  • ctx.selections.<name> — resolved mosaic Selections, one per boro.SelectionTrait field on the Python class (filter_by / target come from the base; subclasses can declare more).
  • ctx.state(name, opts?) — a {get, set, subscribe} handle on a sync trait. Optional {target, clause} opts auto-derive a clause from the trait and publish it to a Selection on every change.
  • ctx.liveQuery({ filterBy }, queryFn, onState) — registers a filter-driven query. onState receives {status: 'idle'|'pending'|'success'|'error', data, error}.
  • ctx.coordinator — the mosaic Coordinator for one-shot ad-hoc queries (await ctx.coordinator.query(sql, { type: 'arrow' })).
  • ctx.client, ctx.clients, ctx.signal — the synthetic primary MosaicClient (clause source identity), the Set of all sibling clients used for cross-filter exclusion in state-derived clauses, and the abort signal scoped to this render.

example

uv run jupyterlab examples/

Metadata

Release files for boro 0.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for boro 0.0.0
File Size Uploaded
boro-0.0.0.tar.gz 12.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for boro 0.0.0
File Interpreter ABI Platform
boro-0.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 27.6 kB

Release files / boro-0.0.0.tar.gz

Download URL boro-0.0.0.tar.gz
Size 12.0 kB
Tags Source
SHA-256 checksum
How to use checksums
79b0621b125c93580de9bbf30784204b38e70a9fd883fe757f1a1560dd8df0bf
BLAKE2b-256 checksum
How to use checksums
7b502a9cf15d0e46b3f1768b27e32e90006912f8fed6df7cef68b27cf8f6a7dd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / boro-0.0.0-py3-none-any.whl

Download URL boro-0.0.0-py3-none-any.whl
Size 15.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4657a987fc461998dcb52271fe374bbd7d87e15db67135a22d7e4e92d623fb8c
BLAKE2b-256 checksum
How to use checksums
b0d035df76979ae731ece4751b0cee8e3ccccc087d2b59dc3b3b7574a3b2969a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page