Skip to content

feat: remove the Private JupyterHub launch option - #152

Merged
mmcky merged 2 commits into
mainfrom
feat/remove-private-jupyterhub
Sep 5, 2026
Merged

feat: remove the Private JupyterHub launch option#152
mmcky merged 2 commits into
mainfrom
feat/remove-private-jupyterhub

Conversation

@mmcky

@mmcky mmcky commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Collapses the notebook launcher to a direct Colab link. Closes #87.

Why now

#87's resolution path was "gather demand/usage signal from lecture maintainers." That signal is available from the lecture repos themselves, and it is empty.

The book-theme only renders its hub button when jupyterhub_url is set in _config.yml (launch.py appends it to launch_buttons conditionally). An org-wide code search finds that key in no lecture repo at all — every hit is inside quantecon-book-theme itself. What the flagship series actually configure:

Repo Configured launch targets
lecture-python-programming colab_url
lecture-python.myst colab_url
lecture-python-intro colab_url
lecture-jax colab_url

So the hub button has never appeared on a live QuantEcon lecture site over the lifetime of the incumbent theme.

It was also not the feature it looked like

Probed against a live build rather than read off the source. Typing http://localhost:8888 into the box produced:

http://localhost:8888/jupyter/hub/user-redirect/git-pull?repo=https://github.com/QuantEcon/quantecon-theme.mystmd.notebooks&branch=main&urlpath=tree/quantecon-theme.mystmd.notebooks/notebook.ipynb

Three things that URL shows:

  • The /jupyter/hub/ segment is hardcoded. The Sphinx theme builds {jupyterhub_url}/user-redirect/git-pull?…, leaving the whole prefix to configuration, so any hub layout works. This baked QuantEcon's production layout into the code, so it could only ever address hubs at <host>/jupyter/hub/ — a stock JupyterHub at /hub/user-redirect/ would 404, and you cannot compensate from the text box.
  • It targets a Hub, not a server. /hub/user-redirect/ is JupyterHub routing; a plain jupyter lab has no such route, and nbgitpuller on a single-user server answers at /git-pull.
  • It never touches local content. git-pull clones from GitHub — here a .notebooks repo that does not exist — so even on a correctly configured hub it fetches published notebooks rather than what you are reading.

There was no config key of any kind, so it rendered unconditionally even on Colab-only sites, and privateServiceUrl was React.useState('') — verified that closing the popover resets the field to "" and the radio to unchecked, so the URL had to be retyped for every launch.

What changed beyond deleting the option

  • LaunchButton is now an anchor, not a button driving window.open, matching the GitHubButton idiom. With no choice left to make there is nothing for a popover to hold, and a real link restores middle-click, open-in-new-tab and copy-link. The href is computed at render from the manifest, so it is present in the served HTML and works without JS.
  • It renders nothing when project.github or the page location is missing. Previously the popover still opened with every control inside it disabled — the clickable-but-inert affordance Code cells nested in a directive are never registered with the kernel, so they render a run button that does nothing #117 was about.
  • buildJupyterHubUrl and its unit tests are removed.
  • @radix-ui/react-popover and @radix-ui/react-radio-group are dropped from package.json — the launcher was their only consumer, as react-dialog was for the history modal. Confirmed no other consumer repo-wide, and that refactor: rebuild the contents drawer on the Popover API #144 does not introduce one.
  • launch-open.png and both its baselines are deleted — there is no popover to photograph. launch-colab now asserts the anchor's href instead of stubbing window.open, which is offline and deterministic and additionally pins that the control is a link, so a regression back to a chooser fails the test.

Verification

npm run compile clean · npm run test:unit 18/18 · full visual suite 19 passed, 3 skipped, against untouched baselines — the toolbar is visually identical, which is why no snapshot moved.

Follow-up

Re-adding launch targets properly is tracked as three separate enhancement issues linked from #87 (JupyterHub, BinderHub, and local-server connections via Thebe), each with the background research behind it.

🤖 Generated with Claude Code

Collapses the launcher to a direct Colab link. Closes #87.

The demand signal #87 was gated on came back empty. The book-theme only
renders its hub button when `jupyterhub_url` is set in `_config.yml`, and an
org-wide search finds that key in no lecture repo at all — every flagship
series configures `colab_url` alone — so the button has never appeared on a
live QuantEcon site.

The MyST version was also not the same feature. It had no config key and
rendered unconditionally, asking the reader to type a hub URL into a box whose
value was `React.useState('')`, discarded as soon as the popover closed.
Probing a live build showed it also hardcodes a `/jupyter/hub/` path segment
that the Sphinx theme leaves to the configured URL, so it only ever addressed
hubs at `<host>/jupyter/hub/` — not a stock JupyterHub, and not a local Jupyter
server, which it could not reach in any case because nbgitpuller clones from
GitHub rather than serving local files.

Changes beyond deleting the option:

- `LaunchButton` becomes an anchor rather than a button driving `window.open`,
  matching `GitHubButton`. With no choice left to make there is nothing for a
  popover to hold, and a real link restores middle-click and open-in-new-tab.
- It renders nothing when `project.github` or the page location is missing.
  Previously the popover still opened with everything inside it disabled, which
  is the clickable-but-inert affordance #117 was about.
- `buildJupyterHubUrl` and its unit tests are gone; `@radix-ui/react-popover`
  and `@radix-ui/react-radio-group` had no other consumers and are dropped from
  package.json, as `react-dialog` was when the history modal was removed.
- `launch-open.png` and its two baselines are deleted — there is no popover to
  photograph. `launch-colab` now asserts the anchor's `href`, which also pins
  that the control is a link, so a regression back to a chooser fails here.

Verified: `npm run compile` clean, `npm run test:unit` 18/18, and the full
visual suite 19 passed / 3 skipped against untouched baselines.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings August 26, 2026 02:41
@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-09-05 02:50 UTC

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

🎭 Visual regression results

passed  19 passed
skipped  5 skipped

Details

stats  24 tests across 1 suite
duration  38.8 seconds
commit  15ed360

Skipped tests

mobile-chrome › theme.spec.ts › QuantEcon theme — visual regression › without JavaScript › drawer-opens-without-javascript
mobile-chrome › theme.spec.ts › QuantEcon theme — visual regression › drawer-closes-when-search-opens
mobile-chrome › theme.spec.ts › QuantEcon theme — visual regression › launch-colab
mobile-chrome › theme.spec.ts › QuantEcon theme — visual regression › live-compute-toggle
mobile-chrome › theme.spec.ts › QuantEcon theme — visual regression › live-compute-toggle-absent-without-thebe

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes the Private JupyterHub notebook-launch option (resolving #87), collapsing the launcher from a Radix popover with a radio group and a hand-typed service-URL box down to a single direct anchor to Google Colab. The href is computed at render from the manifest, so the link is present in the server-rendered HTML and supports middle-click/open-in-new-tab. The change also drops the now-unused buildJupyterHubUrl builder, its unit tests, the Radix popover/radio-group dependencies, and the launch-open.png visual baseline.

Changes:

  • Rewrote LaunchButton as an <a> (from a Popover + RadioGroup + window.open), rendering nothing when project.github or the page location is missing.
  • Removed buildJupyterHubUrl and its tests; converted the launch-colab visual test to assert the anchor's href/target instead of stubbing window.open.
  • Dropped @radix-ui/react-popover and @radix-ui/react-radio-group direct dependencies and updated README/PLAN/CHANGELOG/types documentation.

Reviewed changes

Copilot reviewed 9 out of 12 changed files in this pull request and generated no comments.

Show a summary per file
File Description
app/components/toolbar/LaunchButton.tsx Replaces popover/radio launcher with a direct Colab anchor; hides control when repo/location missing
app/components/toolbar/launchUrls.ts Removes the now-unused buildJupyterHubUrl builder
tests/unit/launch-urls.test.mjs Drops JupyterHub URL tests and the HUB fixture constant
tests/visual/theme.spec.ts Rewrites launch-colab to assert the anchor href/target rather than a stubbed popover
package.json / package-lock.json Removes the Radix popover and radio-group direct dependencies
app/types.ts Updates comment to reference only Colab launch URLs
README.md / PLAN.md / CHANGELOG.md Documents the removal and future-work tracking

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@mmcky

mmcky commented Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

@DrDrij we don't use this so I suggest we remove for now.

I have opened issues to track better integration points.

…upyterhub

# Conflicts:
#	CHANGELOG.md
#	app/components/toolbar/LaunchButton.tsx
#	tests/visual/__snapshots__/desktop-chrome-darwin/launch-open.png
#	tests/visual/__snapshots__/desktop-chrome-linux/launch-open.png
#	tests/visual/theme.spec.ts

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The removal leaves user-facing docs outside the diff stale — template/README.md still advertises launching "Private Jupyter Hub" sessions and README.md's Live-compute section still says "Colab/Hub".

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 9/12 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@mmcky

mmcky commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto current main (merge commit 15ed360) after #165#169 landed. Resolutions: LaunchButton.tsx keeps this PR's anchor but takes #165's tooltip shape (Tooltip asChild wrapping the <a>, so the anchor is the only interactive element); theme.spec.ts keeps both #144's no-JavaScript drawer test and this PR's launch-colab href assertion; the changelog entry sits under [Unreleased]Removed between today's Changed and Fixed entries; the two launch-open.png baselines that #166/#167 had refreshed are deleted, since there is no popover to photograph. The auto-merged lockfile was already consistent (only react-radio-group drops relative to main; react-popover stays hoisted for @myst-theme/site). Verified locally: compile clean, 18 unit tests, full visual + FOUC suite 21 passed / 5 skipped with every remaining baseline untouched. The first CI run hung in the Playwright WebKit download step and was re-run; all jobs green on the same head. Copilot's original review stands with no inline comments.

@mmcky
mmcky merged commit 01bd015 into main Sep 5, 2026
6 of 7 checks passed
@mmcky
mmcky deleted the feat/remove-private-jupyterhub branch September 5, 2026 02:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consider removing the Private JupyterHub launch option (Colab-first direction)

2 participants