From 5cdc8682d393c15ee921b0aaed0665a365685dfa Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Thu, 3 Nov 2016 16:00:46 -0700 Subject: [PATCH] Start documenting how to use Comms See gh-1869 --- docs/source/comms.rst | 93 +++++++++++++++++++++++++++++++++++++++++++ docs/source/index.rst | 1 + 2 files changed, 94 insertions(+) create mode 100644 docs/source/comms.rst diff --git a/docs/source/comms.rst b/docs/source/comms.rst new file mode 100644 index 000000000..cc03a8baa --- /dev/null +++ b/docs/source/comms.rst @@ -0,0 +1,93 @@ +Comms +===== + +*Comms* allow custom messages between the frontend and the kernel. They are used, +for instance, in `ipywidgets `__ to +update widget state. + +A comm consists of a pair of objects, in the kernel and the frontend, with an +automatically assigned unique ID. When one side sends a message, a callback on +the other side is triggered with that message data. Either side can open or +close the comm. + +.. seealso:: + + `Custom Messages `__ + The messaging specification section on comms + +Opening a comm from the kernel +------------------------------ + +First, the function to accept the comm must be available on the frontend. This +can either be specified in a requirejs module, or registered in a registry, for +example when an :doc:`extension ` is loaded. The +latter is what we'll show here: + +.. code-block:: javascript + + Jupyter.notebook.kernel.comm_manager.register_target('my_comm_target', + function(comm, msg) { + // comm is the frontend comm instance + // msg is the comm_open message, which can carry data + + // Register handlers for later messages: + comm.on_msg(function(msg) {...}); + comm.on_close(function(msg) {...}); + comm.send({'foo': 0}); + }); + +Now you can open it from the kernel:: + + from ipykernel.comm import Comm + my_comm = Comm(target_name='my_comm_target', data={'foo': 1}) + my_comm.send({'foo': 2}) + + # Add a callback for received messages. + @my_comm.on_msg + def _recv(msg): + # Use msg['content']['data'] for the data in the message + + +This example is for IPython; its up to each kernel what API, if any, it offers +for using comms. + +Opening a comm from the frontend +-------------------------------- + +This is very similar to above, but in reverse. First, a comm target must be +registered in the kernel. For instance, this may be done by code displaying +output: it will register a target in the kernel, and then display output +containing Javascript to connect to it. + +:: + + def target_func(comm, msg): + # comm is the kernel Comm instance + # msg is the comm_open message + + # Register handler for later messages + @comm.on_msg + def _recv(msg): + # Use msg['content']['data'] for the data in the message + + # Send data to the frontend + comm.send({'foo': 5}) + + get_ipython().kernel.comm_manager.register_target('my_comm_target', target_func) + +This example is for IPython again; this will be different in other kernels that +support comms. + +And then open it from the frontend: + +.. code-block:: javascript + + comm = Jupyter.notebook.kernel.comm_manager.new_comm('my_comm_target', + {'foo': 6}) + // Send data + comm.send({'foo': 7}) + + // Register a handler + comm.on_msg(function(msg) { + console.log(msg.content.data.foo); + }); diff --git a/docs/source/index.rst b/docs/source/index.rst index ae1cbd6c0..f44bf8514 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -11,6 +11,7 @@ The Jupyter notebook Running the Notebook Migrating from IPython ui_components + comms .. toctree:: :maxdepth: 2