##// END OF EJS Templates
Update messaging spec.
Fernando Perez -
Show More
@@ -1,580 +1,590 b''
1 .. _messaging:
1 .. _messaging:
2
2
3 ======================
3 ======================
4 Messaging in IPython
4 Messaging in IPython
5 ======================
5 ======================
6
6
7
7
8 Introduction
8 Introduction
9 ============
9 ============
10
10
11 This document explains the basic communications design and messaging
11 This document explains the basic communications design and messaging
12 specification for how the various IPython objects interact over a network
12 specification for how the various IPython objects interact over a network
13 transport. The current implementation uses the ZeroMQ_ library for messaging
13 transport. The current implementation uses the ZeroMQ_ library for messaging
14 within and between hosts.
14 within and between hosts.
15
15
16 .. Note::
16 .. Note::
17
17
18 This document should be considered the authoritative description of the
18 This document should be considered the authoritative description of the
19 IPython messaging protocol, and all developers are strongly encouraged to
19 IPython messaging protocol, and all developers are strongly encouraged to
20 keep it updated as the implementation evolves, so that we have a single
20 keep it updated as the implementation evolves, so that we have a single
21 common reference for all protocol details.
21 common reference for all protocol details.
22
22
23 The basic design is explained in the following diagram:
23 The basic design is explained in the following diagram:
24
24
25 .. image:: frontend-kernel.png
25 .. image:: frontend-kernel.png
26 :width: 450px
26 :width: 450px
27 :alt: IPython kernel/frontend messaging architecture.
27 :alt: IPython kernel/frontend messaging architecture.
28 :align: center
28 :align: center
29 :target: ../_images/frontend-kernel.png
29 :target: ../_images/frontend-kernel.png
30
30
31 A single kernel can be simultaneously connected to one or more frontends. The
31 A single kernel can be simultaneously connected to one or more frontends. The
32 kernel has three sockets that serve the following functions:
32 kernel has three sockets that serve the following functions:
33
33
34 1. REQ: this socket is connected to a *single* frontend at a time, and it allows
34 1. REQ: this socket is connected to a *single* frontend at a time, and it allows
35 the kernel to request input from a frontend when :func:`raw_input` is called.
35 the kernel to request input from a frontend when :func:`raw_input` is called.
36 The frontend holding the matching REP socket acts as a 'virtual keyboard'
36 The frontend holding the matching REP socket acts as a 'virtual keyboard'
37 for the kernel while this communication is happening (illustrated in the
37 for the kernel while this communication is happening (illustrated in the
38 figure by the black outline around the central keyboard). In practice,
38 figure by the black outline around the central keyboard). In practice,
39 frontends may display such kernel requests using a special input widget or
39 frontends may display such kernel requests using a special input widget or
40 otherwise indicating that the user is to type input for the kernel instead
40 otherwise indicating that the user is to type input for the kernel instead
41 of normal commands in the frontend.
41 of normal commands in the frontend.
42
42
43 2. XREP: this single sockets allows multiple incoming connections from
43 2. XREP: this single sockets allows multiple incoming connections from
44 frontends, and this is the socket where requests for code execution, object
44 frontends, and this is the socket where requests for code execution, object
45 information, prompts, etc. are made to the kernel by any frontend. The
45 information, prompts, etc. are made to the kernel by any frontend. The
46 communication on this socket is a sequence of request/reply actions from
46 communication on this socket is a sequence of request/reply actions from
47 each frontend and the kernel.
47 each frontend and the kernel.
48
48
49 3. PUB: this socket is the 'broadcast channel' where the kernel publishes all
49 3. PUB: this socket is the 'broadcast channel' where the kernel publishes all
50 side effects (stdout, stderr, etc.) as well as the requests coming from any
50 side effects (stdout, stderr, etc.) as well as the requests coming from any
51 client over the XREP socket and its own requests on the REP socket. There
51 client over the XREP socket and its own requests on the REP socket. There
52 are a number of actions in Python which generate side effects: :func:`print`
52 are a number of actions in Python which generate side effects: :func:`print`
53 writes to ``sys.stdout``, errors generate tracebacks, etc. Additionally, in
53 writes to ``sys.stdout``, errors generate tracebacks, etc. Additionally, in
54 a multi-client scenario, we want all frontends to be able to know what each
54 a multi-client scenario, we want all frontends to be able to know what each
55 other has sent to the kernel (this can be useful in collaborative scenarios,
55 other has sent to the kernel (this can be useful in collaborative scenarios,
56 for example). This socket allows both side effects and the information
56 for example). This socket allows both side effects and the information
57 about communications taking place with one client over the XREQ/XREP channel
57 about communications taking place with one client over the XREQ/XREP channel
58 to be made available to all clients in a uniform manner.
58 to be made available to all clients in a uniform manner.
59
59
60 All messages are tagged with enough information (details below) for clients
60 All messages are tagged with enough information (details below) for clients
61 to know which messages come from their own interaction with the kernel and
61 to know which messages come from their own interaction with the kernel and
62 which ones are from other clients, so they can display each type
62 which ones are from other clients, so they can display each type
63 appropriately.
63 appropriately.
64
64
65 The actual format of the messages allowed on each of these channels is
65 The actual format of the messages allowed on each of these channels is
66 specified below. Messages are dicts of dicts with string keys and values that
66 specified below. Messages are dicts of dicts with string keys and values that
67 are reasonably representable in JSON. Our current implementation uses JSON
67 are reasonably representable in JSON. Our current implementation uses JSON
68 explicitly as its message format, but this shouldn't be considered a permanent
68 explicitly as its message format, but this shouldn't be considered a permanent
69 feature. As we've discovered that JSON has non-trivial performance issues due
69 feature. As we've discovered that JSON has non-trivial performance issues due
70 to excessive copying, we may in the future move to a pure pickle-based raw
70 to excessive copying, we may in the future move to a pure pickle-based raw
71 message format. However, it should be possible to easily convert from the raw
71 message format. However, it should be possible to easily convert from the raw
72 objects to JSON, since we may have non-python clients (e.g. a web frontend).
72 objects to JSON, since we may have non-python clients (e.g. a web frontend).
73 As long as it's easy to make a JSON version of the objects that is a faithful
73 As long as it's easy to make a JSON version of the objects that is a faithful
74 representation of all the data, we can communicate with such clients.
74 representation of all the data, we can communicate with such clients.
75
75
76 .. Note::
76 .. Note::
77
77
78 Not all of these have yet been fully fleshed out, but the key ones are, see
78 Not all of these have yet been fully fleshed out, but the key ones are, see
79 kernel and frontend files for actual implementation details.
79 kernel and frontend files for actual implementation details.
80
80
81
81
82 Python functional API
82 Python functional API
83 =====================
83 =====================
84
84
85 As messages are dicts, they map naturally to a ``func(**kw)`` call form. We
85 As messages are dicts, they map naturally to a ``func(**kw)`` call form. We
86 should develop, at a few key points, functional forms of all the requests that
86 should develop, at a few key points, functional forms of all the requests that
87 take arguments in this manner and automatically construct the necessary dict
87 take arguments in this manner and automatically construct the necessary dict
88 for sending.
88 for sending.
89
89
90
90
91 General Message Format
91 General Message Format
92 ======================
92 ======================
93
93
94 All messages send or received by any IPython process should have the following
94 All messages send or received by any IPython process should have the following
95 generic structure::
95 generic structure::
96
96
97 {
97 {
98 # The message header contains a pair of unique identifiers for the
98 # The message header contains a pair of unique identifiers for the
99 # originating session and the actual message id, in addition to the
99 # originating session and the actual message id, in addition to the
100 # username for the process that generated the message. This is useful in
100 # username for the process that generated the message. This is useful in
101 # collaborative settings where multiple users may be interacting with the
101 # collaborative settings where multiple users may be interacting with the
102 # same kernel simultaneously, so that frontends can label the various
102 # same kernel simultaneously, so that frontends can label the various
103 # messages in a meaningful way.
103 # messages in a meaningful way.
104 'header' : { 'msg_id' : uuid,
104 'header' : { 'msg_id' : uuid,
105 'username' : str,
105 'username' : str,
106 'session' : uuid
106 'session' : uuid
107 },
107 },
108
108
109 # In a chain of messages, the header from the parent is copied so that
109 # In a chain of messages, the header from the parent is copied so that
110 # clients can track where messages come from.
110 # clients can track where messages come from.
111 'parent_header' : dict,
111 'parent_header' : dict,
112
112
113 # All recognized message type strings are listed below.
113 # All recognized message type strings are listed below.
114 'msg_type' : str,
114 'msg_type' : str,
115
115
116 # The actual content of the message must be a dict, whose structure
116 # The actual content of the message must be a dict, whose structure
117 # depends on the message type.x
117 # depends on the message type.x
118 'content' : dict,
118 'content' : dict,
119 }
119 }
120
120
121 For each message type, the actual content will differ and all existing message
121 For each message type, the actual content will differ and all existing message
122 types are specified in what follows of this document.
122 types are specified in what follows of this document.
123
123
124
124
125 Messages on the XREP/XREQ socket
125 Messages on the XREP/XREQ socket
126 ================================
126 ================================
127
127
128 .. _execute:
128 .. _execute:
129
129
130 Execute
130 Execute
131 -------
131 -------
132
132
133 The execution request contains a single string, but this may be a multiline
133 The execution request contains a single string, but this may be a multiline
134 string. The kernel is responsible for splitting this into possibly more than
134 string. The kernel is responsible for splitting this into possibly more than
135 one block and deciding whether to compile these in 'single' or 'exec' mode.
135 one block and deciding whether to compile these in 'single' or 'exec' mode.
136 We're still sorting out this policy. The current inputsplitter is capable of
136 We're still sorting out this policy. The current inputsplitter is capable of
137 splitting the input for blocks that can all be run as 'single', but in the long
137 splitting the input for blocks that can all be run as 'single', but in the long
138 run it may prove cleaner to only use 'single' mode for truly single-line
138 run it may prove cleaner to only use 'single' mode for truly single-line
139 inputs, and run all multiline input in 'exec' mode. This would preserve the
139 inputs, and run all multiline input in 'exec' mode. This would preserve the
140 natural behavior of single-line inputs while allowing long cells to behave more
140 natural behavior of single-line inputs while allowing long cells to behave more
141 likea a script. This design will be refined as we complete the implementation.
141 likea a script. This design will be refined as we complete the implementation.
142
142
143 Message type: ``execute_request``::
143 Message type: ``execute_request``::
144
144
145 content = {
145 content = {
146 # Source code to be executed by the kernel, one or more lines.
146 # Source code to be executed by the kernel, one or more lines.
147 'code' : str,
147 'code' : str,
148
148
149 # A boolean flag which, if True, signals the kernel to execute this
149 # A boolean flag which, if True, signals the kernel to execute this
150 # code as quietly as possible. This means that the kernel will compile
150 # code as quietly as possible. This means that the kernel will compile
151 # the code with 'exec' instead of 'single' (so sys.displayhook will not
151 # the code with 'exec' instead of 'single' (so sys.displayhook will not
152 # fire), and will *not*:
152 # fire), and will *not*:
153 # - broadcast exceptions on the PUB socket
153 # - broadcast exceptions on the PUB socket
154 # - do any logging
154 # - do any logging
155 # - populate any history
155 # - populate any history
156 # The default is False.
156 # The default is False.
157 'silent' : bool,
157 'silent' : bool,
158 }
158 }
159
159
160 Upon execution, the kernel *always* sends a reply, with a status code
160 Upon execution, the kernel *always* sends a reply, with a status code
161 indicating what happened and additional data depending on the outcome.
161 indicating what happened and additional data depending on the outcome.
162
162
163 Message type: ``execute_reply``::
163 Message type: ``execute_reply``::
164
164
165 content = {
165 content = {
166 # One of: 'ok' OR 'error' OR 'abort'
166 # One of: 'ok' OR 'error' OR 'abort'
167 'status' : str,
167 'status' : str,
168
168
169 # This has the same structure as the output of a prompt request, but is
169 # This has the same structure as the output of a prompt request, but is
170 # for the client to set up the *next* prompt (with identical limitations
170 # for the client to set up the *next* prompt (with identical limitations
171 # to a prompt request)
171 # to a prompt request)
172 'next_prompt' : {
172 'next_prompt' : {
173 'prompt_string' : str,
173 'prompt_string' : str,
174 'prompt_number' : int,
174 'prompt_number' : int,
175 'input_sep' : str
175 'input_sep' : str
176 },
176 },
177
177
178 # The prompt number of the actual execution for this code, which may be
178 # The prompt number of the actual execution for this code, which may be
179 # different from the one used when the code was typed, which was the
179 # different from the one used when the code was typed, which was the
180 # 'next_prompt' field of the *previous* request. They will differ in the
180 # 'next_prompt' field of the *previous* request. They will differ in the
181 # case where there is more than one client talking simultaneously to a
181 # case where there is more than one client talking simultaneously to a
182 # kernel, since the numbers can go out of sync. GUI clients can use this
182 # kernel, since the numbers can go out of sync. GUI clients can use this
183 # to correct the previously written number in-place, terminal ones may
183 # to correct the previously written number in-place, terminal ones may
184 # re-print a corrected one if desired.
184 # re-print a corrected one if desired.
185 'prompt_number' : int,
185 'prompt_number' : int,
186 }
186 }
187
187
188 When status is 'ok', the following extra fields are present::
188 When status is 'ok', the following extra fields are present::
189
189
190 {
190 {
191 # The kernel will often transform the input provided to it. This
191 # The kernel will often transform the input provided to it. This
192 # contains the transformed code, which is what was actually executed.
192 # contains the transformed code, which is what was actually executed.
193 'transformed_code' : str,
193 'transformed_code' : str,
194
194
195 # The execution payload is a dict with string keys that may have been
195 # The execution payload is a dict with string keys that may have been
196 # produced by the code being executed. It is retrieved by the kernel at
196 # produced by the code being executed. It is retrieved by the kernel at
197 # the end of the execution and sent back to the front end, which can take
197 # the end of the execution and sent back to the front end, which can take
198 # action on it as needed. See main text for further details.
198 # action on it as needed. See main text for further details.
199 'payload' : dict,
199 'payload' : dict,
200 }
200 }
201
201
202 .. admonition:: Execution payloads
202 .. admonition:: Execution payloads
203
203
204 The notion of an 'execution payload' is different from a return value of a
204 The notion of an 'execution payload' is different from a return value of a
205 given set of code, which normally is just displayed on the pyout stream
205 given set of code, which normally is just displayed on the pyout stream
206 through the PUB socket. The idea of a payload is to allow special types of
206 through the PUB socket. The idea of a payload is to allow special types of
207 code, typically magics, to populate a data container in the IPython kernel
207 code, typically magics, to populate a data container in the IPython kernel
208 that will be shipped back to the caller via this channel. The kernel will
208 that will be shipped back to the caller via this channel. The kernel will
209 have an API for this, probably something along the lines of::
209 have an API for this, probably something along the lines of::
210
210
211 ip.exec_payload_add(key, value)
211 ip.exec_payload_add(key, value)
212
212
213 though this API is still in the design stages. The data returned in this
213 though this API is still in the design stages. The data returned in this
214 payload will allow frontends to present special views of what just happened.
214 payload will allow frontends to present special views of what just happened.
215
215
216
216
217 When status is 'error', the following extra fields are present::
217 When status is 'error', the following extra fields are present::
218
218
219 {
219 {
220 'exc_name' : str, # Exception name, as a string
220 'exc_name' : str, # Exception name, as a string
221 'exc_value' : str, # Exception value, as a string
221 'exc_value' : str, # Exception value, as a string
222
222
223 # The traceback will contain a list of frames, represented each as a
223 # The traceback will contain a list of frames, represented each as a
224 # string. For now we'll stick to the existing design of ultraTB, which
224 # string. For now we'll stick to the existing design of ultraTB, which
225 # controls exception level of detail statefully. But eventually we'll
225 # controls exception level of detail statefully. But eventually we'll
226 # want to grow into a model where more information is collected and
226 # want to grow into a model where more information is collected and
227 # packed into the traceback object, with clients deciding how little or
227 # packed into the traceback object, with clients deciding how little or
228 # how much of it to unpack. But for now, let's start with a simple list
228 # how much of it to unpack. But for now, let's start with a simple list
229 # of strings, since that requires only minimal changes to ultratb as
229 # of strings, since that requires only minimal changes to ultratb as
230 # written.
230 # written.
231 'traceback' : list,
231 'traceback' : list,
232 }
232 }
233
233
234
234
235 When status is 'abort', there are for now no additional data fields. This
235 When status is 'abort', there are for now no additional data fields. This
236 happens when the kernel was interrupted by a signal.
236 happens when the kernel was interrupted by a signal.
237
237
238
238
239 Prompt
239 Prompt
240 ------
240 ------
241
241
242 A simple request for a current prompt string.
242 A simple request for a current prompt string.
243
243
244 Message type: ``prompt_request``::
244 Message type: ``prompt_request``::
245
245
246 content = {}
246 content = {}
247
247
248 In the reply, the prompt string comes back with the prompt number placeholder
248 In the reply, the prompt string comes back with the prompt number placeholder
249 *unevaluated*. The message format is:
249 *unevaluated*. The message format is:
250
250
251 Message type: ``prompt_reply``::
251 Message type: ``prompt_reply``::
252
252
253 content = {
253 content = {
254 'prompt_string' : str,
254 'prompt_string' : str,
255 'prompt_number' : int,
255 'prompt_number' : int,
256 }
256 }
257
257
258 Clients can produce a prompt with ``prompt_string.format(prompt_number)``, but
258 Clients can produce a prompt with ``prompt_string.format(prompt_number)``, but
259 they should be aware that the actual prompt number for that input could change
259 they should be aware that the actual prompt number for that input could change
260 later, in the case where multiple clients are interacting with a single
260 later, in the case where multiple clients are interacting with a single
261 kernel.
261 kernel.
262
262
263
263
264 Object information
264 Object information
265 ------------------
265 ------------------
266
266
267 One of IPython's most used capabilities is the introspection of Python objects
267 One of IPython's most used capabilities is the introspection of Python objects
268 in the user's namespace, typically invoked via the ``?`` and ``??`` characters
268 in the user's namespace, typically invoked via the ``?`` and ``??`` characters
269 (which in reality are shorthands for the ``%pinfo`` magic). This is used often
269 (which in reality are shorthands for the ``%pinfo`` magic). This is used often
270 enough that it warrants an explicit message type, especially because frontends
270 enough that it warrants an explicit message type, especially because frontends
271 may want to get object information in response to user keystrokes (like Tab or
271 may want to get object information in response to user keystrokes (like Tab or
272 F1) besides from the user explicitly typing code like ``x??``.
272 F1) besides from the user explicitly typing code like ``x??``.
273
273
274 Message type: ``object_info_request``::
274 Message type: ``object_info_request``::
275
275
276 content = {
276 content = {
277 # The (possibly dotted) name of the object to be searched in all
277 # The (possibly dotted) name of the object to be searched in all
278 # relevant namespaces
278 # relevant namespaces
279 'name' : str,
279 'name' : str,
280
280
281 # The level of detail desired. The default (0) is equivalent to typing
281 # The level of detail desired. The default (0) is equivalent to typing
282 # 'x?' at the prompt, 1 is equivalent to 'x??'.
282 # 'x?' at the prompt, 1 is equivalent to 'x??'.
283 'detail_level' : int,
283 'detail_level' : int,
284 }
284 }
285
285
286 The returned information will be a dictionary with keys very similar to the
286 The returned information will be a dictionary with keys very similar to the
287 field names that IPython prints at the terminal.
287 field names that IPython prints at the terminal.
288
288
289 Message type: ``object_info_reply``::
289 Message type: ``object_info_reply``::
290
290
291 content = {
291 content = {
292 # Flags for magics and system aliases
292 # Flags for magics and system aliases
293 'ismagic' : bool,
293 'ismagic' : bool,
294 'isalias' : bool,
294 'isalias' : bool,
295
295
296 # The name of the namespace where the object was found ('builtin',
296 # The name of the namespace where the object was found ('builtin',
297 # 'magics', 'alias', 'interactive', etc.)
297 # 'magics', 'alias', 'interactive', etc.)
298 'namespace' : str,
298 'namespace' : str,
299
299
300 # The type name will be type.__name__ for normal Python objects, but it
300 # The type name will be type.__name__ for normal Python objects, but it
301 # can also be a string like 'Magic function' or 'System alias'
301 # can also be a string like 'Magic function' or 'System alias'
302 'type_name' : str,
302 'type_name' : str,
303
303
304 'string_form' : str,
304 'string_form' : str,
305
305
306 # For objects with a __class__ attribute this will be set
306 # For objects with a __class__ attribute this will be set
307 'base_class' : str,
307 'base_class' : str,
308
308
309 # For objects with a __len__ attribute this will be set
309 # For objects with a __len__ attribute this will be set
310 'length' : int,
310 'length' : int,
311
311
312 # If the object is a function, class or method whose file we can find,
312 # If the object is a function, class or method whose file we can find,
313 # we give its full path
313 # we give its full path
314 'file' : str,
314 'file' : str,
315
315
316 # For pure Python callable objects, we can reconstruct the object
316 # For pure Python callable objects, we can reconstruct the object
317 # definition line which provides its call signature
317 # definition line which provides its call signature
318 'definition' : str,
318 'definition' : str,
319
319
320 # For instances, provide the constructor signature (the definition of
320 # For instances, provide the constructor signature (the definition of
321 # the __init__ method):
321 # the __init__ method):
322 'init_definition' : str,
322 'init_definition' : str,
323
323
324 # Docstrings: for any object (function, method, module, package) with a
324 # Docstrings: for any object (function, method, module, package) with a
325 # docstring, we show it. But in addition, we may provide additional
325 # docstring, we show it. But in addition, we may provide additional
326 # docstrings. For example, for instances we will show the constructor
326 # docstrings. For example, for instances we will show the constructor
327 # and class docstrings as well, if available.
327 # and class docstrings as well, if available.
328 'docstring' : str,
328 'docstring' : str,
329
329
330 # For instances, provide the constructor and class docstrings
330 # For instances, provide the constructor and class docstrings
331 'init_docstring' : str,
331 'init_docstring' : str,
332 'class_docstring' : str,
332 'class_docstring' : str,
333
333
334 # If detail_level was 1, we also try to find the source code that
334 # If detail_level was 1, we also try to find the source code that
335 # defines the object, if possible. The string 'None' will indicate
335 # defines the object, if possible. The string 'None' will indicate
336 # that no source was found.
336 # that no source was found.
337 'source' : str,
337 'source' : str,
338 }
338 }
339
339
340
340
341 Complete
341 Complete
342 --------
342 --------
343
343
344 Message type: ``complete_request``::
344 Message type: ``complete_request``::
345
345
346 content = {
346 content = {
347 # The text to be completed, such as 'a.is'
347 # The text to be completed, such as 'a.is'
348 'text' : str,
348 'text' : str,
349
349
350 # The full line, such as 'print a.is'. This allows completers to
350 # The full line, such as 'print a.is'. This allows completers to
351 # make decisions that may require information about more than just the
351 # make decisions that may require information about more than just the
352 # current word.
352 # current word.
353 'line' : str,
353 'line' : str,
354
355 # The entire block of text where the line is. This may be useful in the
356 # case of multiline completions where more context may be needed. Note: if
357 # in practice this field proves unnecessary, remove it to lighten the
358 # messages.
359
360 'block' : str,
361
362 # The position of the cursor where the user hit 'TAB' on the line.
363 'cursor_pos' : int,
354 }
364 }
355
365
356 Message type: ``complete_reply``::
366 Message type: ``complete_reply``::
357
367
358 content = {
368 content = {
359 # The list of all matches to the completion request, such as
369 # The list of all matches to the completion request, such as
360 # ['a.isalnum', 'a.isalpha'] for the above example.
370 # ['a.isalnum', 'a.isalpha'] for the above example.
361 'matches' : list
371 'matches' : list
362 }
372 }
363
373
364
374
365 History
375 History
366 -------
376 -------
367
377
368 For clients to explicitly request history from a kernel. The kernel has all
378 For clients to explicitly request history from a kernel. The kernel has all
369 the actual execution history stored in a single location, so clients can
379 the actual execution history stored in a single location, so clients can
370 request it from the kernel when needed.
380 request it from the kernel when needed.
371
381
372 Message type: ``history_request``::
382 Message type: ``history_request``::
373
383
374 content = {
384 content = {
375
385
376 # If True, also return output history in the resulting dict.
386 # If True, also return output history in the resulting dict.
377 'output' : bool,
387 'output' : bool,
378
388
379 # If True, return the raw input history, else the transformed input.
389 # If True, return the raw input history, else the transformed input.
380 'raw' : bool,
390 'raw' : bool,
381
391
382 # This parameter can be one of: A number, a pair of numbers, None
392 # This parameter can be one of: A number, a pair of numbers, None
383 # If not given, last 40 are returned.
393 # If not given, last 40 are returned.
384 # - number n: return the last n entries.
394 # - number n: return the last n entries.
385 # - pair n1, n2: return entries in the range(n1, n2).
395 # - pair n1, n2: return entries in the range(n1, n2).
386 # - None: return all history
396 # - None: return all history
387 'range' : n or (n1, n2) or None,
397 'range' : n or (n1, n2) or None,
388
398
389 # If a filter is given, it is treated as a regular expression and only
399 # If a filter is given, it is treated as a regular expression and only
390 # matching entries are returned. re.search() is used to find matches.
400 # matching entries are returned. re.search() is used to find matches.
391 'filter' : str,
401 'filter' : str,
392 }
402 }
393
403
394 Message type: ``history_reply``::
404 Message type: ``history_reply``::
395
405
396 content = {
406 content = {
397 # A dict with prompt numbers as keys and either (input, output) or input
407 # A dict with prompt numbers as keys and either (input, output) or input
398 # as the value depending on whether output was True or False,
408 # as the value depending on whether output was True or False,
399 # respectively.
409 # respectively.
400 'history' : dict,
410 'history' : dict,
401 }
411 }
402 Messages on the PUB/SUB socket
412 Messages on the PUB/SUB socket
403 ==============================
413 ==============================
404
414
405 Streams (stdout, stderr, etc)
415 Streams (stdout, stderr, etc)
406 ------------------------------
416 ------------------------------
407
417
408 Message type: ``stream``::
418 Message type: ``stream``::
409
419
410 content = {
420 content = {
411 # The name of the stream is one of 'stdin', 'stdout', 'stderr'
421 # The name of the stream is one of 'stdin', 'stdout', 'stderr'
412 'name' : str,
422 'name' : str,
413
423
414 # The data is an arbitrary string to be written to that stream
424 # The data is an arbitrary string to be written to that stream
415 'data' : str,
425 'data' : str,
416 }
426 }
417
427
418 When a kernel receives a raw_input call, it should also broadcast it on the pub
428 When a kernel receives a raw_input call, it should also broadcast it on the pub
419 socket with the names 'stdin' and 'stdin_reply'. This will allow other clients
429 socket with the names 'stdin' and 'stdin_reply'. This will allow other clients
420 to monitor/display kernel interactions and possibly replay them to their user
430 to monitor/display kernel interactions and possibly replay them to their user
421 or otherwise expose them.
431 or otherwise expose them.
422
432
423 Python inputs
433 Python inputs
424 -------------
434 -------------
425
435
426 These messages are the re-broadcast of the ``execute_request``.
436 These messages are the re-broadcast of the ``execute_request``.
427
437
428 Message type: ``pyin``::
438 Message type: ``pyin``::
429
439
430 content = {
440 content = {
431 # Source code to be executed, one or more lines
441 # Source code to be executed, one or more lines
432 'code' : str
442 'code' : str
433 }
443 }
434
444
435 Python outputs
445 Python outputs
436 --------------
446 --------------
437
447
438 When Python produces output from code that has been compiled in with the
448 When Python produces output from code that has been compiled in with the
439 'single' flag to :func:`compile`, any expression that produces a value (such as
449 'single' flag to :func:`compile`, any expression that produces a value (such as
440 ``1+1``) is passed to ``sys.displayhook``, which is a callable that can do with
450 ``1+1``) is passed to ``sys.displayhook``, which is a callable that can do with
441 this value whatever it wants. The default behavior of ``sys.displayhook`` in
451 this value whatever it wants. The default behavior of ``sys.displayhook`` in
442 the Python interactive prompt is to print to ``sys.stdout`` the :func:`repr` of
452 the Python interactive prompt is to print to ``sys.stdout`` the :func:`repr` of
443 the value as long as it is not ``None`` (which isn't printed at all). In our
453 the value as long as it is not ``None`` (which isn't printed at all). In our
444 case, the kernel instantiates as ``sys.displayhook`` an object which has
454 case, the kernel instantiates as ``sys.displayhook`` an object which has
445 similar behavior, but which instead of printing to stdout, broadcasts these
455 similar behavior, but which instead of printing to stdout, broadcasts these
446 values as ``pyout`` messages for clients to display appropriately.
456 values as ``pyout`` messages for clients to display appropriately.
447
457
448 Message type: ``pyout``::
458 Message type: ``pyout``::
449
459
450 content = {
460 content = {
451 # The data is typically the repr() of the object.
461 # The data is typically the repr() of the object.
452 'data' : str,
462 'data' : str,
453
463
454 # The prompt number for this execution is also provided so that clients
464 # The prompt number for this execution is also provided so that clients
455 # can display it, since IPython automatically creates variables called
465 # can display it, since IPython automatically creates variables called
456 # _N (for prompt N).
466 # _N (for prompt N).
457 'prompt_number' : int,
467 'prompt_number' : int,
458 }
468 }
459
469
460 Python errors
470 Python errors
461 -------------
471 -------------
462
472
463 When an error occurs during code execution
473 When an error occurs during code execution
464
474
465 Message type: ``pyerr``::
475 Message type: ``pyerr``::
466
476
467 content = {
477 content = {
468 # Similar content to the execute_reply messages for the 'error' case,
478 # Similar content to the execute_reply messages for the 'error' case,
469 # except the 'status' field is omitted.
479 # except the 'status' field is omitted.
470 }
480 }
471
481
472 Kernel crashes
482 Kernel crashes
473 --------------
483 --------------
474
484
475 When the kernel has an unexpected exception, caught by the last-resort
485 When the kernel has an unexpected exception, caught by the last-resort
476 sys.excepthook, we should broadcast the crash handler's output before exiting.
486 sys.excepthook, we should broadcast the crash handler's output before exiting.
477 This will allow clients to notice that a kernel died, inform the user and
487 This will allow clients to notice that a kernel died, inform the user and
478 propose further actions.
488 propose further actions.
479
489
480 Message type: ``crash``::
490 Message type: ``crash``::
481
491
482 content = {
492 content = {
483 # Similarly to the 'error' case for execute_reply messages, this will
493 # Similarly to the 'error' case for execute_reply messages, this will
484 # contain exc_name, exc_type and traceback fields.
494 # contain exc_name, exc_type and traceback fields.
485
495
486 # An additional field with supplementary information such as where to
496 # An additional field with supplementary information such as where to
487 # send the crash message
497 # send the crash message
488 'info' : str,
498 'info' : str,
489 }
499 }
490
500
491
501
492 Future ideas
502 Future ideas
493 ------------
503 ------------
494
504
495 Other potential message types, currently unimplemented, listed below as ideas.
505 Other potential message types, currently unimplemented, listed below as ideas.
496
506
497 Message type: ``file``::
507 Message type: ``file``::
498
508
499 content = {
509 content = {
500 'path' : 'cool.jpg',
510 'path' : 'cool.jpg',
501 'mimetype' : str,
511 'mimetype' : str,
502 'data' : str,
512 'data' : str,
503 }
513 }
504
514
505
515
506 Messages on the REQ/REP socket
516 Messages on the REQ/REP socket
507 ==============================
517 ==============================
508
518
509 This is a socket that goes in the opposite direction: from the kernel to a
519 This is a socket that goes in the opposite direction: from the kernel to a
510 *single* frontend, and its purpose is to allow ``raw_input`` and similar
520 *single* frontend, and its purpose is to allow ``raw_input`` and similar
511 operations that read from ``sys.stdin`` on the kernel to be fulfilled by the
521 operations that read from ``sys.stdin`` on the kernel to be fulfilled by the
512 client. For now we will keep these messages as simple as possible, since they
522 client. For now we will keep these messages as simple as possible, since they
513 basically only mean to convey the ``raw_input(prompt)`` call.
523 basically only mean to convey the ``raw_input(prompt)`` call.
514
524
515 Message type: ``input_request``::
525 Message type: ``input_request``::
516
526
517 content = { 'prompt' : str }
527 content = { 'prompt' : str }
518
528
519 Message type: ``input_reply``::
529 Message type: ``input_reply``::
520
530
521 content = { 'value' : str }
531 content = { 'value' : str }
522
532
523 .. Note::
533 .. Note::
524
534
525 We do not explicitly try to forward the raw ``sys.stdin`` object, because in
535 We do not explicitly try to forward the raw ``sys.stdin`` object, because in
526 practice the kernel should behave like an interactive program. When a
536 practice the kernel should behave like an interactive program. When a
527 program is opened on the console, the keyboard effectively takes over the
537 program is opened on the console, the keyboard effectively takes over the
528 ``stdin`` file descriptor, and it can't be used for raw reading anymore.
538 ``stdin`` file descriptor, and it can't be used for raw reading anymore.
529 Since the IPython kernel effectively behaves like a console program (albeit
539 Since the IPython kernel effectively behaves like a console program (albeit
530 one whose "keyboard" is actually living in a separate process and
540 one whose "keyboard" is actually living in a separate process and
531 transported over the zmq connection), raw ``stdin`` isn't expected to be
541 transported over the zmq connection), raw ``stdin`` isn't expected to be
532 available.
542 available.
533
543
534
544
535 Heartbeat for kernels
545 Heartbeat for kernels
536 =====================
546 =====================
537
547
538 Initially we had considered using messages like those above over ZMQ for a
548 Initially we had considered using messages like those above over ZMQ for a
539 kernel 'heartbeat' (a way to detect quickly and reliably whether a kernel is
549 kernel 'heartbeat' (a way to detect quickly and reliably whether a kernel is
540 alive at all, even if it may be busy executing user code). But this has the
550 alive at all, even if it may be busy executing user code). But this has the
541 problem that if the kernel is locked inside extension code, it wouldn't execute
551 problem that if the kernel is locked inside extension code, it wouldn't execute
542 the python heartbeat code. But it turns out that we can implement a basic
552 the python heartbeat code. But it turns out that we can implement a basic
543 heartbeat with pure ZMQ, without using any Python messaging at all.
553 heartbeat with pure ZMQ, without using any Python messaging at all.
544
554
545 The monitor sends out a single zmq message (right now, it is a str of the
555 The monitor sends out a single zmq message (right now, it is a str of the
546 monitor's lifetime in seconds), and gets the same message right back, prefixed
556 monitor's lifetime in seconds), and gets the same message right back, prefixed
547 with the zmq identity of the XREQ socket in the heartbeat process. This can be
557 with the zmq identity of the XREQ socket in the heartbeat process. This can be
548 a uuid, or even a full message, but there doesn't seem to be a need for packing
558 a uuid, or even a full message, but there doesn't seem to be a need for packing
549 up a message when the sender and receiver are the exact same Python object.
559 up a message when the sender and receiver are the exact same Python object.
550
560
551 The model is this::
561 The model is this::
552
562
553 monitor.send(str(self.lifetime)) # '1.2345678910'
563 monitor.send(str(self.lifetime)) # '1.2345678910'
554
564
555 and the monitor receives some number of messages of the form::
565 and the monitor receives some number of messages of the form::
556
566
557 ['uuid-abcd-dead-beef', '1.2345678910']
567 ['uuid-abcd-dead-beef', '1.2345678910']
558
568
559 where the first part is the zmq.IDENTITY of the heart's XREQ on the engine, and
569 where the first part is the zmq.IDENTITY of the heart's XREQ on the engine, and
560 the rest is the message sent by the monitor. No Python code ever has any
570 the rest is the message sent by the monitor. No Python code ever has any
561 access to the message between the monitor's send, and the monitor's recv.
571 access to the message between the monitor's send, and the monitor's recv.
562
572
563
573
564 ToDo
574 ToDo
565 ====
575 ====
566
576
567 Missing things include:
577 Missing things include:
568
578
569 * Important: finish thinking through the payload concept and API.
579 * Important: finish thinking through the payload concept and API.
570
580
571 * Important: ensure that we have a good solution for magics like %edit. It's
581 * Important: ensure that we have a good solution for magics like %edit. It's
572 likely that with the payload concept we can build a full solution, but not
582 likely that with the payload concept we can build a full solution, but not
573 100% clear yet.
583 100% clear yet.
574
584
575 * Finishing the details of the heartbeat protocol.
585 * Finishing the details of the heartbeat protocol.
576
586
577 * Signal handling: specify what kind of information kernel should broadcast (or
587 * Signal handling: specify what kind of information kernel should broadcast (or
578 not) when it receives signals.
588 not) when it receives signals.
579
589
580 .. include:: ../links.rst
590 .. include:: ../links.rst
General Comments 0
You need to be logged in to leave comments. Login now