Skip to main contentSkip to footer
ExamplenotebookbeginnerRunnablenotebook-to-app

Tutorial: Notebook to Web App in Five Minutes

This notebook shows how to turn a small Python function into a shareable interface with Gradio or Streamlit. It focuses on one clear input -> processing -> output flow so the app wrapper stays explicit and easy to review.

Key Facts

Level
beginner
Runtime
Notebook • Streamlit / Gradio
Pattern
Notebook to shareable application
Interaction
Runnable sandbox • Notebook
Updated
21 March 2026

Navigate this example

High-level flow

How this example moves from input to execution and reviewable output
Tutorial: Notebook to Web App… -> User request -> System execution -> Reviewable output -> Design for delegation rather… -> Apply progressive disclosure to…

Trigger

Tutorial: Notebook to Web App…

Runtime

User request

Outcome

System execution

Why this page exists

This example is shown as both real source code and a product-facing interaction pattern so learners can connect implementation, UX, and doctrine without leaving the library.

Visual flowReal sourceSandbox or walkthroughMCP access
How should this example be used in the platform?

Use the sandbox to understand the experience pattern first, then inspect the source to see how the product boundary, model boundary, and doctrine boundary are actually implemented.

UX pattern: Notebook to shareable application
Design for delegation rather than direct manipulation
Apply progressive disclosure to system agency
Establish trust through inspectability
Source references
Library entry
frameworks-notebooks-1-introduction-1-notebook-to-web-app
Source path
content/example-library/sources/frameworks/notebooks/1-introduction/1-notebook-to-web-app.ipynb
Libraries
gradio, streamlit
Runtime requirements
streamlit, gradio
Related principles
Design for delegation rather than direct manipulation, Apply progressive disclosure to system agency, Establish trust through inspectability, Represent delegated work as a system, not merely as a conversation

1-notebook-to-web-app.ipynb

json
{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Tutorial: Notebook to Web App in Five Minutes\n",
        "\n",
        "This notebook shows how to turn a small Python function into a shareable interface with Gradio or Streamlit. It focuses on one clear input -> processing -> output flow so the app wrapper stays explicit and easy to review.\n",
        "\n",
        "**Audience**\n",
        "- Data scientists and AI builders who prototype in notebooks first.\n",
        "\n",
        "**Prerequisites**\n",
        "- Basic Python functions\n",
        "- Jupyter notebooks\n",
        "- Optional: `gradio` or `streamlit` installed locally\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Outline\n",
        "\n",
        "1. Start with one clear function\n",
        "2. Make the input and output contract explicit\n",
        "3. Wrap the function with Gradio\n",
        "4. Wrap the same function with Streamlit\n",
        "5. Decide when this should stay staged instead of fully productized\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "from __future__ import annotations\n",
        "\n",
        "def predict_sentiment(text: str) -> str:\n",
        "    lowered = text.lower()\n",
        "    if \"good\" in lowered:\n",
        "        return \"Positive\"\n",
        "    if \"bad\" in lowered:\n",
        "        return \"Negative\"\n",
        "    return \"Neutral\"\n",
        "\n",
        "samples = [\n",
        "    \"The launch looked good and the team felt calm.\",\n",
        "    \"The handoff went bad after the last deployment.\",\n",
        "    \"We need one more review before deciding.\",\n",
        "]\n",
        "\n",
        "[(sample, predict_sentiment(sample)) for sample in samples]\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Step 1 - Keep the notebook logic narrow\n",
        "\n",
        "The function above is the real asset. If the notebook cannot point to one bounded function, the app wrapper usually becomes messy too.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "app_contract = {\n",
        "    \"input\": \"One sentence from the user\",\n",
        "    \"processing\": \"Run predict_sentiment(text)\",\n",
        "    \"output\": \"A single label: Positive, Negative, or Neutral\",\n",
        "}\n",
        "\n",
        "app_contract\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Step 2 - Gradio wrapper\n",
        "\n",
        "Gradio is a fast choice when you want a lightweight demo or model surface.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "import gradio as gr\n",
        "\n",
        "gradio_snippet = \"\"\"\n",
        "demo = gr.Interface(\n",
        "    fn=predict_sentiment,\n",
        "    inputs=gr.Textbox(label=\"Enter your sentence\"),\n",
        "    outputs=gr.Label(),\n",
        ")\n",
        "demo.launch()\n",
        "\"\"\"\n",
        "\n",
        "print(gradio_snippet)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Step 3 - Streamlit wrapper\n",
        "\n",
        "Streamlit is useful when the notebook is becoming more dashboard-like and you need a little more layout structure.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "import streamlit as st\n",
        "\n",
        "streamlit_snippet = \"\"\"\n",
        "st.title(\"Sentiment Predictor\")\n",
        "text = st.text_input(\"Enter your sentence\")\n",
        "if text:\n",
        "    st.write(predict_sentiment(text))\n",
        "\"\"\"\n",
        "\n",
        "print(streamlit_snippet)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Step 4 - Review the execution path\n",
        "\n",
        "This example is staged executable rather than a full in-product runtime. The key review questions are:\n",
        "\n",
        "- Is the notebook function clean enough to expose directly?\n",
        "- Are the user input and output labels explicit?\n",
        "- Does the team need a quick demo surface or a more durable product wrapper?\n",
        "- Is it acceptable to stay at notebook-plus-wrapper stage for now?\n"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "name": "python",
      "version": "3.12"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}
What should the learner inspect in the code?

Look for the exact place where system scope is bounded: schema definitions, prompt framing, runtime configuration, and the call site that turns user intent into a concrete model or workflow action.

Look for output contracts and validation
Look for the exact execution call
Look for what the product could expose to the user
How does the sandbox relate to the source?

The sandbox should make the UX legible: what the user sees, what the system is deciding, and how the result becomes reviewable. The source then shows how that behavior is actually implemented.

Describe the function or notebook flow you want to expose.
Choose the framework that best fits the interaction pattern.
Review the input/output contract and launch block for the app wrapper.
SandboxNotebook to shareable application
Notebook-to-app lab

This sandbox turns a notebook workflow into a shareable interface by making inputs, outputs, and the recommended UI framework explicit.

UX explanation

A notebook becomes a product surface when input, processing, and output are made explicit for another person, without forcing the team into a full custom frontend.

AI design explanation

The example teaches how to isolate a clear Python function, choose a UI wrapper like Gradio or Streamlit, and keep the notebook logic reusable.

Interaction walkthrough

  1. 1Describe the function or notebook flow you want to expose.
  2. 2Choose the framework that best fits the interaction pattern.
  3. 3Review the input/output contract and launch block for the app wrapper.

Notebook description

GradioStreamlit

App contract

The input/output contract appears here.

Launch snippet

The starter app wrapper appears here.

Used in courses and paths

This example currently stands on its own in the library, but it still connects to the principle system and the broader example family.

Related principles

Runtime architecture

Use this example in your agents

This example is also available through the blueprint’s agent-ready layer. Use the For agents page for the public MCP, deterministic exports, and Claude/Cursor setup.

Define triggers, context, and boundaries before increasing autonomy
Make control, observability, and recovery explicit in the runtime
Choose the right operational patterns before delegating to workflows