nbclient

raw JSON →
0.10.4 verified Tue May 12 auth: no python install: verified quickstart: stale

nbclient is a client library for programmatically executing Jupyter notebooks. It was originally spun out of `nbconvert`'s `ExecutePreprocessor` to allow for independent development and easier integration into other tools. It currently supports Python 3.10+ and releases minor versions frequently, typically every few weeks to months.

pip install nbclient
error ModuleNotFoundError: No module named 'nbformat'
cause The 'nbformat' package (a dependency of nbclient) is not installed in the Python environment being used, or there's a mismatch between the installed environment and where nbclient is trying to run.
fix
Ensure 'nbformat' and 'nbclient' are installed in the active Python environment by running pip install nbformat nbclient or conda install nbformat nbclient.
error nbclient.exceptions.CellExecutionError: An error occurred while executing the following cell:
cause A cell within the executed Jupyter notebook encountered an unhandled exception during its execution. By default, nbclient stops notebook execution and raises this error.
fix
Inspect the notebook's saved output or the detailed traceback provided by the error message to debug the specific code in the failing cell. To allow the notebook to continue executing even after an error, initialize NotebookClient with allow_errors=True.
error nbclient.exceptions.CellTimeoutError: A cell timed out while it was being executed, after X seconds.
cause A specific cell in the notebook exceeded the maximum allowed execution time, which defaults to 30 seconds.
fix
Increase the timeout parameter when initializing NotebookClient (e.g., NotebookClient(nb, timeout=600) for 10 minutes), or set timeout=None or timeout=-1 to disable the timeout for all cells.
error RuntimeError: Kernel died before replying to kernel_info
cause The Jupyter kernel responsible for executing the notebook's code unexpectedly terminated or became unresponsive during startup or execution. This can be caused by resource exhaustion (e.g., memory), unhandled kernel crashes, or issues with the kernel itself.
fix
Check for sufficient system resources (RAM, CPU) if running locally, or increase allocated compute resources if on a cloud platform like Kaggle. Review the notebook's code for operations that might consume excessive resources. Ensure jupyter_client and other Jupyter-related packages are up to date.
breaking nbclient has incrementally dropped support for older Python versions. Version 0.10.2 dropped Python 3.8 support, and 0.10.3 dropped Python 3.9 support. Users on these Python versions must upgrade their Python environment to 3.10+ or use an older `nbclient` version.
fix Upgrade your Python environment to 3.10 or newer, or pin `nbclient` to a compatible older version (e.g., `<0.10.2` for Python 3.9, `<0.10.0` for Python 3.8).
breaking nbclient was extracted from `nbconvert`'s `ExecutePreprocessor`. Code that previously imported `ExecutePreprocessor` or `executenb` from `nbconvert` needs to be updated to use `nbclient` directly.
fix Migrate imports from `from nbconvert.preprocessors.execute import ...` to `from nbclient import ...`. For example, `from nbconvert.preprocessors.execute import executenb` should become `from nbclient import execute`.
gotcha The `timeout` parameter in `NotebookClient` defaults to 30 seconds per cell. For notebooks with long-running cells, this can lead to `TimeoutError`.
fix When initializing `NotebookClient`, explicitly set `timeout` to a higher value (e.g., `timeout=600` for 10 minutes) or set it to `None` or `-1` to disable the timeout entirely.
breaking An `AttributeError: metadata` occurs during `nbformat.write`, specifically when `nbformat` attempts to process `cell.metadata` (e.g., in `strip_transient`). This indicates that a notebook cell object within the provided content is malformed and lacks the expected 'metadata' attribute. This often happens when the input dictionary passed to `nbformat.from_dict` does not strictly conform to the `nbformat` specification, where every cell (code, markdown, raw) must have a `metadata` dictionary.
fix Ensure that the notebook content (dictionary) provided to `nbformat.from_dict` or similar constructors is valid and adheres to the `nbformat` specification. Specifically, verify that every cell object includes a `metadata` attribute, which should be a dictionary (even if empty). Consider using `nbformat.normalize()` on the notebook object before writing to resolve common structural issues if your `nbformat` version supports it.
breaking An `AttributeError: metadata` occurs when `nbformat` attempts to write a notebook where one or more cell objects are missing the required `metadata` attribute. This typically happens when notebook content is programmatically constructed and does not fully adhere to the `nbformat` schema, which dictates that every cell must include a `metadata` dictionary.
fix Ensure that all cell objects within the notebook structure (e.g., passed to `nbformat.from_dict`) explicitly include a `metadata` attribute, even if it's an empty dictionary (e.g., `{'cell_type': 'code', 'source': '...', 'metadata': {}}`). Verify that the notebook content conforms to the `nbformat` schema before writing.
python os / libc status wheel install import disk
3.10 alpine (musl) wheel - 0.64s 36.1M
3.10 alpine (musl) - - 0.61s 36.1M
3.10 slim (glibc) wheel 4.0s 0.49s 33M
3.10 slim (glibc) - - 0.49s 33M
3.11 alpine (musl) wheel - 0.83s 40.2M
3.11 alpine (musl) - - 0.89s 40.2M
3.11 slim (glibc) wheel 3.7s 0.72s 37M
3.11 slim (glibc) - - 0.68s 37M
3.12 alpine (musl) wheel - 0.95s 31.5M
3.12 alpine (musl) - - 0.99s 31.5M
3.12 slim (glibc) wheel 3.1s 0.89s 28M
3.12 slim (glibc) - - 0.91s 28M
3.13 alpine (musl) wheel - 0.91s 30.8M
3.13 alpine (musl) - - 0.95s 30.7M
3.13 slim (glibc) wheel 3.2s 0.85s 27M
3.13 slim (glibc) - - 0.88s 27M
3.9 alpine (musl) wheel - 0.66s 35.9M
3.9 alpine (musl) - - 0.66s 35.9M
3.9 slim (glibc) wheel 4.8s 0.67s 32M
3.9 slim (glibc) - - 0.56s 32M

This example demonstrates how to create a basic Jupyter notebook programmatically, execute it using `nbclient`, and then save the resulting notebook with its outputs. It also includes cleanup of the temporary files.

import nbformat
import os
from nbclient import NotebookClient

# Create a dummy notebook for execution
notebook_content = {
    "cells": [
        {
            "cell_type": "code",
            "source": "a = 1\nb = 2\nprint(a + b)",
            "outputs": [],
            "execution_count": None
        },
        {
            "cell_type": "code",
            "source": "import time\ntime.sleep(0.1)\nprint('Done sleeping')",
            "outputs": [],
            "execution_count": None
        }
    ],
    "metadata": {
        "kernelspec": {
            "display_name": "Python 3",
            "language": "python",
            "name": "python3"
        },
        "language_info": {
            "codemirror_mode": {
                "name": "ipython",
                "version": 3
            },
            "file_extension": ".py",
            "mimetype": "text/x-python",
            "name": "python",
            "nbconvert_exporter": "python",
            "pygments_lexer": "ipython3",
            "version": "3.10.0"
        }
    },
    "nbformat": 4,
    "nbformat_minor": 5
}

input_notebook_path = "my_input_notebook.ipynb"
output_notebook_path = "my_executed_notebook.ipynb"

with open(input_notebook_path, 'w', encoding='utf-8') as f:
    nbformat.write(nbformat.from_dict(notebook_content), f)

# Load the notebook
with open(input_notebook_path) as f:
    nb = nbformat.read(f, as_version=4)

# Configure and execute the notebook
# Adjust timeout for potentially long-running cells or set to None/-1
client = NotebookClient(nb, timeout=600, kernel_name='python3')
try:
    client.execute()
    print(f"Notebook '{input_notebook_path}' executed successfully.")
except Exception as e:
    print(f"Error executing notebook: {e}")

# Save the executed notebook with outputs
with open(output_notebook_path, 'w', encoding='utf-8') as f:
    nbformat.write(nb, f)

print(f"Executed notebook saved to '{output_notebook_path}'.")

# Clean up dummy notebook files
os.remove(input_notebook_path)
os.remove(output_notebook_path)