Skip to content

Latest commit

 

History

60 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

jupyasyncclient

jupyasyncclient runs code on Jupyter kernels hosted by any server speaking the standard kernels API: rustygate, jupygate, or jupyter_server. Kernel lifecycle (create, interrupt, restart, delete) is plain HTTP; messaging is one websocket per client carrying standard Jupyter message dicts with a channel key. There is no zmq and no tornado in the client process, and every send is genuinely awaited - the zmq-side subtleties (sync-send edge consumption, slow-joiner subscriptions, socket identity contracts) all live server-side.

Three classes cover the usual shapes, mirroring jupyter_client where familiarity helps:

  • JupyAsyncKernelClient - one kernel: lifecycle, channels, and messaging. execute, complete, inspect, history, kernel_info, and wait_for_ready work like their jupyter_client namesakes. execute sends fire-and-forget, reply awaits one execute_reply, and run collects every message one execute causes; broadcast traffic goes to an on_jmsg callback, with JmsgQueues as the pull adapter. Every *_request message type in the protocol is callable by name, returning an awaitable of its reply, subshell requests included, so new protocol messages need no client release.
  • JupyAsyncKernelManager - start/stop one kernel and mint clients for it.
  • JupyAsyncMultiKernelManager - a fleet, with keyed reuse: ensure_kernel('some-key') returns the live kernel registered under that key or starts a fresh one.

The core notebook builds the client bottom-up with every method demonstrated against a live server; the managers are thin HTTP wrappers and live in plain modules.

Two sibling pages cover the rest of a gateway’s surface: term attaches JupyAsyncTerminalClient to gateway-hosted terminals, and files builds JupyAsyncFilesClient and JupyAsyncCellsClient over the files and cells APIs, including apply_ops for keeping a local view current from a kernel’s change broadcasts.

Install

pip install jupyasyncclient

Plus a server to talk to. The examples here use rustygate serving ipymini kernels; a stock jupyter_server works identically (the test suite runs against one).

Use

import asyncio
from rustygate.tools import start_gateway
g = start_gateway()
g
True

start_new_server_kernel gives a running kernel and a ready client in one call:

km, kc = await start_new_server_kernel(g.url)
qs = JmsgQueues(kc, queues=('jmsg',), merge=dict(iopub='jmsg', stdin='jmsg'))
rep = await kc.reply("print('hello'); 6*7", timeout=30)
rep['content']['status']
'ok'

Outputs arrive on the iopub queue, like jupyter_client:

m = await qs.jmsg_for('stream', timeout=15)
m['content']['text']
'hello\n'

input() in the kernel becomes an input_request on the stdin queue; answer it with input, which parents the reply properly:

fut = asyncio.ensure_future(kc.reply("name = input('who? ')", timeout=30))
prompt = await qs.jmsg_for('input_request', timeout=15)
kc.input('Jeremy')
(await fut)['content']['status']
'ok'

Any protocol request type works by name, awaited for its reply - here JEP 91 subshells, no client support required beyond the message type:

sub = (await kc.create_subshell(timeout=15))['content']['subshell_id']
rep = await kc.reply('40+2', timeout=30, subshell_id=sub)
await kc.delete_subshell(sub, timeout=15)
rep['content']['status']
'ok'

The multimanager runs fleets, with keyed reuse for “the kernel for X” patterns:

mkm = JupyAsyncMultiKernelManager(g.url)
k1 = await mkm.ensure_kernel('analysis')
k2 = await mkm.ensure_kernel('analysis')
k1 == k2
True
await kc.aclose()
await km.shutdown_kernel()
await mkm.shutdown_all()

Auth is a bearer token when the server requires one: pass token=... to any of the three classes and it is sent as an Authorization header on HTTP and a query param on the websocket.

About

Like jupyter_client, but for websockets

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages