##// END OF EJS Templates
Add docs on writing kernels
Thomas Kluyver -
Show More
@@ -0,0 +1,145 b''
1 ==========================
2 Making kernels for IPython
3 ==========================
4
5 A 'kernel' is a program that runs and introspects the user's code. IPython
6 includes a kernel for Python code, and people have written kernels for
7 `several other languages <https://github.com/ipython/ipython/wiki/Projects-using-IPython#list-of-some-ipython-compatible-kernels>`_.
8
9 When IPython starts a kernel, it passes it a connection file. This specifies
10 how to set up communications with the frontend.
11
12 There are two options for writing a kernel:
13
14 1. You can reuse the IPython kernel machinery to handle the communications, and
15 just describe how to execute your code. This is much simpler if the target
16 language can be driven from Python. See :doc:`wrapperkernels` for details.
17 2. You can implement the kernel machinery in your target language. This is more
18 work initially, but the people using your kernel might be more likely to
19 contribute to it if it's in the language they know.
20
21 Connection files
22 ================
23
24 Your kernel will be given the path to a connection file when it starts (see
25 :ref:`kernelspecs` for how to specify the command line arguments for your kernel).
26 This file, which is accessible only to the current user, will contain a JSON
27 dictionary looking something like this::
28
29 {
30 "control_port": 50160,
31 "shell_port": 57503,
32 "transport": "tcp",
33 "signature_scheme": "hmac-sha256",
34 "stdin_port": 52597,
35 "hb_port": 42540,
36 "ip": "127.0.0.1",
37 "iopub_port": 40885,
38 "key": "a0436f6c-1916-498b-8eb9-e81ab9368e84"
39 }
40
41 The ``transport``, ``ip`` and five ``_port`` fields specify five ports which the
42 kernel should bind to using `ZeroMQ <http://zeromq.org/>`_. For instance, the
43 address of the shell socket in the example above would be::
44
45 tcp://127.0.0.1:57503
46
47 New ports are chosen at random for each kernel started.
48
49 ``signature_scheme`` and ``key`` are used to cryptographically sign messages, so
50 that other users on the system can't send code to run in this kernel. See
51 :ref:`wire_protocol` for the details of how this signature is calculated.
52
53 Handling messages
54 =================
55
56 After reading the connection file and binding to the necessary sockets, the
57 kernel should go into an event loop, listening on the hb (heartbeat), control
58 and shell sockets.
59
60 :ref:`Heartbeat <kernel_heartbeat>` messages should be echoed back immediately
61 on the same socket - the frontend uses this to check that the kernel is still
62 alive.
63
64 Messages on the control and shell sockets should be parsed, and their signature
65 validated. See :ref:`wire_protocol` for how to do this.
66
67 The kernel will send messages on the iopub socket to display output, and on the
68 stdin socket to prompt the user for textual input.
69
70 .. seealso::
71
72 :doc:`messaging`
73 Details of the different sockets and the messages that come over them.
74
75
76 .. _kernelspecs:
77
78 Kernel specs
79 ============
80
81 A kernel identifies itself to IPython by creating a directory, the name of which
82 is used as an identifier for the kernel. These may be created in a number of
83 locations:
84
85 +--------+--------------------------------------+-----------------------------------+
86 | | Unix | Windows |
87 +========+======================================+===================================+
88 | System | ``/usr/share/ipython/kernels`` | ``%PROGRAMDATA%\ipython\kernels`` |
89 | | | |
90 | | ``/usr/local/share/ipython/kernels`` | |
91 +--------+--------------------------------------+-----------------------------------+
92 | User | ``~/.ipython/kernels`` |
93 +--------+--------------------------------------+-----------------------------------+
94
95 The user location takes priority over the system locations, and the case of the
96 names is ignored, so selecting kernels works the same way whether or not the
97 filesystem is case sensitive.
98
99 Inside the directory, the most important file is *kernel.json*. This should be a
100 JSON serialised dictionary containing the following keys and values:
101
102 - **argv**: A list of command line arguments used to start the kernel. The text
103 ``{connection_file}`` in any argument will be replaced with the path to the
104 connection file.
105 - **display_name**: The kernel's name as it should be displayed in the UI.
106 Unlike the kernel name used in the API, this can contain arbitrary unicode
107 characters.
108 - **language**: The programming language which this kernel runs. This will be
109 stored in notebook metadata. This may be used by syntax highlighters to guess
110 how to parse code in a notebook, and frontends may eventually use it to
111 identify alternative kernels that can run some code.
112 - **codemirror_mode** (optional): The `codemirror mode <http://codemirror.net/mode/index.html>`_
113 to use for code in this language. This can be a string or a dictionary, as
114 passed to codemirror config. The string from *language* will be used if this is
115 not provided.
116 - **env** (optional): A dictionary of environment variables to set for the kernel.
117 These will be added to the current environment variables before the kernel is
118 started.
119 - **help_links** (optional): A list of dictionaries, each with keys 'text' and
120 'url'. These will be displayed in the help menu in the notebook UI.
121
122 For example, the kernel.json file for IPython looks like this::
123
124 {
125 "argv": ["python3", "-c", "from IPython.kernel.zmq.kernelapp import main; main()",
126 "-f", "{connection_file}"],
127 "codemirror_mode": {
128 "version": 3,
129 "name": "ipython"
130 },
131 "display_name": "IPython (Python 3)",
132 "language": "python"
133 }
134
135 To see the available kernel specs, run::
136
137 ipython kernelspec list
138
139 To start the terminal console or the Qt console with a specific kernel::
140
141 ipython console --kernel bash
142 ipython qtconsole --kernel bash
143
144 To use different kernels in the notebook, select a different kernel from the
145 dropdown menu in the top-right of the UI.
@@ -1,1063 +1,1066 b''
1 1 .. _messaging:
2 2
3 3 ======================
4 4 Messaging in IPython
5 5 ======================
6 6
7 7
8 8 Versioning
9 9 ==========
10 10
11 11 The IPython message specification is versioned independently of IPython.
12 12 The current version of the specification is 5.0.
13 13
14 14
15 15 Introduction
16 16 ============
17 17
18 18 This document explains the basic communications design and messaging
19 19 specification for how the various IPython objects interact over a network
20 20 transport. The current implementation uses the ZeroMQ_ library for messaging
21 21 within and between hosts.
22 22
23 23 .. Note::
24 24
25 25 This document should be considered the authoritative description of the
26 26 IPython messaging protocol, and all developers are strongly encouraged to
27 27 keep it updated as the implementation evolves, so that we have a single
28 28 common reference for all protocol details.
29
29
30 30 The basic design is explained in the following diagram:
31 31
32 32 .. image:: figs/frontend-kernel.png
33 33 :width: 450px
34 34 :alt: IPython kernel/frontend messaging architecture.
35 35 :align: center
36 36 :target: ../_images/frontend-kernel.png
37 37
38 38 A single kernel can be simultaneously connected to one or more frontends. The
39 39 kernel has three sockets that serve the following functions:
40 40
41 41 1. Shell: this single ROUTER socket allows multiple incoming connections from
42 42 frontends, and this is the socket where requests for code execution, object
43 43 information, prompts, etc. are made to the kernel by any frontend. The
44 44 communication on this socket is a sequence of request/reply actions from
45 45 each frontend and the kernel.
46 46
47 47 2. IOPub: this socket is the 'broadcast channel' where the kernel publishes all
48 48 side effects (stdout, stderr, etc.) as well as the requests coming from any
49 49 client over the shell socket and its own requests on the stdin socket. There
50 50 are a number of actions in Python which generate side effects: :func:`print`
51 51 writes to ``sys.stdout``, errors generate tracebacks, etc. Additionally, in
52 52 a multi-client scenario, we want all frontends to be able to know what each
53 53 other has sent to the kernel (this can be useful in collaborative scenarios,
54 54 for example). This socket allows both side effects and the information
55 55 about communications taking place with one client over the shell channel
56 56 to be made available to all clients in a uniform manner.
57 57
58 58 3. stdin: this ROUTER socket is connected to all frontends, and it allows
59 59 the kernel to request input from the active frontend when :func:`raw_input` is called.
60 60 The frontend that executed the code has a DEALER socket that acts as a 'virtual keyboard'
61 61 for the kernel while this communication is happening (illustrated in the
62 62 figure by the black outline around the central keyboard). In practice,
63 63 frontends may display such kernel requests using a special input widget or
64 64 otherwise indicating that the user is to type input for the kernel instead
65 65 of normal commands in the frontend.
66 66
67 67 All messages are tagged with enough information (details below) for clients
68 68 to know which messages come from their own interaction with the kernel and
69 69 which ones are from other clients, so they can display each type
70 70 appropriately.
71 71
72 72 4. Control: This channel is identical to Shell, but operates on a separate socket,
73 73 to allow important messages to avoid queueing behind execution requests (e.g. shutdown or abort).
74 74
75 75 The actual format of the messages allowed on each of these channels is
76 76 specified below. Messages are dicts of dicts with string keys and values that
77 77 are reasonably representable in JSON. Our current implementation uses JSON
78 78 explicitly as its message format, but this shouldn't be considered a permanent
79 79 feature. As we've discovered that JSON has non-trivial performance issues due
80 80 to excessive copying, we may in the future move to a pure pickle-based raw
81 81 message format. However, it should be possible to easily convert from the raw
82 82 objects to JSON, since we may have non-python clients (e.g. a web frontend).
83 83 As long as it's easy to make a JSON version of the objects that is a faithful
84 84 representation of all the data, we can communicate with such clients.
85 85
86 86 .. Note::
87 87
88 88 Not all of these have yet been fully fleshed out, but the key ones are, see
89 89 kernel and frontend files for actual implementation details.
90 90
91 91 General Message Format
92 92 ======================
93 93
94 94 A message is defined by the following four-dictionary structure::
95 95
96 96 {
97 97 # The message header contains a pair of unique identifiers for the
98 98 # originating session and the actual message id, in addition to the
99 99 # username for the process that generated the message. This is useful in
100 100 # collaborative settings where multiple users may be interacting with the
101 101 # same kernel simultaneously, so that frontends can label the various
102 102 # messages in a meaningful way.
103 103 'header' : {
104 104 'msg_id' : uuid,
105 105 'username' : str,
106 106 'session' : uuid,
107 107 # All recognized message type strings are listed below.
108 108 'msg_type' : str,
109 109 # the message protocol version
110 110 'version' : '5.0',
111 111 },
112 112
113 113 # In a chain of messages, the header from the parent is copied so that
114 114 # clients can track where messages come from.
115 115 'parent_header' : dict,
116 116
117 117 # Any metadata associated with the message.
118 118 'metadata' : dict,
119 119
120 120 # The actual content of the message must be a dict, whose structure
121 121 # depends on the message type.
122 122 'content' : dict,
123 123 }
124 124
125 125 .. versionchanged:: 5.0
126 126
127 127 ``version`` key added to the header.
128 128
129 .. _wire_protocol:
130
129 131 The Wire Protocol
130 132 =================
131 133
132 134
133 135 This message format exists at a high level,
134 136 but does not describe the actual *implementation* at the wire level in zeromq.
135 137 The canonical implementation of the message spec is our :class:`~IPython.kernel.zmq.session.Session` class.
136 138
137 139 .. note::
138 140
139 141 This section should only be relevant to non-Python consumers of the protocol.
140 142 Python consumers should simply import and use IPython's own implementation of the wire protocol
141 143 in the :class:`IPython.kernel.zmq.session.Session` object.
142 144
143 145 Every message is serialized to a sequence of at least six blobs of bytes:
144 146
145 147 .. sourcecode:: python
146 148
147 149 [
148 150 b'u-u-i-d', # zmq identity(ies)
149 151 b'<IDS|MSG>', # delimiter
150 152 b'baddad42', # HMAC signature
151 153 b'{header}', # serialized header dict
152 154 b'{parent_header}', # serialized parent header dict
153 155 b'{metadata}', # serialized metadata dict
154 156 b'{content}, # serialized content dict
155 157 b'blob', # extra raw data buffer(s)
156 158 ...
157 159 ]
158 160
159 161 The front of the message is the ZeroMQ routing prefix,
160 162 which can be zero or more socket identities.
161 163 This is every piece of the message prior to the delimiter key ``<IDS|MSG>``.
162 164 In the case of IOPub, there should be just one prefix component,
163 165 which is the topic for IOPub subscribers, e.g. ``execute_result``, ``display_data``.
164 166
165 167 .. note::
166 168
167 169 In most cases, the IOPub topics are irrelevant and completely ignored,
168 170 because frontends just subscribe to all topics.
169 171 The convention used in the IPython kernel is to use the msg_type as the topic,
170 172 and possibly extra information about the message, e.g. ``execute_result`` or ``stream.stdout``
171 173
172 174 After the delimiter is the `HMAC`_ signature of the message, used for authentication.
173 175 If authentication is disabled, this should be an empty string.
174 176 By default, the hashing function used for computing these signatures is sha256.
175 177
176 178 .. _HMAC: http://en.wikipedia.org/wiki/HMAC
177 179
178 180 .. note::
179 181
180 182 To disable authentication and signature checking,
181 183 set the `key` field of a connection file to an empty string.
182 184
183 185 The signature is the HMAC hex digest of the concatenation of:
184 186
185 187 - A shared key (typically the ``key`` field of a connection file)
186 188 - The serialized header dict
187 189 - The serialized parent header dict
188 190 - The serialized metadata dict
189 191 - The serialized content dict
190 192
191 193 In Python, this is implemented via:
192 194
193 195 .. sourcecode:: python
194 196
195 197 # once:
196 198 digester = HMAC(key, digestmod=hashlib.sha256)
197 199
198 200 # for each message
199 201 d = digester.copy()
200 202 for serialized_dict in (header, parent, metadata, content):
201 203 d.update(serialized_dict)
202 204 signature = d.hexdigest()
203 205
204 206 After the signature is the actual message, always in four frames of bytes.
205 207 The four dictionaries that compose a message are serialized separately,
206 208 in the order of header, parent header, metadata, and content.
207 209 These can be serialized by any function that turns a dict into bytes.
208 210 The default and most common serialization is JSON, but msgpack and pickle
209 211 are common alternatives.
210 212
211 213 After the serialized dicts are zero to many raw data buffers,
212 214 which can be used by message types that support binary data (mainly apply and data_pub).
213 215
214 216
215 217 Python functional API
216 218 =====================
217 219
218 220 As messages are dicts, they map naturally to a ``func(**kw)`` call form. We
219 221 should develop, at a few key points, functional forms of all the requests that
220 222 take arguments in this manner and automatically construct the necessary dict
221 223 for sending.
222 224
223 225 In addition, the Python implementation of the message specification extends
224 226 messages upon deserialization to the following form for convenience::
225 227
226 228 {
227 229 'header' : dict,
228 230 # The msg's unique identifier and type are always stored in the header,
229 231 # but the Python implementation copies them to the top level.
230 232 'msg_id' : uuid,
231 233 'msg_type' : str,
232 234 'parent_header' : dict,
233 235 'content' : dict,
234 236 'metadata' : dict,
235 237 }
236 238
237 239 All messages sent to or received by any IPython process should have this
238 240 extended structure.
239 241
240 242
241 243 Messages on the shell ROUTER/DEALER sockets
242 244 ===========================================
243 245
244 246 .. _execute:
245 247
246 248 Execute
247 249 -------
248 250
249 251 This message type is used by frontends to ask the kernel to execute code on
250 252 behalf of the user, in a namespace reserved to the user's variables (and thus
251 253 separate from the kernel's own internal code and variables).
252 254
253 255 Message type: ``execute_request``::
254 256
255 257 content = {
256 258 # Source code to be executed by the kernel, one or more lines.
257 259 'code' : str,
258 260
259 261 # A boolean flag which, if True, signals the kernel to execute
260 262 # this code as quietly as possible.
261 263 # silent=True forces store_history to be False,
262 264 # and will *not*:
263 265 # - broadcast output on the IOPUB channel
264 266 # - have an execute_result
265 267 # The default is False.
266 268 'silent' : bool,
267 269
268 270 # A boolean flag which, if True, signals the kernel to populate history
269 271 # The default is True if silent is False. If silent is True, store_history
270 272 # is forced to be False.
271 273 'store_history' : bool,
272 274
273 275 # A dict mapping names to expressions to be evaluated in the
274 276 # user's dict. The rich display-data representation of each will be evaluated after execution.
275 277 # See the display_data content for the structure of the representation data.
276 278 'user_expressions' : dict,
277 279
278 280 # Some frontends do not support stdin requests.
279 281 # If raw_input is called from code executed from such a frontend,
280 282 # a StdinNotImplementedError will be raised.
281 283 'allow_stdin' : True,
282 284 }
283 285
284 286 .. versionchanged:: 5.0
285 287
286 288 ``user_variables`` removed, because it is redundant with user_expressions.
287 289
288 290 The ``code`` field contains a single string (possibly multiline) to be executed.
289 291
290 292 The ``user_expressions`` field deserves a detailed explanation. In the past, IPython had
291 293 the notion of a prompt string that allowed arbitrary code to be evaluated, and
292 294 this was put to good use by many in creating prompts that displayed system
293 295 status, path information, and even more esoteric uses like remote instrument
294 296 status acquired over the network. But now that IPython has a clean separation
295 297 between the kernel and the clients, the kernel has no prompt knowledge; prompts
296 298 are a frontend feature, and it should be even possible for different
297 299 frontends to display different prompts while interacting with the same kernel.
298 300 ``user_expressions`` can be used to retrieve this information.
299 301
300 302 Any error in evaluating any expression in ``user_expressions`` will result in
301 303 only that key containing a standard error message, of the form::
302 304
303 305 {
304 306 'status' : 'error',
305 307 'ename' : 'NameError',
306 308 'evalue' : 'foo',
307 309 'traceback' : ...
308 310 }
309 311
310 312 .. Note::
311 313
312 314 In order to obtain the current execution counter for the purposes of
313 315 displaying input prompts, frontends may make an execution request with an
314 316 empty code string and ``silent=True``.
315 317
316 318 Upon completion of the execution request, the kernel *always* sends a reply,
317 319 with a status code indicating what happened and additional data depending on
318 320 the outcome. See :ref:`below <execution_results>` for the possible return
319 321 codes and associated data.
320 322
321 323 .. seealso::
322 324
323 325 :ref:`execution_semantics`
324 326
325 327 .. _execution_counter:
326 328
327 329 Execution counter (prompt number)
328 330 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
329 331
330 332 The kernel should have a single, monotonically increasing counter of all execution
331 333 requests that are made with ``store_history=True``. This counter is used to populate
332 334 the ``In[n]`` and ``Out[n]`` prompts. The value of this counter will be returned as the
333 335 ``execution_count`` field of all ``execute_reply`` and ``execute_input`` messages.
334 336
335 337 .. _execution_results:
336 338
337 339 Execution results
338 340 ~~~~~~~~~~~~~~~~~
339 341
340 342 Message type: ``execute_reply``::
341 343
342 344 content = {
343 345 # One of: 'ok' OR 'error' OR 'abort'
344 346 'status' : str,
345 347
346 348 # The global kernel counter that increases by one with each request that
347 349 # stores history. This will typically be used by clients to display
348 350 # prompt numbers to the user. If the request did not store history, this will
349 351 # be the current value of the counter in the kernel.
350 352 'execution_count' : int,
351 353 }
352 354
353 355 When status is 'ok', the following extra fields are present::
354 356
355 357 {
356 358 # 'payload' will be a list of payload dicts.
357 359 # Each execution payload is a dict with string keys that may have been
358 360 # produced by the code being executed. It is retrieved by the kernel at
359 361 # the end of the execution and sent back to the front end, which can take
360 362 # action on it as needed.
361 363 # The only requirement of each payload dict is that it have a 'source' key,
362 364 # which is a string classifying the payload (e.g. 'pager').
363 365 'payload' : list(dict),
364 366
365 367 # Results for the user_expressions.
366 368 'user_expressions' : dict,
367 369 }
368 370
369 371 .. versionchanged:: 5.0
370 372
371 373 ``user_variables`` is removed, use user_expressions instead.
372 374
373 375 .. admonition:: Execution payloads
374 376
375 377 The notion of an 'execution payload' is different from a return value of a
376 378 given set of code, which normally is just displayed on the execute_result stream
377 379 through the PUB socket. The idea of a payload is to allow special types of
378 380 code, typically magics, to populate a data container in the IPython kernel
379 381 that will be shipped back to the caller via this channel. The kernel
380 382 has an API for this in the PayloadManager::
381 383
382 384 ip.payload_manager.write_payload(payload_dict)
383 385
384 386 which appends a dictionary to the list of payloads.
385 387
386 388 The payload API is not yet stabilized,
387 389 and should probably not be supported by non-Python kernels at this time.
388 390 In such cases, the payload list should always be empty.
389 391
390 392
391 393 When status is 'error', the following extra fields are present::
392 394
393 395 {
394 396 'ename' : str, # Exception name, as a string
395 397 'evalue' : str, # Exception value, as a string
396 398
397 399 # The traceback will contain a list of frames, represented each as a
398 400 # string. For now we'll stick to the existing design of ultraTB, which
399 401 # controls exception level of detail statefully. But eventually we'll
400 402 # want to grow into a model where more information is collected and
401 403 # packed into the traceback object, with clients deciding how little or
402 404 # how much of it to unpack. But for now, let's start with a simple list
403 405 # of strings, since that requires only minimal changes to ultratb as
404 406 # written.
405 407 'traceback' : list,
406 408 }
407 409
408 410
409 411 When status is 'abort', there are for now no additional data fields. This
410 412 happens when the kernel was interrupted by a signal.
411 413
412 414 .. _msging_inspection:
413 415
414 416 Introspection
415 417 -------------
416 418
417 419 Code can be inspected to show useful information to the user.
418 420 It is up to the Kernel to decide what information should be displayed, and its formatting.
419 421
420 422 Message type: ``inspect_request``::
421 423
422 424 content = {
423 425 # The code context in which introspection is requested
424 426 # this may be up to an entire multiline cell.
425 427 'code' : str,
426 428
427 429 # The cursor position within 'code' (in unicode characters) where inspection is requested
428 430 'cursor_pos' : int,
429 431
430 432 # The level of detail desired. In IPython, the default (0) is equivalent to typing
431 433 # 'x?' at the prompt, 1 is equivalent to 'x??'.
432 434 # The difference is up to kernels, but in IPython level 1 includes the source code
433 435 # if available.
434 436 'detail_level' : 0 or 1,
435 437 }
436 438
437 439 .. versionchanged:: 5.0
438 440
439 441 ``object_info_request`` renamed to ``inspect_request``.
440 442
441 443 .. versionchanged:: 5.0
442 444
443 445 ``name`` key replaced with ``code`` and ``cursor_pos``,
444 446 moving the lexing responsibility to the kernel.
445 447
446 448 The reply is a mime-bundle, like a `display_data`_ message,
447 449 which should be a formatted representation of information about the context.
448 450 In the notebook, this is used to show tooltips over function calls, etc.
449 451
450 452 Message type: ``inspect_reply``::
451 453
452 454 content = {
453 455 # 'ok' if the request succeeded or 'error', with error information as in all other replies.
454 456 'status' : 'ok',
455 457
456 458 # data can be empty if nothing is found
457 459 'data' : dict,
458 460 'metadata' : dict,
459 461 }
460 462
461 463 .. versionchanged:: 5.0
462 464
463 465 ``object_info_reply`` renamed to ``inspect_reply``.
464 466
465 467 .. versionchanged:: 5.0
466 468
467 469 Reply is changed from structured data to a mime bundle, allowing formatting decisions to be made by the kernel.
468 470
469 471 .. _msging_completion:
470 472
471 473 Completion
472 474 ----------
473 475
474 476 Message type: ``complete_request``::
475 477
476 478 content = {
477 479 # The code context in which completion is requested
478 480 # this may be up to an entire multiline cell, such as
479 481 # 'foo = a.isal'
480 482 'code' : str,
481 483
482 484 # The cursor position within 'code' (in unicode characters) where completion is requested
483 485 'cursor_pos' : int,
484 486 }
485 487
486 488 .. versionchanged:: 5.0
487 489
488 490 ``line``, ``block``, and ``text`` keys are removed in favor of a single ``code`` for context.
489 491 Lexing is up to the kernel.
490 492
491 493
492 494 Message type: ``complete_reply``::
493 495
494 496 content = {
495 497 # The list of all matches to the completion request, such as
496 498 # ['a.isalnum', 'a.isalpha'] for the above example.
497 499 'matches' : list,
498 500
499 501 # The range of text that should be replaced by the above matches when a completion is accepted.
500 502 # typically cursor_end is the same as cursor_pos in the request.
501 503 'cursor_start' : int,
502 504 'cursor_end' : int,
503 505
504 506 # Information that frontend plugins might use for extra display information about completions.
505 507 'metadata' : dict,
506 508
507 509 # status should be 'ok' unless an exception was raised during the request,
508 510 # in which case it should be 'error', along with the usual error message content
509 511 # in other messages.
510 512 'status' : 'ok'
511 513 }
512 514
513 515 .. versionchanged:: 5.0
514 516
515 517 - ``matched_text`` is removed in favor of ``cursor_start`` and ``cursor_end``.
516 518 - ``metadata`` is added for extended information.
517 519
518 520 .. _msging_history:
519 521
520 522 History
521 523 -------
522 524
523 525 For clients to explicitly request history from a kernel. The kernel has all
524 526 the actual execution history stored in a single location, so clients can
525 527 request it from the kernel when needed.
526 528
527 529 Message type: ``history_request``::
528 530
529 531 content = {
530 532
531 533 # If True, also return output history in the resulting dict.
532 534 'output' : bool,
533 535
534 536 # If True, return the raw input history, else the transformed input.
535 537 'raw' : bool,
536 538
537 539 # So far, this can be 'range', 'tail' or 'search'.
538 540 'hist_access_type' : str,
539 541
540 542 # If hist_access_type is 'range', get a range of input cells. session can
541 543 # be a positive session number, or a negative number to count back from
542 544 # the current session.
543 545 'session' : int,
544 546 # start and stop are line numbers within that session.
545 547 'start' : int,
546 548 'stop' : int,
547 549
548 550 # If hist_access_type is 'tail' or 'search', get the last n cells.
549 551 'n' : int,
550 552
551 553 # If hist_access_type is 'search', get cells matching the specified glob
552 554 # pattern (with * and ? as wildcards).
553 555 'pattern' : str,
554 556
555 557 # If hist_access_type is 'search' and unique is true, do not
556 558 # include duplicated history. Default is false.
557 559 'unique' : bool,
558 560
559 561 }
560 562
561 563 .. versionadded:: 4.0
562 564 The key ``unique`` for ``history_request``.
563 565
564 566 Message type: ``history_reply``::
565 567
566 568 content = {
567 569 # A list of 3 tuples, either:
568 570 # (session, line_number, input) or
569 571 # (session, line_number, (input, output)),
570 572 # depending on whether output was False or True, respectively.
571 573 'history' : list,
572 574 }
573 575
574 576
575 577 Connect
576 578 -------
577 579
578 580 When a client connects to the request/reply socket of the kernel, it can issue
579 581 a connect request to get basic information about the kernel, such as the ports
580 582 the other ZeroMQ sockets are listening on. This allows clients to only have
581 583 to know about a single port (the shell channel) to connect to a kernel.
582 584
583 585 Message type: ``connect_request``::
584 586
585 587 content = {
586 588 }
587 589
588 590 Message type: ``connect_reply``::
589 591
590 592 content = {
591 593 'shell_port' : int, # The port the shell ROUTER socket is listening on.
592 594 'iopub_port' : int, # The port the PUB socket is listening on.
593 595 'stdin_port' : int, # The port the stdin ROUTER socket is listening on.
594 596 'hb_port' : int, # The port the heartbeat socket is listening on.
595 597 }
596 598
597 599 .. _msging_kernel_info:
598 600
599 601 Kernel info
600 602 -----------
601 603
602 604 If a client needs to know information about the kernel, it can
603 605 make a request of the kernel's information.
604 606 This message can be used to fetch core information of the
605 607 kernel, including language (e.g., Python), language version number and
606 608 IPython version number, and the IPython message spec version number.
607 609
608 610 Message type: ``kernel_info_request``::
609 611
610 612 content = {
611 613 }
612 614
613 615 Message type: ``kernel_info_reply``::
614 616
615 617 content = {
616 618 # Version of messaging protocol.
617 619 # The first integer indicates major version. It is incremented when
618 620 # there is any backward incompatible change.
619 621 # The second integer indicates minor version. It is incremented when
620 622 # there is any backward compatible change.
621 623 'protocol_version': 'X.Y.Z',
622 624
623 625 # The kernel implementation name
624 626 # (e.g. 'ipython' for the IPython kernel)
625 627 'implementation': str,
626 628
627 629 # Implementation version number.
628 630 # The version number of the kernel's implementation
629 631 # (e.g. IPython.__version__ for the IPython kernel)
630 632 'implementation_version': 'X.Y.Z',
631 633
632 634 # Programming language in which kernel is implemented.
633 635 # Kernel included in IPython returns 'python'.
634 636 'language': str,
635 637
636 638 # Language version number.
637 639 # It is Python version number (e.g., '2.7.3') for the kernel
638 640 # included in IPython.
639 641 'language_version': 'X.Y.Z',
640 642
641 643 # A banner of information about the kernel,
642 644 # which may be desplayed in console environments.
643 645 'banner' : str,
644 646 }
645 647
646 648 .. versionchanged:: 5.0
647 649
648 650 Versions changed from lists of integers to strings.
649 651
650 652 .. versionchanged:: 5.0
651 653
652 654 ``ipython_version`` is removed.
653 655
654 656 .. versionchanged:: 5.0
655 657
656 658 ``implementation``, ``implementation_version``, and ``banner`` keys are added.
657 659
658 660 .. _msging_shutdown:
659 661
660 662 Kernel shutdown
661 663 ---------------
662 664
663 665 The clients can request the kernel to shut itself down; this is used in
664 666 multiple cases:
665 667
666 668 - when the user chooses to close the client application via a menu or window
667 669 control.
668 670 - when the user types 'exit' or 'quit' (or their uppercase magic equivalents).
669 671 - when the user chooses a GUI method (like the 'Ctrl-C' shortcut in the
670 672 IPythonQt client) to force a kernel restart to get a clean kernel without
671 673 losing client-side state like history or inlined figures.
672 674
673 675 The client sends a shutdown request to the kernel, and once it receives the
674 676 reply message (which is otherwise empty), it can assume that the kernel has
675 677 completed shutdown safely.
676 678
677 679 Upon their own shutdown, client applications will typically execute a last
678 680 minute sanity check and forcefully terminate any kernel that is still alive, to
679 681 avoid leaving stray processes in the user's machine.
680 682
681 683 Message type: ``shutdown_request``::
682 684
683 685 content = {
684 686 'restart' : bool # whether the shutdown is final, or precedes a restart
685 687 }
686 688
687 689 Message type: ``shutdown_reply``::
688 690
689 691 content = {
690 692 'restart' : bool # whether the shutdown is final, or precedes a restart
691 693 }
692 694
693 695 .. Note::
694 696
695 697 When the clients detect a dead kernel thanks to inactivity on the heartbeat
696 698 socket, they simply send a forceful process termination signal, since a dead
697 699 process is unlikely to respond in any useful way to messages.
698 700
699 701
700 702 Messages on the PUB/SUB socket
701 703 ==============================
702 704
703 705 Streams (stdout, stderr, etc)
704 706 ------------------------------
705 707
706 708 Message type: ``stream``::
707 709
708 710 content = {
709 711 # The name of the stream is one of 'stdout', 'stderr'
710 712 'name' : str,
711 713
712 714 # The data is an arbitrary string to be written to that stream
713 715 'data' : str,
714 716 }
715 717
716 718 Display Data
717 719 ------------
718 720
719 721 This type of message is used to bring back data that should be displayed (text,
720 722 html, svg, etc.) in the frontends. This data is published to all frontends.
721 723 Each message can have multiple representations of the data; it is up to the
722 724 frontend to decide which to use and how. A single message should contain all
723 725 possible representations of the same information. Each representation should
724 726 be a JSON'able data structure, and should be a valid MIME type.
725 727
726 728 Some questions remain about this design:
727 729
728 730 * Do we use this message type for execute_result/displayhook? Probably not, because
729 731 the displayhook also has to handle the Out prompt display. On the other hand
730 732 we could put that information into the metadata section.
731 733
732 734 .. _display_data:
733 735
734 736 Message type: ``display_data``::
735 737
736 738 content = {
737 739
738 740 # Who create the data
739 741 'source' : str,
740 742
741 743 # The data dict contains key/value pairs, where the keys are MIME
742 744 # types and the values are the raw data of the representation in that
743 745 # format.
744 746 'data' : dict,
745 747
746 748 # Any metadata that describes the data
747 749 'metadata' : dict
748 750 }
749 751
750 752
751 753 The ``metadata`` contains any metadata that describes the output.
752 754 Global keys are assumed to apply to the output as a whole.
753 755 The ``metadata`` dict can also contain mime-type keys, which will be sub-dictionaries,
754 756 which are interpreted as applying only to output of that type.
755 757 Third parties should put any data they write into a single dict
756 758 with a reasonably unique name to avoid conflicts.
757 759
758 760 The only metadata keys currently defined in IPython are the width and height
759 761 of images::
760 762
761 763 metadata = {
762 764 'image/png' : {
763 765 'width': 640,
764 766 'height': 480
765 767 }
766 768 }
767 769
768 770
769 771 .. versionchanged:: 5.0
770 772
771 773 `application/json` data should be unpacked JSON data,
772 774 not double-serialized as a JSON string.
773 775
774 776
775 777 Raw Data Publication
776 778 --------------------
777 779
778 780 ``display_data`` lets you publish *representations* of data, such as images and html.
779 781 This ``data_pub`` message lets you publish *actual raw data*, sent via message buffers.
780 782
781 783 data_pub messages are constructed via the :func:`IPython.lib.datapub.publish_data` function:
782 784
783 785 .. sourcecode:: python
784 786
785 787 from IPython.kernel.zmq.datapub import publish_data
786 788 ns = dict(x=my_array)
787 789 publish_data(ns)
788 790
789 791
790 792 Message type: ``data_pub``::
791 793
792 794 content = {
793 795 # the keys of the data dict, after it has been unserialized
794 796 'keys' : ['a', 'b']
795 797 }
796 798 # the namespace dict will be serialized in the message buffers,
797 799 # which will have a length of at least one
798 800 buffers = [b'pdict', ...]
799 801
800 802
801 803 The interpretation of a sequence of data_pub messages for a given parent request should be
802 804 to update a single namespace with subsequent results.
803 805
804 806 .. note::
805 807
806 808 No frontends directly handle data_pub messages at this time.
807 809 It is currently only used by the client/engines in :mod:`IPython.parallel`,
808 810 where engines may publish *data* to the Client,
809 811 of which the Client can then publish *representations* via ``display_data``
810 812 to various frontends.
811 813
812 814 Code inputs
813 815 -----------
814 816
815 817 To let all frontends know what code is being executed at any given time, these
816 818 messages contain a re-broadcast of the ``code`` portion of an
817 819 :ref:`execute_request <execute>`, along with the :ref:`execution_count
818 820 <execution_counter>`.
819 821
820 822 Message type: ``execute_input``::
821 823
822 824 content = {
823 825 'code' : str, # Source code to be executed, one or more lines
824 826
825 827 # The counter for this execution is also provided so that clients can
826 828 # display it, since IPython automatically creates variables called _iN
827 829 # (for input prompt In[N]).
828 830 'execution_count' : int
829 831 }
830 832
831 833 .. versionchanged:: 5.0
832 834
833 835 ``pyin`` is renamed to ``execute_input``.
834 836
835 837
836 838 Execution results
837 839 -----------------
838 840
839 841 Results of an execution are published as an ``execute_result``.
840 842 These are identical to `display_data`_ messages, with the addition of an ``execution_count`` key.
841 843
842 844 Results can have multiple simultaneous formats depending on its
843 845 configuration. A plain text representation should always be provided
844 846 in the ``text/plain`` mime-type. Frontends are free to display any or all of these
845 847 according to its capabilities.
846 848 Frontends should ignore mime-types they do not understand. The data itself is
847 849 any JSON object and depends on the format. It is often, but not always a string.
848 850
849 851 Message type: ``execute_result``::
850 852
851 853 content = {
852 854
853 855 # The counter for this execution is also provided so that clients can
854 856 # display it, since IPython automatically creates variables called _N
855 857 # (for prompt N).
856 858 'execution_count' : int,
857 859
858 860 # data and metadata are identical to a display_data message.
859 861 # the object being displayed is that passed to the display hook,
860 862 # i.e. the *result* of the execution.
861 863 'data' : dict,
862 864 'metadata' : dict,
863 865 }
864 866
865 867 Execution errors
866 868 ----------------
867 869
868 870 When an error occurs during code execution
869 871
870 872 Message type: ``error``::
871 873
872 874 content = {
873 875 # Similar content to the execute_reply messages for the 'error' case,
874 876 # except the 'status' field is omitted.
875 877 }
876 878
877 879 .. versionchanged:: 5.0
878 880
879 881 ``pyerr`` renamed to ``error``
880 882
881 883 Kernel status
882 884 -------------
883 885
884 886 This message type is used by frontends to monitor the status of the kernel.
885 887
886 888 Message type: ``status``::
887 889
888 890 content = {
889 891 # When the kernel starts to handle a message, it will enter the 'busy'
890 892 # state and when it finishes, it will enter the 'idle' state.
891 893 # The kernel will publish state 'starting' exactly once at process startup.
892 894 execution_state : ('busy', 'idle', 'starting')
893 895 }
894 896
895 897 .. versionchanged:: 5.0
896 898
897 899 Busy and idle messages should be sent before/after handling every message,
898 900 not just execution.
899 901
900 902 Clear output
901 903 ------------
902 904
903 905 This message type is used to clear the output that is visible on the frontend.
904 906
905 907 Message type: ``clear_output``::
906 908
907 909 content = {
908 910
909 911 # Wait to clear the output until new output is available. Clears the
910 912 # existing output immediately before the new output is displayed.
911 913 # Useful for creating simple animations with minimal flickering.
912 914 'wait' : bool,
913 915 }
914 916
915 917 .. versionchanged:: 4.1
916 918
917 919 ``stdout``, ``stderr``, and ``display`` boolean keys for selective clearing are removed,
918 920 and ``wait`` is added.
919 921 The selective clearing keys are ignored in v4 and the default behavior remains the same,
920 922 so v4 clear_output messages will be safely handled by a v4.1 frontend.
921 923
922 924
923 925 Messages on the stdin ROUTER/DEALER sockets
924 926 ===========================================
925 927
926 928 This is a socket where the request/reply pattern goes in the opposite direction:
927 929 from the kernel to a *single* frontend, and its purpose is to allow
928 930 ``raw_input`` and similar operations that read from ``sys.stdin`` on the kernel
929 931 to be fulfilled by the client. The request should be made to the frontend that
930 932 made the execution request that prompted ``raw_input`` to be called. For now we
931 933 will keep these messages as simple as possible, since they only mean to convey
932 934 the ``raw_input(prompt)`` call.
933 935
934 936 Message type: ``input_request``::
935 937
936 938 content = {
937 939 # the text to show at the prompt
938 940 'prompt' : str,
939 941 # Is the request for a password?
940 942 # If so, the frontend shouldn't echo input.
941 943 'password' : bool
942 944 }
943 945
944 946 Message type: ``input_reply``::
945 947
946 948 content = { 'value' : str }
947 949
948 950
949 951 When ``password`` is True, the frontend should not echo the input as it is entered.
950 952
951 953 .. versionchanged:: 5.0
952 954
953 955 ``password`` key added.
954 956
955 957 .. note::
956 958
957 959 The stdin socket of the client is required to have the same zmq IDENTITY
958 960 as the client's shell socket.
959 961 Because of this, the ``input_request`` must be sent with the same IDENTITY
960 962 routing prefix as the ``execute_reply`` in order for the frontend to receive
961 963 the message.
962 964
963 965 .. note::
964 966
965 967 We do not explicitly try to forward the raw ``sys.stdin`` object, because in
966 968 practice the kernel should behave like an interactive program. When a
967 969 program is opened on the console, the keyboard effectively takes over the
968 970 ``stdin`` file descriptor, and it can't be used for raw reading anymore.
969 971 Since the IPython kernel effectively behaves like a console program (albeit
970 972 one whose "keyboard" is actually living in a separate process and
971 973 transported over the zmq connection), raw ``stdin`` isn't expected to be
972 974 available.
973 975
976 .. _kernel_heartbeat:
974 977
975 978 Heartbeat for kernels
976 979 =====================
977 980
978 981 Clients send ping messages on a REQ socket, which are echoed right back
979 982 from the Kernel's REP socket. These are simple bytestrings, not full JSON messages described above.
980 983
981 984
982 985 Custom Messages
983 986 ===============
984 987
985 988 .. versionadded:: 4.1
986 989
987 990 IPython 2.0 (msgspec v4.1) adds a messaging system for developers to add their own objects with Frontend
988 991 and Kernel-side components, and allow them to communicate with each other.
989 992 To do this, IPython adds a notion of a ``Comm``, which exists on both sides,
990 993 and can communicate in either direction.
991 994
992 995 These messages are fully symmetrical - both the Kernel and the Frontend can send each message,
993 996 and no messages expect a reply.
994 997 The Kernel listens for these messages on the Shell channel,
995 998 and the Frontend listens for them on the IOPub channel.
996 999
997 1000 Opening a Comm
998 1001 --------------
999 1002
1000 1003 Opening a Comm produces a ``comm_open`` message, to be sent to the other side::
1001 1004
1002 1005 {
1003 1006 'comm_id' : 'u-u-i-d',
1004 1007 'target_name' : 'my_comm',
1005 1008 'data' : {}
1006 1009 }
1007 1010
1008 1011 Every Comm has an ID and a target name.
1009 1012 The code handling the message on the receiving side is responsible for maintaining a mapping
1010 1013 of target_name keys to constructors.
1011 1014 After a ``comm_open`` message has been sent,
1012 1015 there should be a corresponding Comm instance on both sides.
1013 1016 The ``data`` key is always a dict and can be any extra JSON information used in initialization of the comm.
1014 1017
1015 1018 If the ``target_name`` key is not found on the receiving side,
1016 1019 then it should immediately reply with a ``comm_close`` message to avoid an inconsistent state.
1017 1020
1018 1021 Comm Messages
1019 1022 -------------
1020 1023
1021 1024 Comm messages are one-way communications to update comm state,
1022 1025 used for synchronizing widget state, or simply requesting actions of a comm's counterpart.
1023 1026
1024 1027 Essentially, each comm pair defines their own message specification implemented inside the ``data`` dict.
1025 1028
1026 1029 There are no expected replies (of course, one side can send another ``comm_msg`` in reply).
1027 1030
1028 1031 Message type: ``comm_msg``::
1029 1032
1030 1033 {
1031 1034 'comm_id' : 'u-u-i-d',
1032 1035 'data' : {}
1033 1036 }
1034 1037
1035 1038 Tearing Down Comms
1036 1039 ------------------
1037 1040
1038 1041 Since comms live on both sides, when a comm is destroyed the other side must be notified.
1039 1042 This is done with a ``comm_close`` message.
1040 1043
1041 1044 Message type: ``comm_close``::
1042 1045
1043 1046 {
1044 1047 'comm_id' : 'u-u-i-d',
1045 1048 'data' : {}
1046 1049 }
1047 1050
1048 1051 Output Side Effects
1049 1052 -------------------
1050 1053
1051 1054 Since comm messages can execute arbitrary user code,
1052 1055 handlers should set the parent header and publish status busy / idle,
1053 1056 just like an execute request.
1054 1057
1055 1058
1056 1059 To Do
1057 1060 =====
1058 1061
1059 1062 Missing things include:
1060 1063
1061 1064 * Important: finish thinking through the payload concept and API.
1062 1065
1063 1066 .. include:: ../links.txt
General Comments 0
You need to be logged in to leave comments. Login now