Skip to main content

jupyterlab-rtclauncher

A small JupyterLab 4 extension for the NASA Research Platform. It adds a Launcher tile"Open <project> Collaboration" — that opens the project's shared real-time-collaboration (RTC) server.

Without it, members reach the shared server through JupyterHub's admin UI (/hub/admin), which is why they were granted the broad-looking admin-ui scope. This extension replaces that route so the scope can be dropped.

How it works

The tile is state-aware: it starts the shared server when it is down, and stops it when it is up.

server down │ "Open abtesting Collaboration"  ──▶ /hub/spawn/abtesting-collab
            │                                  ──▶ /user/abtesting-collab/lab
────────────┼──────────────────────────────────────────────────────────────────
server up   │ "Stop abtesting Collaboration"  ──▶ confirm ──▶ DELETE server
  1. On activation the frontend calls GET /jupyterlab-rtclauncher/config, which reads the spawn-time environment and answers with the project and shared account name.
  2. It then polls GET /jupyterlab-rtclauncher/status (every 15s) to track whether the shared server is running.
  3. Start is a plain navigation to <hubPrefix>/spawn/<project>-collab. Stop posts to /jupyterlab-rtclauncher/stop after a confirmation dialog, which proxies DELETE /hub/api/users/<project>-collab/server.

Why stopping matters

The shared server bills the project pool for as long as it runs. JupyterHub's idle culler reaps it after 1h idle, but an open browser tab keeps refreshing last_activity and can defeat that — and since the admin-ui scope was dropped, members have no other way to shut it down. The Stop action closes that gap.

Note the server's 10Gi EBS home persists whether it runs or not; stopping releases the compute, which is the expensive part.

Why the stop goes through the server extension

The hub's _xsrf cookie is scoped to Path=/hub/, so JavaScript served from /user/<name>/lab cannot read it — and JupyterHub 5 requires that XSRF token for cookie-authenticated, non-GET API calls. The stop therefore proxies through this extension's server handler, which authenticates with the notebook server's own JUPYTERHUB_API_TOKEN.

That token only carries admin:servers!user=<project>-collab when the user genuinely holds it: JupyterHub resolves Spawner.server_token_scopes against the user's own scopes and drops the rest. A user outside the project's Keycloak group gets a token without it and the hub answers 403. The extension grants nothing.

Requires rp-deployment to request that scope via Spawner.server_token_scopes (terraform/config/20-nojovyan.py). Without it, can_control is false and the tile degrades to start-only.

Which projects get a tile

Any project with collaboration enabled — there is no hardcoded project list and no allowlist to configure here.

The enablement signal is the RP_COLLAB_ACCOUNT environment variable:

  1. A platform admin flips Real-Time Collaboration → Enable collaboration for a project in the RPAdmin console, which provisions its login-less <key>-collab principal.
  2. RPAdmin's GET /api/me/spawn-identity — already called on every spawn — now returns collab_account: "<key>-collab" for that project, or null.
  3. rp-deployment terraform/config/20-nojovyan.py forwards a non-null value to the notebook as RP_COLLAB_ACCOUNT.
  4. This extension shows the tile only when that variable is present.

So enabling a new project is a toggle in RPAdmin — no change to this extension, the spawner, or the image. OSSProject supplies the project key for the tile's label; the account name comes from RP_COLLAB_ACCOUNT so the naming convention lives only in RPAdmin.

Operational note. JupyterHub access is granted separately, by the RP_COLLAB_PROJECT_KEYS allowlist in rp-deployment (the ISSO widening gate, feature 083). A project enabled in RPAdmin but missing from that allowlist will show a tile whose spawn the hub refuses — enabling collaboration is a two-step operation by design, and the two must be kept in sync.

The tile grants nothing

It is a link. Starting the shared server requires admin:servers!user=<acct> and entering it requires access:servers!user=<acct>; both are granted to the project's Keycloak /smdc-oss/<project> group by rp-deployment terraform/config/41-collab-accounts.py, and auto-revoke when Keycloak drops the membership. A user without them who follows the link is refused by the hub.

The tile hides itself when RP_COLLAB_ACCOUNT is unset (collaboration is off for the project), or when the current server is the collaboration server (JUPYTERHUB_USER ends in -collab).

Install

pip install jupyterlab-rtclauncher

Both the frontend and the server extension are enabled automatically. To verify:

jupyter labextension list   # jupyterlab-rtclauncher ... enabled OK
jupyter server extension list

Development

pip install -e ".[test]"
jupyter labextension develop . --overwrite
jlpm build

Run the tests:

python -m pytest tests/   # server extension
jlpm test                 # frontend

Rebuild after a source change with jlpm build, or run jlpm watch in one terminal and jupyter lab in another.

Uninstall

pip uninstall jupyterlab-rtclauncher

Related

  • Feature 083 — RTC collaboration accounts (rpadmin/specs/083-rtc-collab-accounts/)
  • jupyterlab-resource-tracker — the usage & cost extension shipped in the same image

Download files

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

Source Distribution

jupyterlab_rtclauncher-0.2.0.tar.gz (152.6 kB view details)

Uploaded Source

Built Distribution

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

jupyterlab_rtclauncher-0.2.0-py3-none-any.whl (39.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: jupyterlab_rtclauncher-0.2.0.tar.gz
  • Upload date:
  • Size: 152.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.6

File hashes

Hashes for jupyterlab_rtclauncher-0.2.0.tar.gz
Algorithm Hash digest
SHA256 d00d31e76908c42f46ea17ddf11339333be079abe1a4efcf988c3e23cd524554
MD5 561bbe6dcd37ed64fb35dae31dbf88eb
BLAKE2b-256 20f86ce3ae1f5171f99d2741a56fae308051bea8f054e2a5ab8071903fe18cca

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for jupyterlab_rtclauncher-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4e65a83e94cc8237427afca7073604de80d1a246adf1666e5ccf10ecb897f845
MD5 ff17e17f1b5529acf17746bfb133370d
BLAKE2b-256 c15760b63bd4c27147b4ece8b29ec31c5eef4d5fcae2f9502799511b81e123ac

See more details on using hashes here.

Release history Release notifications | RSS feed

0.3.0

2 files

This release

0.2.0 This release

2 files

0.1.0

2 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