Skip to main content

girder-dashboards

A Girder 5 plugin that adds a new class of entity: Dashboards — lightweight, interactive UIs operating on the data gathered in a Girder instance.

A dashboard is a small JS app. It gets a card in a gallery reachable from a Dashboards entry in the left sidebar, and when opened it takes over the whole window: none of Girder's usual header, navigation or footer, just the dashboard and a top bar with the way back.

What you get

  • Sidebar entryDashboards in the global navigation, routing to #dashboards.
  • Card gallery (#dashboards) — image, name, description, an Open action for users with READ access, and a settings gear for users with ADMIN access.
  • Config page (#plugins/dashboards/config, linked from Admin console → Plugins) — a site admin enables/disables each installed dashboard, edits its card, edits its settings, and controls who may open it.
  • Full-window runner (#dashboard/<id>) — the dashboard renders under Girder's Layout.EMPTY, with a Dashboards back link in its own top navbar.
  • One bundled dashboardData Overview, a small worked example. Real dashboards are separate plugins (see below).

Dashboards live in their own plugins

Beyond the bundled example, a dashboard is a separate pip-installable plugin that declares itself against this one. Installing it adds a card; uninstalling it takes the card away and leaves the admin's settings behind in case it comes back.

pip install girder-dashboards girder-dashboards-precipitate

girder-dashboards-precipitate is the worked example of a substantial one: precipitate detection and inter-particle spacing measurement on SEM/TEM micrographs, with a Celery backend, its own REST resource and its own scientific-stack extra. None of that is this package's concern — which is the point.

To write your own, see docs/extending.md. It is a step-by-step recipe with a complete copy-pasteable example, and it was verified by building that example and driving it in a browser.

How a dashboard is put together

A dashboard has two halves that meet at a shared key:

Half Where Responsibility
Declaration Python, registerDashboard() That the dashboard exists, and what its card says
Implementation web_client, registerDashboard() The Backbone view that renders it

The Python half is what makes dashboards discoverable server-side, so the config page can list them and cards can render without every dashboard's JS having to be parsed first.

Persistent state lives in a dashboard document, one per registered key. It holds the parts an admin owns — enabled, the ACL, the card metadata, and a free-form settings object handed to the view at runtime. Documents are created by an atomic upsert at plugin load, so a restart or a redeploy never clobbers an admin's edits, and concurrent workers can't race into duplicates.

New dashboards start disabled but publicly readable: enabling one is the only step needed to offer it to everyone, and narrowing the ACL is how you restrict it.

Adding a dashboard from your own plugin

Server side, from your plugin's load():

from girder.plugin import GirderPlugin, getPlugin
from girder_dashboards import registerDashboard


class MyPlugin(GirderPlugin):
    def load(self, info):
        getPlugin("dashboards").load(info)
        registerDashboard(
            "sample-throughput",
            name="Sample Throughput",
            description="Samples registered per week, by instrument.",
            image="https://example.org/card.png",  # optional; falls back to `icon`
            icon="icon-chart-line",
            settings={"weeks": 12},
        )

Client side, from your web_client entry point:

import SampleThroughputView from './dashboards/SampleThroughputView';

girder.plugins.dashboards.registerDashboard('sample-throughput', {
    view: SampleThroughputView
});

The view is instantiated with {el, parentView, dashboard, settings}, where dashboard is the DashboardModel and settings is its (admin-editable) settings object. Render into el and you own the viewport below the top bar.

Registering after this plugin has loaded is fine — new registrations are provisioned immediately rather than at the next restart. Call getPlugin("dashboards").load(info) first, though: that is what puts this plugin's bundle ahead of yours in the browser, and your entry point reads girder.plugins.dashboards at module scope. docs/extending.md has the full story, including packaging, the Vite config and how to test it.

REST API

Dashboards

All routes are under /api/v1/dashboard.

Route Access Purpose
GET /dashboard public Dashboards readable by the caller. includeDisabled / includeUnavailable are site-admin only.
GET /dashboard/{id} READ A single dashboard.
PUT /dashboard/{id} ADMIN Change name, description, image, icon, enabled, settings.
PUT /dashboard/{id}/reset ADMIN Restore the card metadata and settings the plugin declared.
DELETE /dashboard/{id} site admin Prune a document whose implementation is gone.
GET/PUT /dashboard/{id}/access ADMIN Read/set the ACL.

Every response carries an extra available flag: false means the document's key no longer has a registered implementation, e.g. the plugin that shipped it was uninstalled. Such dashboards are hidden from the gallery but still listed on the config page so an admin can remove them.

Development

Server side:

tox -e lint          # ruff check .
tox -e pytest        # needs a running MongoDB

Web client, from girder_dashboards/web_client/:

npm ci
npm run build        # vite build -> dist/, required before the server can serve the assets
npm run dev          # vite build --watch

registerPluginStaticContent in girder_dashboards/__init__.py serves the built dist/girder-plugin-dashboards.umd.cjs and dist/style.css, so rebuild after changing web_client source and reload Girder.

Build the web client before running the Python tests: the plugin hashes the files in web_client/dist at load time, so without them every test that starts a server fails.

End-to-end browser check, against a running Girder:

(cd test/browser && npm ci && npx playwright install chromium)   # once
python3 test/browser/seed.py     # admin, the bundled dashboard enabled, sample collections
node test/browser/verify.cjs

It drives headless Chrome through the gallery, the runner and the config page as both an anonymous and an admin user, and fails on any console error or failed request. Screenshots are written to test/browser/screenshots/. Configure with GIRDER_URL, GIRDER_ADMIN, GIRDER_PASSWORD. Both scripts are idempotent, so they can be re-run against the same instance, and the harness adapts to whatever other dashboard plugins are installed alongside. Those plugins bring their own harness for their own dashboard.

CI (.github/workflows/build-test.yaml) runs lint, the Python tests, and the browser check on every push to main and every pull request.

License

BSD-3-Clause — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

girder_dashboards-0.2.0.tar.gz (25.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

girder_dashboards-0.2.0-py3-none-any.whl (25.2 kB view details)

Uploaded Python 3

File details

Details for the file girder_dashboards-0.2.0.tar.gz.

File metadata

  • Download URL: girder_dashboards-0.2.0.tar.gz
  • Upload date:
  • Size: 25.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for girder_dashboards-0.2.0.tar.gz
Algorithm Hash digest
SHA256 d6ccdb9c15b3518f124994a46daa3bdefa4ee4d0d5b88962cd06642e99e3d163
MD5 137888fe4704afb4277e17e547f4cf4c
BLAKE2b-256 8e8e151583a6f549fce99f0d269a50a83320190bffba5a2f69d07c26983149f3

See more details on using hashes here.

Provenance

The following attestation bundles were made for girder_dashboards-0.2.0.tar.gz:

Publisher: release.yml on Xarthisius/girder-dashboards

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file girder_dashboards-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for girder_dashboards-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 35817807d449de5edca49d1e9ef14bed104cde81cde8ce9b34d9b4e4c56d19d8
MD5 408d5cb8cbe6152f2268b3487a430960
BLAKE2b-256 21313846be509b39aeea20139a7c79b5f426c9d4f22fb857e7c367b36f94907f

See more details on using hashes here.

Provenance

The following attestation bundles were made for girder_dashboards-0.2.0-py3-none-any.whl:

Publisher: release.yml on Xarthisius/girder-dashboards

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page