Skip to main content

hedron-workbench

PyPI Python License: MIT

Optional Posit Workbench / RStudio Server deployment adapter for Hedron.

An existing FastAPI Hedron app can run unchanged behind Workbench by switching the launch command. Installing or importing this package does not wrap your application. RS_SERVER_URL is discovery-only and never grants trust.

Also available as hedron[workbench].

Package maturity: Beta · Train: 0.39.x · pin >=0.39.0,<0.40

Supported Workbench floor is 2025.05.1; current verified lane is 2026.07.0.

Behavior is reimplemented from observed fastapi-workbench 0.3.4 (MIT) with attribution. This package does not depend on or vendor that project.

Install

pip install "hedron-workbench>=0.39.0,<0.40"
# or
uv add "hedron[workbench]>=0.39.0,<0.40"

Hedron application facade

Import HedronWorkbench in place of Hedron. With no Workbench signal it is an ordinary Hedron application: local Uvicorn, generic ASGI root_path, routes, middleware, and cookies retain Hedron behavior.

from hedron_workbench import HedronWorkbench

app = HedronWorkbench(
    title="My app",
    session_secret="replace-me",
)

Run the same object locally with Uvicorn or on Workbench with the launcher:

uvicorn app:app --reload
hedron run app:app  # auto-selects the Workbench launcher when RS_SERVER_URL is present
hedron-workbench run app:app

For local proxy reproduction, use HedronWorkbench(workbench_mount="/s/session/p/123"). The explicit mount is applied before Hedron creates session/CSRF cookies and also handles prefixed request paths when the ASGI server does not set root_path.

The class cannot execute rserver-url itself: dynamic discovery needs a bound listener port before the module is imported. The launcher performs that ordering and passes the resolved deployment into the class.

Launcher path

hedron-workbench run app:app
hedron-workbench check --format json
hedron-workbench run app:create_app --factory

The launcher binds a loopback socket, runs rserver-url when RS_SERVER_URL is set, exports HEDRON_ROOT_PATH before importing the app (so session/CSRF cookie Path is correct), recognizes HedronWorkbench as already adapted, and serves with one normalizer.

External binds require the explicit --allow-external-bind flag. The built-in runner supports --reload and --workers: its parent binds and discovers once, then execs Uvicorn's supervisor/workers with the inherited listener and resolved mount. Reload and multiple workers cannot be enabled together.

workbenchify(app) remains available for adapting an already-created generic ASGI application. The response boundary repairs Hedron-owned cookies whose path is still /; third-party cookies remain application-owned.

app.workbench_status() returns a redacted deployment diagnostic without exposing session IDs, URL credentials, or token-shaped values.

Public links and email invites

Use the facade to build links that leave the current browser, such as email invites, OAuth callbacks, and password resets:

from fastapi import Request


@app.post("/invite")
def send_invite(request: Request):
    accept_url = app.external_url_for(
        "accept_invite",
        request=request,
        invite_id="abc123",
        query={"token": "signed-single-use-token"},
    )
    # enqueue email containing accept_url

external_url* is deliberately durable: a disposable Workbench /s/.../p/... session URL is rejected. Use browser_url* for a link that stays in the current interactive session, and deploy durable invitations/callbacks to a stable URL (typically Posit Connect or an explicit external_base_url). On Posit Connect, a request can supply the platform's app-base header, but it is accepted only when its path exactly matches ASGI root_path and Connect's protected runtime marker is present (or an immediate proxy peer is explicitly trusted). Outside either platform, configure a stable base explicitly:

app = HedronWorkbench(
    title="My app",
    session_secret="replace-me",
    external_base_url="https://apps.example.com/my-app",
)

If no trusted base exists, link generation raises ValueError; it never falls back to an untrusted inbound Host header. Route paths must remain local and query parameters are encoded structurally. A Workbench discovery result that contains only a mount path also fails for public links because its inferred origin is loopback; configure workbench_public_base_url for browser-only links or a stable external_base_url for durable links.

Hands-off URL adaptation

Hedron-owned component URL attributes (href, form actions, HTMX request and history paths, assets), safe local response redirects, HTMX redirect/location headers, OpenAPI, static assets, cookies, and WebSockets are mount-aware. A request-time ASGI root_path from Posit Connect or a generic proxy is sufficient; the app does not need to manually call local_href or mounted_redirect. Connect's authenticated proxy adds its content prefix to cookie paths but passes redirect locations through, so the adapter de-scopes only Hedron-owned cookies before Connect's outer rewrite and still mounts local response headers itself.

Mounted pages expose window.Hedron.href(), .fetch(), .eventSource(), .websocketUrl(), and .websocket() for application JavaScript. Python code can use app.href_for(), app.redirect_for(), app.browser_url_for(), and app.external_url_for(). app.external_base(request=...) captures a validated, immutable base for a background job; app.deployment_capabilities() explains whether that base is browser-only or durable.

Raw trusted HTML, arbitrary JavaScript strings, third-party ASGI response bodies, third-party cookies, and a stable sharing destination cannot be inferred safely. Those remain explicit integration points.

Diagnostics and topology profiles

hedron-workbench doctor --format json
hedron-workbench doctor app:app --live --mount /s/example/p/8050
hedron-workbench run app:app --topology launcher-kubernetes

doctor --live binds, discovers when applicable, imports the app after the handoff, and ASGI-probes generated URLs and cookie paths. Topology profiles cover local, local Launcher, Kubernetes Launcher, Slurm Launcher, and external reverse proxy deployments. Remote Launcher profiles select a reachable bind by default; proxy CIDRs must still be explicitly bounded (wildcard trust remains rejected).

Non-goals

Flask/Django/WSGI, bundling rserver-url, automated Connect publishing, treating Workbench or Connect login as Hedron identity, or guessing a durable deployment from an ephemeral session.

License

MIT. See the repository license.

Download files

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

Source Distribution

hedron_workbench-0.39.0.tar.gz (9.7 kB view details)

Uploaded Source

Built Distribution

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

hedron_workbench-0.39.0-py3-none-any.whl (11.3 kB view details)

Uploaded Python 3

File details

Details for the file hedron_workbench-0.39.0.tar.gz.

File metadata

  • Download URL: hedron_workbench-0.39.0.tar.gz
  • Upload date:
  • Size: 9.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","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}

File hashes

Hashes for hedron_workbench-0.39.0.tar.gz
Algorithm Hash digest
SHA256 f76850fc0b897528041d8ce39673c6eb46e86600eb1731c99e27a6ec01fb9fd8
MD5 4a575a7357b76f12f643056d09a927f8
BLAKE2b-256 e3e3006933563854c0afcc9245a9b21d0f3530a7d69ed98fcdd3713787055c53

See more details on using hashes here.

File details

Details for the file hedron_workbench-0.39.0-py3-none-any.whl.

File metadata

  • Download URL: hedron_workbench-0.39.0-py3-none-any.whl
  • Upload date:
  • Size: 11.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","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}

File hashes

Hashes for hedron_workbench-0.39.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1a3ff22a1530072f9ec974d5380c889e0f86d573af6f4d50c866f7899d84efd4
MD5 24604bc82f14949e672817d3f2ee9b75
BLAKE2b-256 1c9b96db5973020b1e38980eb844eefc60e4b01eb1ef78f6f85b024ccd787509

See more details on using hashes here.

Supported by

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