Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

genie-overlay

An embeddable "Ask Genie" button for any Databricks App.

Databricks dashboards have a built-in Genie experience: a floating button that answers questions using the data in front of you. Databricks Apps don't — until now. genie-overlay gives any app that same experience, as a drop-in overlay that requires zero changes to your app's code.

Click "Ask Genie" → "Pick an element" → click any chart, table, or number → ask a question grounded in exactly what you clicked.


Why this is different

It's a framework-agnostic reverse proxy, not a plugin. It sits in front of your already-running app, forwards every request and WebSocket to it untouched, and injects a small overlay into each HTML page. Because it works at the HTTP/WebSocket layer, it works with Streamlit, Dash, Gradio, FastAPI, Flask, Shiny, static sites — anything that serves HTTP.

  browser ──▶  genie-overlay proxy (public port)  ──▶  your app (localhost)
                     │  injects overlay.js into HTML
                     │  serves /_genie/api/ask ──▶ Genie Conversation API

What the user gets

  • Floating "Ask Genie" button on every page (isolated in a Shadow DOM, so it never clashes with your app's styles).
  • Pick-an-element: click any element on the page; its visible content — and, optionally, its underlying structured data — is attached as context.
  • Grounded answers from your Genie space: prose answer, the generated SQL, and the result table, with multi-turn follow-ups.
  • On-behalf-of-user auth: Genie runs as the logged-in user, so it honors their Unity Catalog permissions (falls back to the app's service principal).

Quickstart — add it to any app in 3 commands

From your app's folder (the one with app.yaml):

# 1. add the dependency
echo "genie-overlay @ git+https://github.com/arjuncode/genie-overlay.git" >> requirements.txt

# 2. install the CLI locally and wrap your app.yaml automatically (backs up the original)
pip install "git+https://github.com/arjuncode/genie-overlay.git"
genie-overlay wrap app.yaml --genie-space <YOUR_GENIE_SPACE_ID>

# 3. enable on-behalf-of-user auth so Genie respects each user's permissions
databricks apps update <APP_NAME> --json '{"user_api_scopes":["sql","dashboards.genie"]}'

Then deploy as usual (databricks apps deploy …). The button appears — no code changes to your app.

genie-overlay wrap reads your existing start command and rewrites it to run behind the overlay, moving your app to an internal port and giving the overlay the public one. It detects Streamlit / Dash / Gradio / FastAPI / Flask and sets the right port automatically.

Prefer to wrap app.yaml by hand?
command:
  - python
  - -m
  - genie_overlay
  - run
  - --genie-space
  - "<YOUR_GENIE_SPACE_ID>"
  - --upstream-port
  - "8080"
  - --                       # everything after this is YOUR app's command
  - streamlit
  - run
  - app.py

The proxy listens on DATABRICKS_APP_PORT and forwards to your app on --upstream-port. It also sets PORT / STREAMLIT_SERVER_PORT / GRADIO_SERVER_PORT for the child so auto-detecting frameworks bind the internal port instead of fighting the proxy for the public one.

No internet at build time? Vendor it instead.

Copy the genie_overlay/ folder next to your app and add uvicorn, httpx, websockets, databricks-sdk, pyyaml to requirements.txt. Everything else is identical.

Built to not break your app

Adding an overlay should never risk your app. This one is defensive by design:

  • App-first fallback — if the overlay fails to start for any reason, the launcher runs your app directly on the public port instead. Worst case: no overlay, but your app is untouched.
  • The injected script can't throw into your page — all overlay JS runs in a try/catch and lives in a Shadow DOM, isolated from your app's DOM and CSS.
  • CSP-safe — the proxy strips Content-Security-Policy from injected HTML and injects a single same-origin script, so strict app policies don't block it.
  • Genie failures are contained — a bad space id or a Genie error surfaces in the chat panel; your app keeps working.

Attaching underlying data (optional)

Pick-an-element always captures an element's visible text. To also send the data behind a chart or KPI, expose it in one of three ways:

  • HTML attributes — add data-genie-context='{"revenue": 1200}' and data-genie-label="Q3 Revenue" to any element.
  • JS hookwindow.genie.setContext(element, { ...data }).
  • Selector registrywindow.genie.register(".my-card", el => ({...})).

When a user picks an element, the overlay walks up the DOM to find the nearest element carrying context and sends it with the question. See the demo apps in examples/ for working patterns in Streamlit, Dash, and Gradio.

Local development

pip install -e .
# run the overlay in front of any local app:
DATABRICKS_CONFIG_PROFILE=<profile> DATABRICKS_APP_PORT=8700 \
  python -m genie_overlay run --genie-space <id> --upstream-port 8501 -- \
  streamlit run examples/streamlit_retail/app.py --server.port 8501
# open http://localhost:8700

How it works (internals)

Piece File Role
Reverse proxy genie_overlay/proxy.py Raw ASGI app: forwards HTTP + WebSockets, injects the overlay into HTML, serves /_genie/*.
Genie client genie_overlay/genie.py Wraps the Genie Conversation API → text, SQL, and result rows.
Auth genie_overlay/auth.py OBO via X-Forwarded-Access-Token, service-principal fallback.
Launcher genie_overlay/cli.py Starts your app, waits for it, then serves the proxy.
Overlay UI genie_overlay/assets/overlay.js Shadow-DOM button, element picker, chat panel.

Limitations

  • The launcher is Python, so the wrapped app runs in a Python app runtime. Node/JS apps would need Node available in that runtime too.
  • Compressed upstream responses are requested uncompressed so HTML can be rewritten; large non-HTML responses stream through untouched.

License

Apache-2.0

About

Embeddable Ask Genie overlay for any Databricks App — a framework-agnostic reverse proxy that adds a floating Genie button with in-frame context capture.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages