Jupyter Comm
Comm is a low-level Python library providing the core implementation for Jupyter communications (Comms). It enables custom bidirectional messaging between a Jupyter kernel (like ipykernel or xeus-python) and its connected frontend. It is currently at version 0.2.3 and is actively maintained, with releases typically tied to Jupyter ecosystem updates.
Warnings
- breaking The `traitlets` dependency was removed in version 0.2.3. If your code or other dependencies indirectly relied on `traitlets` through the `comm` package, this update might require explicit installation of `traitlets` or adjusting your code.
- gotcha The `comm` library is designed for communication between a Jupyter kernel and its frontend. Attempting to use `comm.Comm` outside of an active Jupyter kernel environment (e.g., in a standalone Python script) will likely result in errors (e.g., `NameError` for `get_ipython()`) because the necessary kernel infrastructure is not present.
- gotcha Direct usage of the `comm` library is a low-level operation. Most users needing kernel-frontend interactivity in Jupyter should consider using higher-level abstractions like `ipywidgets`, which simplify the process of creating interactive UI elements without needing to manage `Comm` objects directly.
Install
-
pip install comm
Imports
- Comm
import comm # ... later in a kernel ... my_comm = comm.Comm(target_name='my_target')
Quickstart
import comm
import os
# This example assumes it's running within a Jupyter kernel environment.
# In a real Jupyter setup, the frontend would register a 'my_comm_target'.
class MyKernelComm(comm.Comm):
def __init__(self, target_name='my_comm_target', data=None, metadata=None, buffers=None):
super().__init__(target_name, data, metadata, buffers)
print(f"Kernel Comm '{target_name}' opened.")
self.on_msg(self._handle_msg)
def _handle_msg(self, msg):
# msg['content']['data'] contains the message payload from the frontend
print(f"Kernel received message: {msg['content']['data']}")
if msg['content']['data'].get('action') == 'ping':
self.send({'action': 'pong', 'value': msg['content']['data'].get('value')})
print("Kernel sent 'pong'.")
def shutdown(self):
self.close()
print(f"Kernel Comm '{self.target_name}' closed.")
# Instantiate the Comm (in a real scenario, this would interact with the frontend)
# Note: Running this outside a Jupyter kernel will likely not connect to anything
# and 'comm.Comm' might rely on 'get_ipython()' which would not exist.
# To simulate, we'll just demonstrate the object creation and basic method calls.
# In a live kernel, this object would be managed by the kernel's CommManager.
try:
# This part would only successfully run inside a live Jupyter kernel
# where get_ipython() is available and the kernel manager is active.
# For a standalone script, this will raise an error.
if os.environ.get('SIMULATE_JUPYTER_KERNEL', 'false').lower() == 'true':
my_comm_instance = MyKernelComm(target_name='test_target')
my_comm_instance.send({'action': 'init', 'message': 'Hello from kernel!'})
# Simulate receiving a message
# In reality, the _handle_msg is called by the kernel's message loop
# This manual call is for demonstration purposes in a non-kernel environment
my_comm_instance._handle_msg({'content': {'data': {'action': 'ping', 'value': 42}}})
my_comm_instance.shutdown()
else:
print("To run a more interactive quickstart, execute this code within a Jupyter Notebook or IPython kernel.")
print("The 'comm' library provides the low-level API; higher-level libraries like ipywidgets are usually preferred.")
except Exception as e:
print(f"Could not fully demonstrate 'comm.Comm' outside a live Jupyter kernel. Error: {e}")