mrkeyoor.com_
Sun 20 Sept 14:45 UTC
PyPIDataupdated 19 Sept 2026

ipykernel review

ipykernel 7.3.0 is the Python process a Jupyter frontend talks to over ZeroMQ. It accepts execute, inspect, complete, interrupt, and debugger messages, then publishes stream output and rich display data back to the client. You normally install it in each virtual environment and register that interpreter as a kernelspec; application code rarely imports it. The current release adds ZMQ Curve transport encryption and display-hook registration, forwards cell metadata into execution, and correctly fails a cell when output formatting raises an exception.

Verdict

ipykernel 7.3.0 added 29 packages and 71 MB in our sandbox, although installation finished in 2.2 seconds with no audit findings. Install it only in environments that must execute notebooks, register the intended interpreter explicitly, and use IPython alone for terminal-only work.

We installed it

Lab card: what happened when we installed ipykernelScreenshot of ipykernel documentation
Install✓ · 2.2s29 packages on disk · 71 MB
Importimport ipykernel in 0.70s · pure Python · py.typed · requires Python >=3.10
Known vulns0(pip-audit)

Answers from our run

Does ipykernel install cleanly?

Yes. In a fresh container with an empty cache, pip install ipykernel finished in 2 seconds, leaving 29 packages and 71 MB on disk. pip-audit reported no known vulnerabilities.

What does ipykernel need to run?

Python >=3.10, and nothing compiled: it is pure Python. In our run import ipykernel succeeded in 0.70s, and the package ships py.typed for type checkers.

ipykernel or jupyter-console: which should you use?

jupyter-console: Choose it when you need a terminal client for an existing Jupyter kernel, without a browser notebook. ipykernel 7.3.0 added 29 packages and 71 MB in our sandbox, although installation finished in 2.2 seconds with no audit findings.

When should you not use ipykernel?

You only want a terminal REPL. IPython gives you completion, history, magics, and top-level await without a kernelspec, ZeroMQ channels, or a separate frontend.

API stability3/5The visible workflow of selecting a named Python kernelspec has stayed consistent, and Jupyter messaging keeps ordinary frontends interoperable. The internal extension surface moved in 7.x: Python 3.9 support ended, subshell work came with a downstream compatibility warning, execution handlers are async, and 7.3 forwards cell_meta into run_cell. Users who only run notebooks see continuity, while kernel subclasses and tools that inspect internals need a pinned-major test matrix.
Docs2/5The API site and changelog document kernel classes, connection helpers, configuration, debugger support, and individual 7.3 changes. The repository README mostly covers installing from source and running tests. Everyday problems such as kernelspec precedence, stale argv paths, connection-file permissions, frontend discovery, and event-loop conflicts span ipykernel, Jupyter Client, IPython, and frontend documentation, so the first useful diagnosis often takes several sites.
Maintenance5/5GitHub shows an unarchived repository pushed on 2026-08-24, with 308 open issues and pull requests. Release 7.3.0 shipped on 2026-06-10 and lists transport, display-hook, metadata, formatter-failure, shutdown, sys.modules, and debugpy work. That queue is large, but it matches a kernel that must coordinate multiple frontends, debuggers, operating systems, GUI loops, transports, and evolving Python runtimes.
Ecosystem5/5The catalog records 16,670,803 weekly downloads and GitHub reports 734 stars. JupyterLab, VS Code notebooks, nbclient, papermill, nbconvert, and hosted notebook systems use the same kernelspec and messaging conventions. Other Python kernels exist, yet ipykernel is the expected interpreter bridge across most of that toolchain, and the installed py.typed marker helps code that embeds its public APIs.

Use it if

  • A Python virtualenv or conda environment must appear by name in JupyterLab, VS Code, or another Jupyter client.
  • Notebook jobs run in CI through nbclient, papermill, or nbconvert and need a repeatable kernel identity.
  • The frontend needs Python debugging through ipykernel's debugpy integration.
  • You are building or testing a client that speaks the Jupyter messaging protocol to a Python kernel.
Skip it if

Setup reality

We installed ipykernel 7.3.0 in a fresh, unprivileged Python 3.12 Bookworm container. pip completed in 2.2 seconds, left 29 packages, and used 71 MB. The metadata declares 34 direct requirements and Python 3.10 or newer. This is pure Python, includes py.typed, and imported in 0.70 seconds. pip-audit found zero known vulnerabilities. The package metadata did not provide a license value, so do not infer one from that field alone.

Installation and discovery are separate steps. Run python -m ipykernel install with the interpreter notebooks should use, then choose a stable --name and either --sys-prefix or --user. The resulting kernel.json stores an executable path in argv. If notebook imports disagree with the activated shell, inspect that file and print sys.executable in a cell. The frontend follows the kernelspec, not the terminal's currently activated environment.

Kernelspecs are ordinary files and can remain after their virtualenv is deleted. Remove stale entries with jupyter kernelspec uninstall. Values passed through --env are written in plain text, which is suitable for thread counts or device selection but unsafe for tokens. Runtime connection files include ports and the HMAC signing key. Shared machines need restrictive permissions on the Jupyter runtime directory; version 7.3.0 adds Curve support when transport encryption is required.

A running kernel already manages an event loop. Top-level await works, while asyncio.run() inside a cell can fail because another loop is active. Matplotlib widget and GUI modes need their backend packages and event-loop integration. Code that subclasses Kernel must test the 7.x async handler signatures, keyword-only cell metadata, debugger behavior, and subshell changes rather than assuming a notebook picker upgrade is the whole migration.

Patterns

Expose the current interpreter to Jupyter register-active-environment

python -m pip install ipykernel
python -m ipykernel install --sys-prefix \
  --name analytics \
  --display-name 'Python (analytics)'

--sys-prefix writes the kernelspec under the active environment. Its argv entry records this environment's Python executable.

Create a user-level kernel entry register-user-kernel

python -m ipykernel install --user \
  --name project-a \
  --display-name 'Python (project-a)'

A --user kernelspec is visible to that user's Jupyter installations and can outlive the virtualenv. Use a unique internal name to avoid replacement.

Find the executable a kernel will start inspect-kernel-paths

jupyter kernelspec list

# Then inspect the selected file:
python -m json.tool /path/to/kernels/project-a/kernel.json

The first argv value in kernel.json decides which Python starts. The display name shown in a frontend does not prove that path is correct.

Confirm the environment from a cell verify-notebook-interpreter

import sys

print(sys.executable)
print(sys.prefix)

%pip install requests

%pip targets the running kernel's interpreter. A !pip shell command can resolve a different executable from the spawned shell's PATH.

Set device and thread limits before startup set-kernel-environment

python -m ipykernel install --sys-prefix \
  --name gpu-job \
  --display-name 'Python (GPU 0)' \
  --env CUDA_VISIBLE_DEVICES 0 \
  --env OMP_NUM_THREADS 4

These values are stored as readable text in kernel.json. Use them for runtime selection, never for passwords or API tokens.

Delete a dead environment entry remove-stale-kernelspec

jupyter kernelspec list
jupyter kernelspec uninstall project-a
jupyter kernelspec list

Removing ipykernel from a virtualenv does not remove a user-level kernelspec. Uninstall the named entry when its argv path no longer exists.

Run a notebook with one named kernel execute-notebook-in-ci

import nbformat
from nbclient import NotebookClient

notebook = nbformat.read('report.ipynb', as_version=4)
NotebookClient(
    notebook,
    timeout=600,
    kernel_name='analytics',
).execute()
nbformat.write(notebook, 'report.executed.ipynb')

kernel_name is the internal --name value, not the display label. CI must register it before nbclient starts or execution raises NoSuchKernel.

Use the kernel's existing event loop await-in-cell

import asyncio

async def load():
    await asyncio.sleep(0.1)
    return 42

value = await load()

Top-level await is supported. Calling asyncio.run(load()) in the same cell can raise because ipykernel already has an active loop.

Select static or widget plots choose-matplotlib-backend

%matplotlib inline

# For an interactive widget after installing ipympl:
%matplotlib widget

The widget backend requires ipympl in the environment used by this kernel. Installing it in the frontend's environment is insufficient.

Attach a console to an existing process connect-console-to-kernel

jupyter console --existing kernel-12345.json

The connection file contains ports and a message-signing key. Only attach to files from a trusted, permission-protected runtime directory.

Inspect the active connection file read-connection-details

from ipykernel.connect import get_connection_file, get_connection_info

print(get_connection_file())
info = get_connection_info(unpack=True)
print(info['transport'], info['shell_port'])

Do not log the full info mapping because it includes the HMAC key. Version 7.3.0 also supports ZMQ Curve for encrypted transport.

Keep Python 3.9 on the 6.x line pin-older-major

# requirements.txt
ipykernel<7

ipykernel 7 requires Python 3.10 or newer. A 6.x pin can also buy time for tools that still depend on the previous subshell or handler internals.

Alternatives

PackageRegistryPick it when
jupyter-consolePyPIChoose it when you need a terminal client for an existing Jupyter kernel, without a browser notebook.
xeus-pythonPyPIChoose it for the xeus C++ kernel architecture and its different embedding tradeoffs.
ptpythonPyPIChoose it for a polished local Python REPL when the Jupyter protocol is irrelevant.

More data guides

numpy · fsspec · pandas · sqlalchemy · pyarrow · lxml · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.