Skip to main content

Programmatic Jupyter cell execution with persistent kernels

Project description

jupyter-cli

Programmatic Jupyter notebook cell execution with persistent kernels.

The Problem

Existing Jupyter tools don't support selective cell execution with persistent state:

  • papermill/nbconvert/nbexec: Run entire notebooks
  • jupyter console: Requires manual interaction
  • nbclient: Kernel dies when Python process exits

jupyter-cli fills this gap: execute specific cells while keeping kernel state alive between CLI invocations.

Use Case

A data science notebook with ~60 cells:

  • Cells 1-49: Expensive setup (DB queries, model training) - takes ~20 minutes
  • Cells 50+: Experimental iterations

With jupyter-cli:

jupyter-cli start notebook.ipynb
jupyter-cli exec notebook.ipynb 0 1 2 ... 49  # Run setup once
jupyter-cli exec notebook.ipynb 50            # Iterate on cell 50
jupyter-cli exec notebook.ipynb 50            # Again, without re-running setup
jupyter-cli stop notebook.ipynb

Installation

pip install jupyter-cli

# Or from source
git clone <repo>
cd jupyter-cli
pip install -e .

Requirements:

  • Python 3.8+
  • jupyter_client
  • nbformat
  • click

Quick Start

# Start a persistent kernel
jupyter-cli start notebook.ipynb

# Execute cells (0-indexed)
jupyter-cli exec notebook.ipynb 0 1 2

# Stop the kernel
jupyter-cli stop notebook.ipynb

Commands

Kernel Management

Command Description
start <notebook> Start persistent kernel
stop <notebook> Stop kernel
stop --all Stop all kernels
status [notebook] Check kernel status

Cell Execution

Command Description
exec <notebook> <cells...> Execute specific cells
exec <notebook> 0 1 2 --timeout 300 With custom timeout
exec <notebook> 0 --quiet Suppress output

Notebook Exploration

Command Description
list <notebook> List all cells with preview
list <notebook> --code Only code cells
list <notebook> --range 0-10 Cell range
read <notebook> 0 1 2 Read full cell source
read <notebook> --code Read all code cells
search <notebook> "pattern" Search cells
search <notebook> "regex" -r Regex search
outputs <notebook> 5 Read stored outputs
info <notebook> Notebook info

Examples

Exploring a Notebook

# Quick overview
$ jupyter-cli list notebook.ipynb
[0] code: import pandas as pd
[1] code: df = pd.read_csv('data.csv')
[2] code: df.head()
[3] markdown: ## Data Cleaning
[4] code: df = df.dropna()
...

# Find all cells using DataFrame
$ jupyter-cli search notebook.ipynb "DataFrame"
Found 3 match(es):
[5] code: df = pd.DataFrame(data)
[12] code: result = DataFrame.from_dict(...)
[45] code: final_df = pd.DataFrame(results)

# Read specific cells
$ jupyter-cli read notebook.ipynb 5 12
=== Cell 5 (code) ===
df = pd.DataFrame(data)
print(df.shape)

=== Cell 12 (code) ===
result = DataFrame.from_dict(processed_data)

Selective Execution

# Start kernel
$ jupyter-cli start analysis.ipynb
Kernel started. ID: abc123

# Run expensive setup
$ jupyter-cli exec analysis.ipynb 0 1 2 3 4 5
[Cell 0] Executing: import pandas as pd...
[Cell 1] Executing: df = load_data()...
Loading 1M rows from database...
...

# Iterate on experiment cell
$ jupyter-cli exec analysis.ipynb 50
[Cell 50] Executing: model.fit(X, y)...
Accuracy: 0.85

# Edit cell 50 in your editor, then re-run
$ jupyter-cli exec analysis.ipynb 50
[Cell 50] Executing: model.fit(X, y, epochs=100)...
Accuracy: 0.92

# Clean up
$ jupyter-cli stop analysis.ipynb
Kernel stopped.

Reading Previous Outputs

$ jupyter-cli outputs notebook.ipynb --range 10-15
=== Cell 10 output ===
[stdout] Training model...
[stdout] Epoch 1/10: loss=0.5

=== Cell 12 output ===
[result] 0.923456

=== Cell 14 output ===
[error] ValueError: invalid shape

Gap Analysis: CLI vs Manual Jupyter

Feature jupyter-cli Manual Jupyter UI
Cell execution Yes Yes
Persistent kernel Yes Yes
Execute specific cells Yes Yes
State persistence Yes Yes
stdout/stderr output Yes Yes
Rich output (HTML) Truncated Full rendering
Image output [Image: PNG] Displayed
Interactive widgets No Yes
Cell editing No (use external editor) Yes
Magic commands Yes (via kernel) Yes
Auto-complete No Yes
Inline plots No (shows placeholder) Yes
Syntax highlighting No Yes
Variable inspector No Extension available
Debugging No Yes
Multiple kernels Yes (one per notebook) Yes

Key takeaway: jupyter-cli is for programmatic automation, not interactive development. Use it when you need:

  • Scripted notebook execution
  • LLM agent integration
  • CI/CD pipelines
  • Selective cell re-execution without re-running setup

Architecture

┌─────────────┐     ┌──────────────────┐     ┌────────────┐
│  CLI Client │────▶│  Daemon Process  │────▶│   Kernel   │
└─────────────┘     └──────────────────┘     └────────────┘
      │                     │                       │
      │  connection.json    │  keeps alive          │  Python
      │◀────────────────────│                       │  process
      │                     │                       │
      └─────────────────────┴───────────────────────┘
  1. Daemon Process: Starts kernel, keeps it alive, writes connection file
  2. CLI Client: Reads notebook, connects to kernel via connection file, executes cells

For LLM Agents

See CLAUDE.md for a comprehensive guide on using jupyter-cli with LLM agents, including:

  • Token-efficient exploration strategies
  • Common workflows
  • Best practices

Development

# Install with dev dependencies
pip install -e ".[dev]"

# Run tests
pytest tests/ -v

# Run specific test class
pytest tests/test_jupyter_cli.py::TestCLIExec -v

License

MIT

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

jupyter_cli-0.1.0.tar.gz (17.7 kB view details)

Uploaded Source

Built Distribution

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

jupyter_cli-0.1.0-py3-none-any.whl (18.6 kB view details)

Uploaded Python 3

File details

Details for the file jupyter_cli-0.1.0.tar.gz.

File metadata

  • Download URL: jupyter_cli-0.1.0.tar.gz
  • Upload date:
  • Size: 17.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.11

File hashes

Hashes for jupyter_cli-0.1.0.tar.gz
Algorithm Hash digest
SHA256 be7e422c40c4d981804ccc06bdc2c6576f4859599b37137ca590dec221707fff
MD5 7c2fc6bb97539f506a60f733806745a8
BLAKE2b-256 fad8d9e92c40bed7307058d5990f3c4e0a1126e68760bd63b43507cd437ff1e1

See more details on using hashes here.

File details

Details for the file jupyter_cli-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: jupyter_cli-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 18.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.11

File hashes

Hashes for jupyter_cli-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f64bd00473cb86102baf237367c7d195c277c590f108e6c40ce6157ab38b334c
MD5 893f55d430686af54e31bd9d38db0f41
BLAKE2b-256 657db1ec25f3847563c0e03599e7daa78b6d52af43692199661a96ab57983d43

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 Pingdom Monitoring Sentry Error logging StatusPage Status page