Skip to content

About

Hosted Bokeh App Demos

Resources

Stars

25 stars

Watchers

11 watching

Forks

Repository files navigation

demo.bokeh.org

This repository powers the Bokeh example gallery. It contains a static landing page and Python applications served through Bokeh's ASGI adapter. The examples are grouped by use case and domain, and the catalog records how each one runs.

Preview

Filled terrain contours crossed by an adjustable transect
Terrain contour explorer: linked contours, a movable transect, and an elevation profile.
Streaming candlestick market chart with technical indicators
Streaming market simulator: intraday OHLC data, volume, drawdown, and MACD.
A colorful cellular automata grid
Cellular automata simulator: editable rules, live pattern comparison, and automatic classification.
Hubble image processing before and after views
Hubble image processing: an editable crop linked to several image-processing pipelines.

What lives here

  • catalog.py is the source of truth for routes and gallery metadata.
  • apps/ contains self-contained applications using public datasets or clearly labeled computed data.
  • site/ contains the shared visual system, landing-page template, Bokeh document template, and deployed error page.
  • framework-demos/ builds the unlisted BokehJS framework examples as static pages, independently of the Python applications.
  • asgi.py serves the landing page, assets, health endpoint, and Bokeh routes.
  • deploy/ecs-task-definition.json is the application-owned deployment template.

The explicit runtime metadata leaves room for BokehJS framework examples and Pyodide or PyScript examples without putting them through the Python server application lifecycle.

Most examples combine several Bokeh features around a practical problem. The vehicle demo recomputes a linked histogram from the current selection. The market simulator connects a seeded, unlimited OHLC stream to volume and MACD. The oscillator demo combines MathText and streaming with three views of the same simulation. The terrain demo links filled contours to a transect that can be moved and rotated.

Other applications map regional airport access over CARTO tiles, use NetworkX for graph analysis, and combine Xarray, Numba, and scikit-image for image processing. Public inputs come with the installed libraries. Computed examples say when their data is synthetic. The container needs no external data service at runtime, although the browser fetches basemap tiles for the airport map.

Gallery previews are crops of Bokeh output from the corresponding application. The Hubble preview and application both use the public-domain NASA/STScI Hubble Deep Field image.

The palette and footer match the Bokeh marketing site. Layouts vary with the example, and toolbars appear only where navigation or selection is useful.

Runtime shape

Each container runs one Uvicorn worker and one BokehASGI instance. Because Bokeh session state is local to the process, ECS tasks provide horizontal concurrency. ALB cookie affinity keeps each browser on the same task for the life of its session.

The production image runs free-threaded Python 3.14 with the GIL disabled. CI checks the active GIL state after importing every application, and the deployment workflow builds the image for ARM64 Fargate tasks.

The public endpoints are:

  • /: generated gallery
  • /404.html: shared Bokeh 404 page
  • /healthz: runtime health and active Python GIL state
  • /robots.txt: crawler policy and sitemap discovery
  • /sitemap.xml: homepage and listed demo routes generated from the catalog
  • /.well-known/security.txt: private vulnerability-reporting contact and policy
  • /monitor: directly accessible, sanitized view of the whole demo service and the task serving the session; it is not listed in the gallery yet
  • /assets/*: shared site CSS
  • every route declared in catalog.DEMOS

All HTTP responses carry the same browser security policy. Stateful Bokeh documents are explicitly non-cacheable; static site assets, crawler files, and the security contact can be cached for one hour. Catalog and application pages also provide canonical, Open Graph, and large-card metadata using the shared site/social-preview.png image. Regenerate that PNG from the maintainable SVG with:

rsvg-convert --width 1200 --height 630 \
  --output site/social-preview.png site/social-preview.svg

site/404.html is an exact copy of the page introduced by bokeh/infra#6 and maintained at components/error-pages/404/404.html in that repository. Update it from the infra source instead of editing the local copy. The ASGI wrapper also returns this page, with status 404, for missing application routes and assets.

Run locally

Docker

The image uses free-threaded Python 3.14, the checked-in uv lockfile, and Bokeh 3.10.0. It loads the matching BokehJS bundles from Bokeh's CDN.

docker build --tag bokeh-demo .
docker run --rm --publish 5006:5006 bokeh-demo

Open http://localhost:5006.

uv

Install uv, then run the ASGI server. uv creates and syncs the locked environment automatically:

uv run --locked uvicorn asgi:application

Open http://127.0.0.1:8000.

The biomass explorer uses the subscribed Arraylake Icechunk repository for native 100 m detail when ARRAYLAKE_API_TOKEN is set. Keep that service-account token in the runtime environment or deployment secret store, never in this repository. Without it, the application remains usable through the public CTrees COG source; broad world views always use COG overviews to avoid scanning the 26 TB native Icechunk array. At service startup, the app caches all 26 annual windows for its initial Pará footprint (about 16.5 MB), making every initial year comparison immediate without preloading arbitrary locations.

Measure that user-visible speedup against a cold query with:

ARRAYLAKE_API_TOKEN=... uv run --locked python scripts/benchmark_biomass.py

The benchmark exits unsuccessfully unless startup warming makes the same native-detail comparison at least five times faster.

Outside ECS, the monitor uses real current-process measurements and an in-memory service registry. For deterministic screenshots or UI development, run it with three clearly labeled simulated task reports:

DEMO_MONITOR_SOURCE=deterministic uv run --locked uvicorn asgi:application

/healthz returns {"status":"ok","python_gil":"disabled"} in the production runtime. If PYTHON_GIL=0 was requested but an imported extension turns the GIL back on, the endpoint remains HTTP 200 and reports {"status":"degraded","reason":"python_gil_enabled","python_gil":"enabled"}. The container stays available while the response explains the degraded state.

Development checks

Install the Git hooks once after cloning:

uv run --locked pre-commit install

Run the same hooks across the checkout at any time:

uv run --locked pre-commit run --all-files

Static framework demos

The unlisted pages at /react, /vue, /svelte, /components, and /nextjs show the same wave interference lab through the BokehJS framework adapters. /next.js is an alias for /nextjs. They share the site's header, footer, and visual styles, but run entirely in the browser. Each page links to its full source directory and shows a short adapter embedding snippet. Each source link opens a complete, independently runnable app: React, Vue, Svelte, Web Components, and Next.js. Every app includes its own dependencies, lockfile, build configuration, plotting code, styles, and README. Its BokehJS 4.0 development packages are pinned independently. The existing Python applications continue to use Bokeh 3.10.0 and its matching CDN resources.

With Node.js 24 or newer (which includes npm), copy any one app directory and run npm ci followed by npm run dev there. It does not need the parent project or another example. Each app also provides check, build, and preview scripts; see its README for details.

To build all five pages for the demo site, run from the repository root:

cd framework-demos
npm ci
npm run install:apps
npm run build
npm run preview

Open http://localhost:4173/react (or another framework route). To serve the pages alongside the Python gallery, build them first, then run the usual uv run --locked uvicorn asgi:application command from the repository root. Without a frontend build, the Python gallery still works and framework routes return the shared 404 page. Docker builds the framework pages automatically; Node.js is only used in the build stage.

The site build sets each app's BOKEH_DEMO_BASE asset prefix and copies its output into site/frameworks/. The app directories include snapshots of the site chrome and styles so they remain independently runnable; keep these snapshots in sync when changing the demo site's visual design. Generated files are not committed. Framework pages are omitted from the gallery and sitemap. The Next.js example uses a static export with browser-side interactive components, so it needs no Node.js server at runtime.

Check types and run the browser tests from framework-demos/:

npm run check
npm run build
npm exec -- playwright install chromium
npm test
npm run test:standalone

The standalone check copies each app outside the repository, installs from its own lockfile, checks types, builds it, and runs the same browser interactions against its local preview. CI verifies both these copies and the combined site.

Test

The tests use the complete dependency set pinned in uv.lock:

uv run --locked pytest

Pass a test module or node ID to narrow the run:

uv run --locked pytest tests/test_cellular_automata.py
uv run --locked pytest tests/test_cellular_automata.py::test_cellular_automata_compares_rules_from_the_same_state

The CI workflow installs the pinned 3.10 dependency, constructs every Bokeh document, exercises static ASGI responses, and checks the container build.

Deploy

The bokeh/infra repository owns the AWS resources under terraform/stacks/aws-demo. This repository contains no Terraform.

The Publish and deploy workflow runs for every push to main and may also be started manually. It uses GitHub OIDC to build a Linux ARM64 image natively on GitHub's ARM64 runner, push it to ECR under an immutable sha-* tag, register a new ECS task definition, update the worker service, wait for stability, and verify the production health endpoint.

Pull requests run all checks and build the container without publishing or deploying it. Merging to main is therefore the normal release action; no Terraform command is needed for an application-only change. The workflow summary records the immutable image digest used by ECS.

To roll back an application release, rerun the workflow for the desired commit or revert the change on main. ECR retains the twenty most recent immutable release images. Infrastructure operations are documented in the bokeh/infra AWS demo stack README.

See Production operations for rollout verification, CloudWatch callback timings, event-loop lag queries, and smoke-test guidance. The monitor data-source and privacy note documents its public contract, DynamoDB exchange, measurement scopes, local behavior, deployment order, and cost boundary.

About

Hosted Bokeh App Demos

Resources

Stars

25 stars

Watchers

11 watching

Forks

Releases

Packages

Used by

Contributors

Languages