jupyter kernel message
目录
概述
每个kernel可以连接到一个或多个前端应用,每个Kernel都可以通过以下socket通道进行通信:
- shell:来自前端应用的传入请求,代码执行请求。这个socket是来自于前端和内核的 request/reply 的动作
- IOpub:这个socket是来自内核的广播,包括 stdout、stderr、debug调试。还包括任何 shell socket的传入和内核自己的stdin请求。在协助场景中(多个shell前端),内核通过这个socket向所有前端广播,此内核产生的一些事件信息。所有消息都带有详细的标记,以标记那些是当前的客户端调用,那些是其他的客户端调用。
- stdin:允许前端以raw_input的方式调用。前端可能使用一些 特殊的输入组件来实现这样的功能
- Control:类似shell通道,为了执行请求时排队。所以使用此socket执行 关闭、重启、调试的指令
- Heartbeat:允许前端发送一些简单的字符,以确保此socket 依然处于连接状态
消息格式
消息头部(header)
1 2 3 4 5 6 7 8 9 10 11 |
{ 'msg_id' : str, # typically UUID, must be unique per message 'session' : str, # typically UUID, should be unique per session 'username' : str, # ISO 8601 timestamp for when the message is created 'date': str, # All recognized message type strings are listed below. 'msg_type' : str, # the message protocol version 'version' : '5.3', } |
其中session id应在多客户端中具有唯一性。当客户端重新连接(reconnect)到内核时应使用相同的id,客户端重启(restart)时应分配新的id
msg_id 每个消息应是唯一的
父消息头(parent_header)
1 2 3 4 5 |
{ # parent_header is a copy of the request's header 'msg_id': '...', ... } |
当一个消息是另一个消息的结果时,例如:output、status、reply。此消息的 parent_header 拷贝自另一个消息的 header,以标识当前消息是针对parent_header进行的回复。reply类型的消息,必须有parent_header。如果消息没有父级关系,应为一个空字典{}。客户端通过 parent_header,将回复的消息路由并在正确的位置进行显示或渲染。
元数据(Metadata)
metadata 这个字典不包含消息的内容,并不经常使用,可以通过metadata额外的存储有关请求或响应的额外位置,例如添加请求或执行上下文的扩展信息
消息正文(Content)
content是消息的正文,它的具体结构由msg_type决定
Buffers
….
完整消息体
1 2 3 4 5 6 7 8 9 10 11 |
{ "header" : { "msg_id": "...", "msg_type": "...", ... }, "parent_header": {}, "metadata": {}, "content": {}, "buffers": [], } |
Shell通道(Request/Reply)
客户端发送 <action_request> 的消息(例如:execute_request、complete_request) 在shell通道,kernel收到消息后,会立刻在IOPub上发布 status: busy的消息,然后kernel处理请求,并发布 <action>_reply的消息(例如:execute_reply),处理完相关请求后,kernel可能会在发布一个 status: idle的消息。这个idle消息,表明在IOPub上给的请求已全部收到
所有的rely 回复消息都会有一个 status字段,该字段具有以下值:
-
- status=’ok’:请求已成功处理,
- status=’error’:请求出现错误,出现错误的请求会包含: ename、evalue、traceback字段
- status=’abort’:与error相同,但没有错误的消息,不会有其他字段
代码执行(Execute)
这个消息要求内核在为用户保留的命名空间中代表用户执行代码(与内核自己内部的代码区分开)
request
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
{ "buffers":[ ], "channel":"shell", "content":{ "silent":false, "store_history":true, "user_expressions":{ }, "allow_stdin":true, "stop_on_error":true, "code":"import os\nprint(123)" }, "header":{ "date":"2022-01-11T02:53:13.592Z", "msg_id":"da0b6075-d6ea-41bd-8620-53f7786657eb", "msg_type":"execute_request", "session":"55d75f58-66ab-4d37-81fc-64e68860ece9", "username":"", "version":"5.2" }, "metadata":{ "deletedCells":[ "2112ea60-d2f0-4aaf-8c9a-17a871b651c2" ], "recordTiming":false, "cellId":"7132447a-3e6f-4c8e-b28b-83895ca986e4" }, "parent_header":{ } } |
- code:内核要执行的源代码,一行或多行
- allow_stdin:在支持标准输入的前端,在内核运行中的代码可以提示用户输入
- stop_on_error:如果为True,在遇到异常时中止执行队列,如果为False,如果次请求产生一次,排队的execute_request也会执行
reply
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
{ "header":{ "msg_id":"497cbe90-f4183bb018b6e2496e31ab7a_1806_79", "msg_type":"execute_reply", "username":"kevinhan", "session":"497cbe90-f4183bb018b6e2496e31ab7a", "date":"2022-01-11T03:02:28.533140Z", "version":"5.3" }, "msg_id":"497cbe90-f4183bb018b6e2496e31ab7a_1806_79", "msg_type":"execute_reply", "parent_header":{ "date":"2022-01-11T03:02:28.527000Z", "msg_id":"393ac647-b674-4d4e-8196-ec4ee30078cb", "msg_type":"execute_request", "session":"55d75f58-66ab-4d37-81fc-64e68860ece9", "username":"", "version":"5.2" }, "metadata":{ "started":"2022-01-11T03:02:28.529976Z", "dependencies_met":true, "engine":"56a79fa2-1147-4d81-a748-83f65d4d4b56", "status":"ok" }, "content":{ "status":"ok", "execution_count":7, "user_expressions":{ }, "payload":[ ] }, "buffers":[ ], "channel":"shell" } |
命令补全(complete_request)
request
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
{ "buffers":[ ], "channel":"shell", "content":{ "code":"impor", "cursor_pos":5 }, "header":{ "date":"2022-01-11T02:32:49.678Z", "msg_id":"3eaf6905-8517-46c4-bc7c-7ad67174dab4", "msg_type":"complete_request", "session":"55d75f58-66ab-4d37-81fc-64e68860ece9", "username":"", "version":"5.2" }, "metadata":{ }, "parent_header":{ } } |
reply
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
{ "header":{ "msg_id":"43a02051-461730fd659b95477cc6391e_1254_50", "msg_type":"complete_reply", "username":"kevinhan", "session":"43a02051-461730fd659b95477cc6391e", "date":"2022-01-11T02:32:49.707059Z", "version":"5.3" }, "msg_id":"43a02051-461730fd659b95477cc6391e_1254_50", "msg_type":"complete_reply", "parent_header":{ "date":"2022-01-11T02:32:49.678000Z", "msg_id":"3eaf6905-8517-46c4-bc7c-7ad67174dab4", "msg_type":"complete_request", "session":"55d75f58-66ab-4d37-81fc-64e68860ece9", "username":"", "version":"5.2" }, "metadata":{ }, "content":{ "matches":[ "import" ], "cursor_end":5, "cursor_start":0, "metadata":{ "_jupyter_types_experimental":[ { "start":0, "end":5, "text":"import", "type":"keyword" } ] }, "status":"ok" }, "buffers":[ ], "channel":"shell" } |
Introspection
…
History
…
Code completeness
…
Kernel Info
客户端如果希望获取内核的信息可以发送此消息,可以获取内核的语言、语言版本、Ipython的版本等
request
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
{ "buffers":[ ], "channel":"shell", "content":{ }, "header":{ "date":"2022-01-11T03:32:13.737Z", "msg_id":"9185d898-6059-4d47-b4e7-415abdc1e4eb", "msg_type":"kernel_info_request", "session":"cec9c151-d64c-4cb7-972f-6df5d21658b6", "username":"", "version":"5.2" }, "metadata":{ }, "parent_header":{ } } |
reply
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
{ "header":{ "msg_id":"ee6f43eb-bede8f416780f55949617be1_2049_11", "msg_type":"kernel_info_reply", "username":"kevinhan", "session":"ee6f43eb-bede8f416780f55949617be1", "date":"2022-01-11T03:32:13.750293Z", "version":"5.3" }, "msg_id":"ee6f43eb-bede8f416780f55949617be1_2049_11", "msg_type":"kernel_info_reply", "parent_header":{ "date":"2022-01-11T03:32:13.737000Z", "msg_id":"9185d898-6059-4d47-b4e7-415abdc1e4eb", "msg_type":"kernel_info_request", "session":"cec9c151-d64c-4cb7-972f-6df5d21658b6", "username":"", "version":"5.2" }, "metadata":{ }, "content":{ "status":"ok", "protocol_version":"5.3", "implementation":"ipython", "implementation_version":"7.31.0", "language_info":{ "name":"python", "version":"3.8.2", "mimetype":"text/x-python", "codemirror_mode":{ "name":"ipython", "version":3 }, "pygments_lexer":"ipython3", "nbconvert_exporter":"python", "file_extension":".py" }, "banner":"Python 3.8.2 (default, Apr 8 2021, 23:19:18) \nType 'copyright', 'credits' or 'license' for more information\nIPython 7.31.0 -- An enhanced Interactive Python. Type '?' for help.\n", "help_links":[ { "text":"Python Reference", "url":"https://docs.python.org/3.8" }, { "text":"IPython Reference", "url":"https://ipython.org/documentation.html" }, { "text":"NumPy Reference", "url":"https://docs.scipy.org/doc/numpy/reference/" }, { "text":"SciPy Reference", "url":"https://docs.scipy.org/doc/scipy/reference/" }, { "text":"Matplotlib Reference", "url":"https://matplotlib.org/contents.html" }, { "text":"SymPy Reference", "url":"http://docs.sympy.org/latest/index.html" }, { "text":"pandas Reference", "url":"https://pandas.pydata.org/pandas-docs/stable/" } ] }, "buffers":[ ], "channel":"shell" } |
IOPub通道(PUB/SUB)
streams(stdout,stderr,etc)
内核通常执行的输出流,会通过stream消息广播,主要是文本消息
stream
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
{ "header":{ "msg_id":"ee6f43eb-bede8f416780f55949617be1_2049_37", "msg_type":"stream", "username":"kevinhan", "session":"ee6f43eb-bede8f416780f55949617be1", "date":"2022-01-11T03:42:03.717876Z", "version":"5.3" }, "msg_id":"ee6f43eb-bede8f416780f55949617be1_2049_37", "msg_type":"stream", "parent_header":{ "date":"2022-01-11T03:42:03.713000Z", "msg_id":"f63ac9d8-12dd-4715-8e38-6f1ee0c918e8", "msg_type":"execute_request", "session":"cec9c151-d64c-4cb7-972f-6df5d21658b6", "username":"", "version":"5.2" }, "metadata":{ }, "content":{ "name":"stdout", "text":"hello\n" }, "buffers":[ ], "channel":"iopub" } |
Display Data
这种消息类型用于带回应该在前端显示的数据(text、html、svg),这些数据会广播到所有客户端,每条消息可以有多种数据表示形式。有客户端决定使用哪种消息,并如何使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
{ "header":{ "msg_id":"ee6f43eb-bede8f416780f55949617be1_2049_188", "msg_type":"display_data", "username":"kevinhan", "session":"ee6f43eb-bede8f416780f55949617be1", "date":"2022-01-11T03:55:51.332028Z", "version":"5.3" }, "msg_id":"ee6f43eb-bede8f416780f55949617be1_2049_188", "msg_type":"display_data", "parent_header":{ "date":"2022-01-11T03:55:51.175000Z", "msg_id":"8d6a4aad-8521-45ab-9d9f-22b63778fc41", "msg_type":"execute_request", "session":"37501ba1-e733-44a1-9c36-2f7c95be1607", "username":"", "version":"5.2" }, "metadata":{ }, "content":{ "data":{ "text/plain":"<Figure size 432x288 with 1 Axes>", "image/png": "<图片的编码>" }, "metadata":{ "needs_background":"light" 'image/png' : { 'width': 640, 'height': 480 } }, "transient":{ } }, "buffers":[ ], "channel":"iopub" } |