conkernelclient
Background
Jupyter’s KernelClient is designed around a simple request-reply pattern: you send one message on the shell channel, wait for its reply, then send the next. This works fine for a single-threaded notebook, but falls apart when you need concurrent execution. For instance, running multiple cells in parallel, or letting an LLM tool loop fire off code while a long-running computation is still in flight. The underlying ZMQ socket isn’t safe to share across tasks, and there’s no built-in mechanism to route replies back to the correct caller when multiple requests are outstanding.
conkernelclient solves this with ConKernelClient, a drop-in replacement for AsyncKernelClient that makes concurrent execute() calls safe. It patches Session.send to synchronise with the ZMQ I/O thread (preventing a race where two sends interleave), and spins up a dedicated reader task on the shell channel that demultiplexes incoming replies by message ID. Each execute(..., reply=True) call gets its own asyncio.Queue, so multiple coroutines can await their replies independently without interfering with each other.
Installation
Install from pypi
$ pip install conkernelclient
How to use
from conkernelclient import *
The main entry point is ConKernelManager, a drop-in replacement for AsyncKernelManager that creates ConKernelClient instances. Start a kernel and connect a client in the usual way:
import asyncio
from jupyter_client.session import Session
km = ConKernelManager(session=Session(key=b'x'))
await km.start_kernel()
kc = await km.client().start_channels()
await kc.is_alive()
True
Once connected, execute() works like the standard client. Pass reply=True to await the shell reply, or reply=False (the default) to fire-and-forget and collect results later via get_pubs:
r = await kc.execute('2+1', timeout=1, reply=True)
r['content']['status']
'ok'
The key feature is safe concurrent execution. Multiple execute(..., reply=True) calls can be outstanding simultaneously — each gets its own asyncio.Queue, and a background reader task routes replies by message ID:
from fastcore.test import test_eq
a = kc.execute('x=2', reply=True)
b = kc.execute('y=3', reply=True)
r = await asyncio.wait_for(asyncio.gather(a, b), timeout=2)
test_eq(len(r), 2)
r[0]['parent_header']['msg_id']
'8c84fe1c-20242a1940eecfc5a1a31500_61486_3'
Both replies arrive independently, each routed to the correct caller. Without ConKernelClient, the second execute would either block waiting for the first to finish, or the replies would get crossed.
As usual, we clean up when we’re done:
if await km.is_alive():
kc.stop_channels()
await km.shutdown_kernel()
Metadata
Release files for conkernelclient 0.0.23
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| conkernelclient-0.0.23.tar.gz | 16.1 kB | Without provenance | Details for conkernelclient-0.0.23.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| conkernelclient-0.0.23-py3-none-any.whl | Python 3 | none | any | Details for conkernelclient-0.0.23-py3-none-any.whl |
Total release size: 30.9 kB
Release files / conkernelclient-0.0.23.tar.gz
| Download URL | conkernelclient-0.0.23.tar.gz |
|---|---|
| Size | 16.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3c3119e2bb77979a131598fc097159b097c03e47886d27e870de6594d562938a
|
|
BLAKE2b-256 checksum How to use checksums |
a1e1cece7bcd1cf221457042d51475fa713954631c549345999eb89f1d322043
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.15
|
Release files / conkernelclient-0.0.23-py3-none-any.whl
| Download URL | conkernelclient-0.0.23-py3-none-any.whl |
|---|---|
| Size | 14.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c0f993c6af0590d1b29c4ce026f0c7b78f0e41316a0a89b90a8cf35edf70b7c7
|
|
BLAKE2b-256 checksum How to use checksums |
0c9b5fa86921f154ac01e60be71cc455e2541c5cbf276d8411ad6f28d40ce6b2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.15
|
Security for conkernelclient 0.0.23
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.