Merge pull request #1874 from takluyver/comms-doc

Start documenting how to use Comms
This commit is contained in:
Carol Willing 2016-11-03 17:35:12 -07:00 committed by GitHub
commit 277ce51dbf
2 changed files with 94 additions and 0 deletions

93
docs/source/comms.rst Normal file
View File

@ -0,0 +1,93 @@
Comms
=====
*Comms* allow custom messages between the frontend and the kernel. They are used,
for instance, in `ipywidgets <http://ipywidgets.readthedocs.io/en/latest/>`__ 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 <http://jupyter-client.readthedocs.io/en/latest/messaging.html#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 <extending/frontend_extensions>` 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);
});

View File

@ -11,6 +11,7 @@ The Jupyter notebook
Running the Notebook <https://jupyter.readthedocs.io/en/latest/running.html>
Migrating from IPython <https://jupyter.readthedocs.io/en/latest/migrating.html>
ui_components
comms
.. toctree::
:maxdepth: 2