公文

公文 允许前端和内核之间的自定义消息。例如,它们用于 ipywidgets 更新小部件状态。

通信由内核和前端中的一对对象组成,具有自动分配的唯一ID。当一方发送消息时,另一方的回调将由该消息数据触发。无论是前端还是内核,都可以打开或关闭通信。

参见

Custom Messages

通信信息规范部分

从内核打开通信

首先,前端必须有接受通信的功能。这可以在 requirejs 模块,或在注册表中注册,例如当 extension 已加载。此示例显示在注册表中注册的前端通信目标:

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});
    });

现在,前端通信已注册,您可以从内核打开通信:

from ipykernel.comm import Comm

# Use comm to send a message from the kernel
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

这个例子使用ipython内核;它取决于每个语言内核,如果有API,它提供什么来使用comms。

从前端打开通信

这与上面的非常相似,但相反。首先,通信目标必须在内核中注册。例如,这可以通过代码显示输出来实现:它将在内核中注册一个目标,然后显示包含要连接到它的javascript的输出。

def target_func(comm, open_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
        comm.send({'echo': msg['content']['data']})

    # Send data to the frontend on creation
    comm.send({'foo': 5})

get_ipython().kernel.comm_manager.register_target('my_comm_target', target_func)

这个例子再次使用ipython内核;这个例子在其他支持通信的内核中会有所不同。有关comms支持,请参阅特定语言内核的文档。

然后从前端打开通讯:

const 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);
});