Skip to main content

Jupyter Notebook Application Builder

Project description

PyPI Version Anaconda-Server Badge Tests Tests

Coverage badge2

Introduction

nbappinator streamlines Jupyter and Voila app development through a structured, opinionated framework for UI construction. Adding a button to a tab is as simple as app.tab(0).button("Run", on_click=callback).

nbappinator has three goals:

  • Simplify UI development for Notebook developers by reducing the surface area of APIs to learn.
  • Abstract the underlying UI components, allowing nbappinator to plug in different frameworks to achieve equivalent behavior.
  • Provide a foundation to develop reusable and portable themes to improve app styling.

Example

Getting Started

import nbappinator as nb

def my_action(app):
    with app.messages:
        print("This message will be written to the Messages footer")
        app.tab(0).label("This is some text")

def choose_action(app):
    with app.messages:
        chosen_value = app["choose1"]
        print(f"You chose {chosen_value}")
        app.tab(1).label(f"You chose {chosen_value}")

# Create a Tabbed UI comprised of three sections:
# "Config" Header, Tabbed Pages: "First Tab" and "Second Tab", and a "Messages" Footer
myapp = nb.App(tabs=["First Tab", "Second Tab"], footer="Messages", header="Config")
myapp.config.label("This is static text in the Config section. Add global settings, buttons and other widgets here.")

# Add a button to First Tab
myapp.tab(0).label("This is the first tab")
myapp.tab(0).button("but1", on_click=my_action, label="Some button")
myapp.tab(0).label("Click the button")

# Add a dropdown selection to Second Tab
myapp.tab(1).select("choose1", options=list(range(10)), on_change=choose_action, label="Choose A Number")

# Render the app:
myapp.display()

API Overview

Creating an App

app = nb.App(
    tabs=["Tab 1", "Tab 2"],  # Required: list of tab names
    header="Config",          # Optional: collapsible header section
    footer="Messages",        # Optional: collapsible footer (default)
    title="My App",           # Optional: browser title
)

Accessing Sections

app.config           # Header section (if configured)
app.tab(0)           # Tab by index
app.tab("Tab 1")     # Tab by name
app.footer           # Footer section
app.messages         # Output widget in footer for print statements

Input Widgets

All input widgets return the page for method chaining.

page.select("name", options=["a", "b"], default="a", on_change=callback)
page.combobox("name", options=["a", "b"])           # Select with text input
page.slider("name", min_val=0, max_val=100, default=50)
page.radio("name", options=["a", "b"], horizontal=True)
page.text("name", default="", multiline=False)
page.checkbox("name", default=False)
page.button("name", on_click=callback, status=True)  # status=True adds progress indicator

Display Widgets

page.label("Static text")
page.pre("Preformatted text")
page.html("<b>HTML content</b>")
page.separator(color="gray")
page.output("name")                # Output area for print statements

Data and Charts

page.dataframe("name", df, on_click=callback)
page.dataframe("name", df, tree=True, tree_column="path", enterprise=True)  # Tree requires enterprise
page.plotly(fig)
page.matplotlib(fig)
page.networkx(graph, layout="force")   # D3 force-directed graph
page.tree("name", paths=["a~b~c"], delimiter="~")  # D3 collapsible tree

Standalone AG Grid

Use create_grid() to create an AG Grid without the App wrapper:

from nbappinator import create_grid, get_column_defs, apply_format, FORMAT_MAG_SI, FORMAT_PERCENT

# Generate column definitions from DataFrame
columns = get_column_defs(df)

# Override
columns[0]["pinned"] = "left"

# Apply built-in formatters (MAG_SI for K/M/B, PERCENT for %)
apply_format(columns[1], FORMAT_MAG_SI, precision=1)   # 1500000 -> "1.5M"
apply_format(columns[2], FORMAT_PERCENT, precision=2)  # 0.05 -> "5.00%"

# Or use custom JS formatters
columns[3]["valueFormatter"] = "params => '$' + params.value.toFixed(2)"

grid = create_grid(
    df,
    column_defs=columns,
    height=400,
    enterprise=False,             # Set True for enterprise features
    license_key="",               # Your AG Grid license key
)
grid

Layout

row = page.row()       # Horizontal container
row.button(...)
col = page.column()    # Vertical container

Callbacks

Callbacks receive the app as their only argument:

def my_callback(app):
    value = app["widget_name"]       # Get widget value
    app["widget_name"] = new_value   # Set widget value
    app.status("Working...")         # Update button status
    app.done("Complete")             # Mark button as done

Button with Status

app.config.button("Run", on_click=run_task, status=True)

def run_task(app):
    app.status("Loading data...")
    # ... do work ...
    app.status("Processing...")
    # ... more work ...
    app.done("Complete")

Examples

Interactive notebooks demonstrating nbappinator features are available in the notebooks/ directory:

Feature Example
Getting Started 1_readme_example.ipynb
Plotly Charts 3_charts_plotly.ipynb
Matplotlib 3_charts_matplotlib.ipynb
D3 Network Graphs 4_networkx_graph.ipynb
Graphviz Graphs 5_graphviz_graph.ipynb
D3 Tree Widget 6_tree_app.ipynb
AG Grid (Community) 7_grid_anywidget.ipynb
AG Grid (Enterprise) 8_aggrid_enterprise.ipynb
Default Grid Renderer 9_default_grid_renderer.ipynb

Deployment and BQuant

nbappinator was originally designed to simplify developing applications within Bloomberg's BQuant environment, which provides a managed but locked down Jupyter environment with a Voila-based deployment of applications.

Acknowledgements

nbappinator builds on some great projects that provide useful building blocks in Jupyter, which themselves build on other great web technologies. At the same time, nbappinator is implementation agnostic - a core goal is to allow any of these components to be swapped out.

Vue.js The Progressive JavaScript Framework

AG Grid is an excellent javascript grid library. nbappinator loads AG Grid via CDN using anywidget, supporting both Community and Enterprise editions.

Plotly is given first class support, although any matplotlib charting library works, such as Seaborn.

D3.js powers the interactive NetworkX graph visualizations and collapsible tree widgets.

This all builds on Jupyter and ipywidgets.

External CDN Dependencies

At runtime, nbappinator loads the following JavaScript libraries from CDN:

  • AG Grid Community/Enterprise from cdn.jsdelivr.net
  • D3.js from cdn.jsdelivr.net
  • Graphviz WASM from cdn.jsdelivr.net (for tree visualizations)

This means an internet connection is required when first rendering widgets that use these libraries. Bundling these dependencies locally for offline/air-gapped use is technically feasible but not yet implemented.

Testing Notes

A significant portion of the tests are Notebook smoketests designed to exercise the code base in its entirety. The coverage report primarily reflects the percentage of the code base that the Notebooks exercise: but manual verification of the Notebook behavior is still required.

Some assertions are baked into the Notebooks, but largely its intended to ensure that all the features are exercised.

Project details


Download files

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

Source Distribution

nbappinator-0.3.0.tar.gz (40.0 kB view details)

Uploaded Source

Built Distribution

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

nbappinator-0.3.0-py3-none-any.whl (50.6 kB view details)

Uploaded Python 3

File details

Details for the file nbappinator-0.3.0.tar.gz.

File metadata

  • Download URL: nbappinator-0.3.0.tar.gz
  • Upload date:
  • Size: 40.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nbappinator-0.3.0.tar.gz
Algorithm Hash digest
SHA256 9923534790b07d68c6d2c78e86ec3613ccd3f193dd5dc5cb975051d1504c3917
MD5 9f51761234db9a6759f4e746e593e5a5
BLAKE2b-256 75b62e10c70d5953a50a73b6ae495622b8b93d5e2118c0ffe5d4f0c345be97cc

See more details on using hashes here.

Provenance

The following attestation bundles were made for nbappinator-0.3.0.tar.gz:

Publisher: build_release.yml on iqmo-org/nbappinator

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nbappinator-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: nbappinator-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 50.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nbappinator-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9c4732fa7d1907d9125edf58859d2947d6bf84e8febb4584852ac1707d13d260
MD5 384bf11a781bdc34c826707bf52a0654
BLAKE2b-256 bccd0acdb9a9ba62f068f8515ebb7dd97bb4252d866a759535333e3d4bef6f11

See more details on using hashes here.

Provenance

The following attestation bundles were made for nbappinator-0.3.0-py3-none-any.whl:

Publisher: build_release.yml on iqmo-org/nbappinator

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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