0

Goal: Enable real-time interaction with a Jupyter Notebook by sharing the same kernel between Python code (CLI/script) and the Jupyter Notebook UI.

Use case: Allow a script to interact with variables defined in the Jupyter Notebook interface, and vice versa. Example:

  • In the Notebook UI, define a variable: x = 2.
  • From Python script/CLI, run a function that executes print(x).
  • Expected output: 2 - confirmation that the kernel sharing works.

Attempts: Started Jupyter Lab using collaborative mode (command: jupyter lab --no-browser --IdentityProvider.token=eere --ip=0.0.0.0 --port=14484 --collaborative). Then, execute the code below:

from jupyter_nbmodel_client import NbModelClient, get_jupyter_notebook_websocket_url
from jupyter_kernel_client import KernelClient

SERVER_URL = "http://localhost:14484"
TOKEN = "eere"
NOTEBOOK_PATH = "~/Documents/envs/test/kernel_test.ipynb"
cell_content = "print(x)"

kernel = KernelClient(server_url=SERVER_URL, token=TOKEN)
kernel.start()

notebook = NbModelClient(
    get_jupyter_notebook_websocket_url(server_url=SERVER_URL, token=TOKEN, path=NOTEBOOK_PATH)
)
await notebook.start()
cell_index = notebook.add_code_cell(cell_content)
notebook.execute_cell(cell_index, kernel)

Code output:

Websocket client stopped.
Traceback (most recent call last):
  File "~Documents/envs/test/.really_delete/lib/python3.10/site-packages/jupyter_nbmodel_client/client.py", line 86, in _listen_to_websocket
    async for message in websocket:
  File "~Documents/envs/test/.really_delete/lib/python3.10/site-packages/websockets/asyncio/connection.py", line 242, in __aiter__
    yield await self.recv()
  File "~Documents/envs/test/.really_delete/lib/python3.10/site-packages/websockets/asyncio/connection.py", line 322, in recv
    raise self.protocol.close_exc from self.recv_exc
websockets.exceptions.ConnectionClosedError: sent 1002 (protocol error) invalid status code; no close frame received
Document ws://localhost:14484/api/collaboration/room/json:notebook:54aee93a-b50f-4190-820f-c5306b218eb8?sessionId=7781e065-b341-4f85-8a56-f4caa4190de6&token=eere not yet synced.

{'execution_count': 1,
 'outputs': [{'output_type': 'error',
   'ename': 'NameError',
   'evalue': "name 'x' is not defined",
   'traceback': ['\x1b[0;31m---------------------------------------------------------------------------\x1b[0m',
    '\x1b[0;31mNameError\x1b[0m                                 Traceback (most recent call last)',
    'Cell \x1b[0;32mIn[1], line 1\x1b[0m\n\x1b[0;32m----> 1\x1b[0m \x1b[38;5;28mprint\x1b[39m(\x1b[43mx\x1b[49m)\n',
    "\x1b[0;31mNameError\x1b[0m: name 'x' is not defined"]}],
 'status': 'error'}

After the WS error, the x name is not defined in the above error:

"\x1b[0;31mNameError\x1b[0m: name 'x' is not defined"]}],

Any help is more than welcome!!

3
  • maybe it needs to execute cell which has x = 2 before you execute cell with print(x)
    – furas
    Commented Apr 10 at 11:33
  • No really! The x = 2 should be in declared in the UI. Then, the print(x) will be added by the code. The code, ideally, connects to the kernel and retrieve x.
    – Morpheus
    Commented Apr 10 at 12:23
  • This post shared some communicating with an ipykernel from a Python script. Maybe it will give you some ideas? Some of the syntax may have changed though since that was around the time of the changeover to infrastructure being based on JupyterLab components.
    – Wayne
    Commented Apr 10 at 15:01

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.