Metadata-Version: 2.4
Name: async-kernel
Version: 0.19.1
Summary: A concurrent python kernel for Jupyter supporting AnyIO, AsyncIO and Trio.
Project-URL: Homepage, https://fleming79.github.io/async-kernel
Project-URL: Documentation, https://fleming79.github.io/async-kernel
Project-URL: Source, https://github.com/fleming79/async-kernel
Project-URL: Tracker, https://github.com/fleming79/async-kernel/issues
Project-URL: Changelog, https://fleming79.github.io/async-kernel/latest/about/changelog/
Author-email: Alan Fleming <async-python@proton.me>
License-Expression: MIT
License-File: IPYTHON_LICENSE
License-File: LICENSE
Keywords: Interactive,Interpreter,Jupyter,Shell,Web
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AnyIO
Classifier: Framework :: AsyncIO
Classifier: Framework :: Jupyter
Classifier: Framework :: Jupyter :: JupyterLab
Classifier: Framework :: Jupyter :: JupyterLab :: 4
Classifier: Framework :: Jupyter :: JupyterLab :: Extensions
Classifier: Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt
Classifier: Framework :: Trio
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: System Administrators
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3.15
Classifier: Programming Language :: Python :: Free Threading :: 1 - Unstable
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: aiologic>=0.16.0
Requires-Dist: anyio>=4.12
Requires-Dist: comm>=0.2
Requires-Dist: ipython>=9.0
Requires-Dist: jupyter-client>=8.8; sys_platform != 'emscripten'
Requires-Dist: jupyter-core>=5.9.1
Requires-Dist: matplotlib-inline>0.1
Requires-Dist: orjson>=3.10.16; sys_platform == 'emscripten'
Requires-Dist: outcome; sys_platform != 'emscripten'
Requires-Dist: pyzmq>=27.0; sys_platform != 'emscripten'
Requires-Dist: sniffio>=1.3.0; sys_platform != 'emscripten'
Requires-Dist: traitlets>=5.14
Requires-Dist: typing-extensions>=4.14
Requires-Dist: wrapt>=2.0.1
Description-Content-Type: text/markdown

# async-kernel

[![pypi](https://img.shields.io/pypi/pyversions/async-kernel.svg)](https://pypi.python.org/pypi/async-kernel)
[![downloads](https://img.shields.io/pypi/dm/async-kernel?logo=pypi&color=3775A9)](https://pypistats.org/packages/async-kernel)
[![CI](https://github.com/fleming79/async-kernel/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/fleming79/async-kernel/actions/workflows/ci.yml)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)
[![basedpyright - checked](https://img.shields.io/badge/basedpyright-checked-42b983)](https://docs.basedpyright.com)
[![Built with Material for MkDocs](https://img.shields.io/badge/Material_for_MkDocs-526CFE?style=plastic&logo=MaterialForMkDocs&logoColor=white)](https://squidfunk.github.io/mkdocs-material/)
[![codecov](https://codecov.io/github/fleming79/async-kernel/graph/badge.svg?token=PX0RWNKT85)](https://codecov.io/github/fleming79/async-kernel)

![logo-svg](https://github.com/user-attachments/assets/6781ec08-94e9-4640-b8f9-bb07a08e9587)

async-kernel is a Python kernel for [Jupyter](https://docs.jupyter.org/en/latest/projects/kernels.html#kernels-programming-languages)
that provides concurrent message handling via an asynchronous backend (asyncio or trio).

The kernel provides two external interfaces:

1. Direct ZMQ socket messaging via a configuration file and kernel spec - (Jupyter, VS Code, etc).
2. An experimental callback style interface (Jupyterlite).

## Highlights

- [IPython shell](https://ipython.readthedocs.io/en/stable/overview.html#enhanced-interactive-python-shell)
    - top-level await ('asyncio' or 'trio' backend) in cells
    - async magic function support in cells
- [anyio](https://pypi.org/project/anyio/) compatible asynchronous backend ([`asyncio`](https://docs.python.org/3/library/asyncio.html) (default) or [`trio`](https://pypi.org/project/trio/))
- [aiologic](https://aiologic.readthedocs.io/latest/) thread-safe synchronisation primitives
- [Backend agnostic multi-thread / multi-event loop management](https://fleming79.github.io/async-kernel/latest/reference/caller/#async_kernel.caller.Caller)
- Per-subshell user_ns
- GUI event loops [^1]
    - [x] inline
    - [x] ipympl
    - [x] tk host and asyncio[^2] or trio[^3] backend running as a guest
    - [x] qt host and asyncio[^2] or trio[^3] backend running as a guest
- [Experimental](https://github.com/fleming79/echo-kernel) support for
  [Jupyterlite](https://github.com/jupyterlite/jupyterlite) (try it online [here](https://fleming79.github.io/echo-kernel/) 👈)
    - `%pip install` magic (using micropip)
- [Debugger client](https://jupyterlab.readthedocs.io/en/latest/user/debugger.html#debugger)

[^1]:
    A gui (_host_) enabled kernel interface starts a gui's mainloop (host) which starts
    the backend as a guest, then finally the Kernel is started.

[^2]:
    The asyncio implementation of `start_guest_run` was written by
    [the author of aiologic](https://github.com/x42005e1f/aiologic) and provided as a
    [gist](https://gist.github.com/x42005e1f/857dcc8b6865a11f1ffc7767bb602779).

[^3]: trio's [start_guest_run](https://trio.readthedocs.io/en/stable/reference-lowlevel.html#trio.lowlevel.start_guest_run).

### Avoid deadlocks

The standard (synchronous) kernel implementation processes messages sequentially irrespective
of the message type. The problem being that long running execute requests make the kernel non-responsive.

Another problem exists when an asynchronous execute request awaits a result that is delivered
via a kernel message - this will cause a deadlock because the message will be stuck in the queue behind
the _blocking_ execute request[^5].

async-kernel handles messages according to the channel and message type. So widget com message
will get processed in a separate queue to an execute request. Further detail is given in the [concurrency notebook](https://fleming79.github.io/async-kernel/latest/notebooks/concurrency/), a Jupyterlite version is available [here](https://fleming79.github.io/echo-kernel/).

#### Example

Make a blocking call in a Jupyter lab notebook or console.

```python
# Make the shell's thread busy
import time

time.sleep(1e6)
```

While the above is _blocking_ (the kernel is _busy_).

```python
dir()  # try code completion (tab) or view the docstring (shift tab)
```

Interrupt the kernel.

It also works for awaitables.

```python
import ipywidgets as ipw
from aiologic import Event

b = ipw.Button(description="Click me")
event = Event()
b.on_click(lambda _: event.set())
display(b)
await event
```

[^5]:
    IPyKernel _solves_ this issue specifically for widgets by using the concept of
    'widget coms over subshells'. Widget messages arrive in a different thread which on
    occasion can cause unexpected behaviour, especially when using asynchronous libraries.

## Installation

```bash
pip install async-kernel
```

## Kernelspecs

A kernelspec with the name 'async' is added when async-kernel is installed.

Kernel specs can be installed/uninstalled via the command line.

```bash
async-kernel install

# To install for a user
async-kernel install --user
```

For further detail about kernel spec customisation see [command line and kernel configuration](https://fleming79.github.io/async-kernel/latest/usage/commands/) and [custom kernel.ipynb](https://fleming79.github.io/async-kernel/latest/notebooks/custom_kernel/).

## Faster data serialization

[orjson](https://github.com/ijl/orjson) (a fast JSON library) is supported and will be used by default if it has been installed.

## Free-threading support

async-kernel's Caller's are _thread-local_ and it's methods are _internally synchronised_[^4].

[^4]: [free threading terminology](https://py-free-threading.github.io/documentation-principles/#free-threading-terminology)

## Origin

async-kernel started as a [fork](https://github.com/ipython/ipykernel/commit/8322a7684b004ee95f07b2f86f61e28146a5996d)
of [IPyKernel](https://github.com/ipython/ipykernel). Thank you to the original contributors of IPyKernel that made async-kernel possible.
