Jupyter Integration

Run and monitor Jupyter notebook servers directly from Stanza’s CLI. The integration provides persistent server management, real-time notebook monitoring, and automatic cell output logging - all designed to streamline interactive development workflows.

Stanza Jupyter Integration Demo
Attaching to a Jupyter notebook kernel for real-time monitoring and control.

Quick Start

Installation Requirements

Jupyter integration requires additional dependencies:

$pip install "cq-stanza[notebook]"

This installs:

  • jupyter_server for server management
  • jupyter_core for runtime discovery
  • Required dependencies for log streaming and monitoring

Start a Jupyter server in your project directory:

$# Start server on default port 8888
>stanza jupyter start
>
># Start in specific directory with custom port
>stanza jupyter start /path/to/notebooks --port 8889
>
># Check server status
>stanza jupyter status
>
># Open Jupyter in browser
>stanza jupyter open

The server runs in the background and persists across terminal sessions, making it ideal for long-running experiments on remote machines.

Server Management

Starting the Server

Launch a persistent Jupyter server that survives terminal closure:

1from stanza.jupyter import start
2from pathlib import Path
3
4# Start server programmatically
5state = start(notebook_dir=Path.cwd(), port=8888)
6print(f"Server running at: {state['url']}")
7print(f"PID: {state['pid']}")

Or via CLI:

$stanza jupyter start

The server automatically configures:

  • Auto-logging of cell outputs to notebook_name.log files
  • Authentication tokens for secure access
  • Background process management with graceful shutdown

Checking Status

Get server information including uptime and URL:

1from stanza.jupyter import status
2
3server_status = status()
4if server_status:
5 print(f"PID: {server_status['pid']}")
6 print(f"URL: {server_status['url']}")
7 print(f"Uptime: {server_status['uptime_seconds']:.0f}s")
8 print(f"Root: {server_status['root_dir']}")
9else:
10 print("No server running")

Via CLI:

$stanza jupyter status

Stopping the Server

Gracefully shutdown using escalating strategies (REST API CMDSIGTERMSIGKILL):

1from stanza.jupyter import stop
2
3stop()

Via CLI:

$stanza jupyter stop

Notebook Monitoring

Listing Active Sessions

View all running notebook kernels with their log file metadata:

1from stanza.jupyter import list_sessions
2
3sessions = list_sessions()
4for session in sessions:
5 print(f"Notebook: {session['notebook_path']}")
6 print(f"Log: {session['log_path']}")
7 print(f"Lines: {session['line_count']}")

Via CLI:

$stanza jupyter list

Viewing Logs

Monitor notebook output in real-time without interrupting execution:

$# List all notebook logs
>stanza jupyter logs
>
># Tail a specific notebook's output (Ctrl+C to detach)
>stanza jupyter logs my_notebook.ipynb
>
># Show last 20 lines of context
>stanza jupyter logs my_notebook.ipynb -n 20

The logs command is useful for monitoring long-running experiments while preserving the ability to detach without affecting the notebook kernel.

Attaching to Notebooks

Connect directly to a notebook kernel with interactive control:

$# Attach with kernel control (Ctrl+C kills kernel, ESC exits)
>stanza jupyter attach my_notebook.ipynb
>
># Show more initial context
>stanza jupyter attach my_notebook.ipynb -n 30

When attached:

  • Ctrl+C: Kills the notebook kernel and exits
  • ESC (twice): Exits without killing the kernel
  • Output streams in real-time directly to your terminal

This mode is ideal for active development and debugging when you need full control over kernel lifecycle.

Python API Examples

Complete Server Workflow

1from pathlib import Path
2from stanza.jupyter import start, status, list_sessions, stop
3
4# Start server
5notebook_dir = Path("./experiments")
6state = start(notebook_dir=notebook_dir, port=8888)
7print(f"Started: {state['url']}")
8
9# Check status
10server_status = status()
11print(f"Uptime: {server_status['uptime_seconds']:.0f}s")
12
13# List running notebooks
14sessions = list_sessions()
15print(f"Active notebooks: {len(sessions)}")
16
17# Cleanup
18stop()

Programmatic Log Streaming

1from pathlib import Path
2from stanza.jupyter import log_stream
3
4# Follow a notebook's log file
5log_file = Path("./experiments/analysis.log")
6log_stream.follow(log_file, lines=10)

Kernel Management

1from stanza.jupyter import kill_kernel
2
3# Stop a specific notebook's kernel
4kill_kernel("analysis.ipynb")

Auto-Logging

When you start the Jupyter server through Stanza, cell outputs are automatically logged to {notebook_name}.log files in the same directory as each notebook. This enables:

  • Persistent record of all cell executions
  • Real-time monitoring via stanza jupyter logs
  • Post-experiment analysis without re-running cells

Log files capture stdout, stderr, and display outputs, providing a complete record of your notebook’s execution history.

Remote Development

For SSH sessions to lab computers, use port forwarding to access Jupyter in your local browser:

$# On your local machine
>ssh -L 8888:localhost:8888 user@lab-computer
>
># On the remote machine
>stanza jupyter start
>stanza jupyter status # Copy the URL
>
># Open the URL in your local browser

The persistent server ensures your notebooks keep running even if your SSH connection drops.

Tips and Best Practices

Background execution: The server runs as a detached process, so you can close your terminal without stopping Jupyter. Use stanza jupyter status to rediscover the URL after reconnecting.

Monitor long experiments: Use stanza jupyter logs to check progress on multi-hour measurements without opening the browser or disrupting execution.

Clean shutdown: Always use stanza jupyter stop to gracefully shutdown the server. This ensures proper cleanup of runtime files and state.

Port conflicts: If port 8888 is already in use, specify a different port with --port 8889 when starting the server.

Next Steps