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.29.x · pin >=0.29.0,<0.30

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.29.0,<0.30"
# or
uv add "hedron[workbench]>=0.29.0,<0.30"

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.29.0.tar.gz (29.4 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.29.0-py3-none-any.whl (34.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: hedron_workbench-0.29.0.tar.gz
  • Upload date:
  • Size: 29.4 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.29.0.tar.gz
Algorithm Hash digest
SHA256 a97ac426f9177f566ed59a048ab015f2744dbb7f43ed9a81ed02ce18deb80206
MD5 fda0c6fca72c3bb95c478baaf0523279
BLAKE2b-256 6507c981dbea2acb469a2bc6a90976a50aaf8ac182b668a27b9663c2f49ea76a

See more details on using hashes here.

File details

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

File metadata

  • Download URL: hedron_workbench-0.29.0-py3-none-any.whl
  • Upload date:
  • Size: 34.8 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.29.0-py3-none-any.whl
Algorithm Hash digest
SHA256 961f7a04c6e1fa36191f1ed67b66dee19a1993384a256c8cd3c497f3f9836a63
MD5 288f231dae7fc5ce18bff60a621af4c6
BLAKE2b-256 38bb9bb85e38299c33b868248fafcdfb14a4ae2575e00ed3ef7509ee53d83d04

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