FireFly Analytics LogoFireFly Analytics
Solutions

Notebook Editor

Interactive Python notebook editing powered by Marimo, embedded directly within your platform. Users can create cells, execute code, and view rich outputs without leaving your application.

Overview

The Notebook Editor provides a full-featured interactive notebook experience by embedding the Marimo notebook application. Marimo is deployed as a Databricks Lakehouse App and accessed through a secure proxy that handles authentication transparently.

This approach allows you to provide notebook functionality to users who authenticate via your application's SSO (Okta, Azure AD, etc.) without exposing Databricks login screens. All API calls use SSO-Mapped Service Principal credentials.

Key Benefits

  • Full notebook functionality without Databricks SSO exposure
  • Reactive Python notebooks with automatic dependency tracking
  • Rich outputs including tables, charts, and interactive widgets
  • Seamless integration with your application's authentication
  • Access to Databricks compute and data resources

How It Works

The Notebook Editor uses an iframe-based architecture with a Go reverse proxy. When a user navigates to the notebook editor, the server fetches their SPN token, encrypts it, and generates a proxy URL. The browser loads the Marimo app through this proxy, which decrypts the token and authenticates requests.

Architecture

Request Flow

  1. User navigates to the notebook editor page in your application
  2. Server-side component fetches the user's SPN credentials from the database and exchanges them for a Databricks workspace token
  3. Token is encrypted using AES-256-GCM and embedded in a proxy URL
  4. Browser renders iframe pointing to the Go proxy with the encrypted token
  5. Go proxy decrypts the token and forwards requests to the Marimo Lakehouse App with proper authentication
  6. WebSocket connections are established for real-time cell execution and output streaming

User Experience

The Notebook Editor provides a modern, reactive notebook interface that feels native to your application.

Features

  • Interactive Python cells with syntax highlighting and autocomplete
  • Reactive execution - cells automatically re-run when dependencies change
  • Rich outputs including DataFrames, Matplotlib/Plotly charts, and HTML
  • Cell execution with real-time output streaming
  • File browser for notebook management
  • Variable explorer and debugging tools
  • Markdown cells for documentation
  • Support for Databricks-specific features like Delta tables and MLflow

Why Marimo?

Marimo offers several advantages over traditional Jupyter notebooks:

Reactive Execution

When you modify a cell, all dependent cells automatically re-execute. No more "run all cells" confusion.

Pure Python

Notebooks are stored as executable Python files, not JSON. Easy to version control and review.

Interactive Widgets

Built-in support for sliders, dropdowns, and other UI elements that reactively update the notebook.

Deterministic State

No hidden state or execution order issues. The notebook state is always consistent with the code.

Backend Configuration

The Notebook Editor component is implemented as a server-side rendered React component that handles token acquisition and proxy URL generation.

Component Implementation

// src/components/sso-spn-notebook-editor-iframe.tsx
import { redirect } from "next/navigation";
import { getDatabricksWorkspaceToken } from "@/lib/databricks-workspace-token";
import { generateProxyUrl } from "@/lib/token-encryption";

export default async function NotebookEditorIframe() {
  // Fetch workspace token using SPN credentials
  const tokenResult = await getDatabricksWorkspaceToken();

  if (!tokenResult.success) {
    redirect("/sso-spn"); // Redirect to re-authenticate
  }

  const { accessToken } = tokenResult.data;

  // Configuration from environment
  const appUrl = process.env.DATABRICKS_NOTEBOOK_APP_URL;
  const proxyBaseUrl = process.env.NEXT_PUBLIC_PROXY_URL;

  // Generate encrypted proxy URL
  const proxyPath = generateProxyUrl(accessToken, appUrl, "/");
  const fullProxyUrl = `${proxyBaseUrl}${proxyPath}`;

  return (
    <div className="h-full flex flex-col">
      <iframe
        src={fullProxyUrl}
        className="w-full h-full border-0"
        title="Notebook Editor"
        sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-downloads"
        allow="clipboard-write; clipboard-read"
      />
    </div>
  );
}

Environment Variables

VariableDescriptionExample
DATABRICKS_NOTEBOOK_APP_URLURL of the Marimo Lakehouse Apphttps://marimo-notebook-shared-xxx.aws.databricksapps.com
NEXT_PUBLIC_PROXY_URLBase URL of the Go proxy serverhttps://app-proxy.your-domain.com
ENCRYPTION_KEYAES-256 encryption key (64 hex chars)Generated via openssl rand -hex 32

Lakehouse App Setup

To use the Notebook Editor, you need to deploy a Marimo Lakehouse App in your Databricks workspace. This is a one-time setup:

  1. Create a Lakehouse App in your Databricks workspace with Marimo as the application
  2. Configure permissions to allow the Service Principal to access the app
  3. Note the app URL and set it as DATABRICKS_NOTEBOOK_APP_URL
  4. Deploy the Go proxy with the same encryption key as your Next.js application

Security Note

The Go proxy and Next.js application must share the same ENCRYPTION_KEY. Store this key securely and rotate it periodically. See the Embedding Apps documentation for proxy deployment details.

Enhancement Opportunities

The Notebook Editor can be extended with additional features to provide a more integrated experience.

postMessage Integration

Enable parent-iframe communication to trigger cell execution, inject variables, or extract outputs programmatically from your application.

Theme Synchronization

Sync dark/light mode and color themes between your application and the embedded notebook for a seamless visual experience.

Notebook Templates

Pre-populate notebooks with starter code, common imports, or organization-specific utilities for consistent starting points.

Execution Callbacks

Receive events when cells complete execution for analytics, logging, or triggering downstream workflows in your application.