Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'stdin'

Changes stdin channel from REQ-REQ to ROUTER-DEALER, fixing
the round-robin load-balancing of stdin_requests across frontends.
stdin_requests now go to the client that made the execute_request
that prompted the stdin request.

stdin_requests from frontends that do not support stdin will raise an error,
rather than hanging on input that will never arrive.

reviewed by @fperez

closes #673
  • Loading branch information...
commit 6e92ffd9a6e598b033114a2fc80db174012eb1cd 2 parents 7883c91 + f882c24
Min RK minrk authored
8 IPython/core/error.py
View
@@ -6,6 +6,7 @@
* Brian Granger
* Fernando Perez
+* Min Ragan-Kelley
Notes
-----
@@ -49,3 +50,10 @@ class UsageError(IPythonCoreError):
Something that probably won't warrant a full traceback, but should
nevertheless interrupt a macro / batch file.
"""
+
+class StdinNotImplementedError(IPythonCoreError, NotImplementedError):
+ """raw_input was requested in a context where it is not supported
+
+ For use in IPython kernels, where only some frontends may support
+ stdin requests.
+ """
2  IPython/core/interactiveshell.py
View
@@ -1546,7 +1546,7 @@ def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
# line, there may be SyntaxError cases with imported code.
self.showsyntaxerror(filename)
elif etype is UsageError:
- print "UsageError:", value
+ self.write_err("UsageError: %s" % value)
else:
# WARNING: these variables are somewhat deprecated and not
# necessarily safe to use in a threaded environment, but tools
1  IPython/frontend/html/notebook/static/js/kernel.js
View
@@ -121,6 +121,7 @@ var IPython = (function (IPython) {
silent : false,
user_variables : [],
user_expressions : {}
+ allow_stdin : false,
};
var msg = this.get_msg("execute_request", content);
this.shell_channel.send(JSON.stringify(msg));
13 IPython/zmq/ipkernel.py
View
@@ -29,6 +29,7 @@
from IPython.config.configurable import Configurable
from IPython.config.application import boolean_flag
from IPython.core.application import ProfileDir
+from IPython.core.error import StdinNotImplementedError
from IPython.core.shellapp import (
InteractiveShellApp, shell_flags, shell_aliases
)
@@ -219,7 +220,11 @@ def execute_request(self, ident, parent):
# Replace raw_input. Note that is not sufficient to replace
# raw_input in the user namespace.
- raw_input = lambda prompt='': self._raw_input(prompt, ident, parent)
+ if content.get('allow_stdin', False):
+ raw_input = lambda prompt='': self._raw_input(prompt, ident, parent)
+ else:
+ raw_input = lambda prompt='' : self._no_raw_input()
+
if py3compat.PY3:
__builtin__.input = raw_input
else:
@@ -406,6 +411,10 @@ def _abort_queue(self):
# be set shorter for true asynchronous clients.
time.sleep(0.1)
+ def _no_raw_input(self):
+ """Raise StdinNotImplentedError if active frontend doesn't support stdin."""
+ raise StdinNotImplementedError("raw_input was called, but this frontend does not support stdin.")
+
def _raw_input(self, prompt, ident, parent):
# Flush output before making the request.
sys.stderr.flush()
@@ -413,7 +422,7 @@ def _raw_input(self, prompt, ident, parent):
# Send the input request.
content = json_clean(dict(prompt=prompt))
- msg = self.session.send(self.stdin_socket, u'input_request', content, parent)
+ msg = self.session.send(self.stdin_socket, u'input_request', content, parent, ident=ident)
# Await a response.
while True:
4 IPython/zmq/kernelapp.py
View
@@ -153,9 +153,9 @@ def init_sockets(self):
self.iopub_port = self._bind_socket(self.iopub_socket, self.iopub_port)
self.log.debug("iopub PUB Channel on port: %i"%self.iopub_port)
- self.stdin_socket = context.socket(zmq.XREQ)
+ self.stdin_socket = context.socket(zmq.ROUTER)
self.stdin_port = self._bind_socket(self.stdin_socket, self.stdin_port)
- self.log.debug("stdin XREQ Channel on port: %i"%self.stdin_port)
+ self.log.debug("stdin ROUTER Channel on port: %i"%self.stdin_port)
self.heartbeat = Heartbeat(context, (self.ip, self.hb_port))
self.hb_port = self.heartbeat.port
22 IPython/zmq/kernelmanager.py
View
@@ -179,6 +179,8 @@ class ShellSocketChannel(ZMQSocketChannel):
"""
command_queue = None
+ # flag for whether execute requests should be allowed to call raw_input:
+ allow_stdin = True
def __init__(self, context, session, address):
super(ShellSocketChannel, self).__init__(context, session, address)
@@ -210,7 +212,7 @@ def call_handlers(self, msg):
raise NotImplementedError('call_handlers must be defined in a subclass.')
def execute(self, code, silent=False,
- user_variables=None, user_expressions=None):
+ user_variables=None, user_expressions=None, allow_stdin=None):
"""Execute code in the kernel.
Parameters
@@ -231,6 +233,12 @@ def execute(self, code, silent=False,
namespace. They will come back as a dict with these names as keys
and their :func:`repr` as values.
+ allow_stdin : bool, optional
+ Flag for
+ A dict with string keys and to pull from the user's
+ namespace. They will come back as a dict with these names as keys
+ and their :func:`repr` as values.
+
Returns
-------
The msg_id of the message sent.
@@ -239,7 +247,10 @@ def execute(self, code, silent=False,
user_variables = []
if user_expressions is None:
user_expressions = {}
-
+ if allow_stdin is None:
+ allow_stdin = self.allow_stdin
+
+
# Don't waste network traffic if inputs are invalid
if not isinstance(code, basestring):
raise ValueError('code %r must be a string' % code)
@@ -250,7 +261,9 @@ def execute(self, code, silent=False,
# not in Session.
content = dict(code=code, silent=silent,
user_variables=user_variables,
- user_expressions=user_expressions)
+ user_expressions=user_expressions,
+ allow_stdin=allow_stdin,
+ )
msg = self.session.msg('execute_request', content)
self._queue_request(msg)
return msg['header']['msg_id']
@@ -735,6 +748,9 @@ def start_channels(self, shell=True, sub=True, stdin=True, hb=True):
self.sub_channel.start()
if stdin:
self.stdin_channel.start()
+ self.shell_channel.allow_stdin = True
+ else:
+ self.shell_channel.allow_stdin = False
if hb:
self.hb_channel.start()
2  IPython/zmq/pykernel.py
View
@@ -209,7 +209,7 @@ def _raw_input(self, prompt, ident, parent):
# Send the input request.
content = dict(prompt=prompt)
- msg = self.session.send(self.stdin_socket, u'input_request', content, parent)
+ msg = self.session.send(self.stdin_socket, u'input_request', content, parent, ident=ident)
# Await a response.
ident,reply = self.session.recv(self.stdin_socket, 0)
BIN  docs/source/development/figs/frontend-kernel.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
120 docs/source/development/figs/frontend-kernel.svg
View
@@ -14,8 +14,8 @@
height="1052.3622047"
id="svg2"
version="1.1"
- inkscape:version="0.47 r22583"
- sodipodi:docname="ipython-frontend-kernel.svg"
+ inkscape:version="0.48.2 r9819"
+ sodipodi:docname="frontend-kernel.svg"
inkscape:export-filename="/home/jtriley/Documents/ipython-frontend-kernel.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
@@ -2956,17 +2956,17 @@
inkscape:pageshadow="2"
inkscape:zoom="0.90509668"
inkscape:cx="256.73404"
- inkscape:cy="303.39911"
+ inkscape:cy="-403.70767"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
showguides="true"
inkscape:guide-bbox="true"
- inkscape:window-width="1440"
- inkscape:window-height="825"
+ inkscape:window-width="1245"
+ inkscape:window-height="756"
inkscape:window-x="0"
- inkscape:window-y="24"
- inkscape:window-maximized="1"
+ inkscape:window-y="0"
+ inkscape:window-maximized="0"
inkscape:snap-nodes="true" />
<metadata
id="metadata7">
@@ -3022,7 +3022,7 @@
<rect
style="fill:#241c1c;fill-opacity:1"
id="rect4235"
- width="151.52289"
+ width="180"
height="92.934036"
x="43.015251"
y="565.53973"
@@ -3032,7 +3032,7 @@
<rect
style="fill:#008000;fill-opacity:1"
id="rect4235-2"
- width="151.52289"
+ width="180"
height="92.934036"
x="285.4671"
y="565.53973"
@@ -3052,7 +3052,7 @@
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
- x="75.632164"
+ x="49.632164"
y="624.2724"
id="text4268"
inkscape:export-filename="/home/jtriley/Documents/path10411-0-4-9.png"
@@ -3060,13 +3060,13 @@
inkscape:export-ydpi="90"><tspan
sodipodi:role="line"
id="tspan4270"
- x="75.632164"
+ x="49.632164"
y="624.2724"
- style="fill:#ffffff">REQ</tspan></text>
+ style="fill:#ffffff">ROUTER</tspan></text>
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
- x="308.98245"
+ x="292.98245"
y="626.58685"
id="text4268-9"
inkscape:export-filename="/home/jtriley/Documents/path10411-0-4-9.png"
@@ -3074,9 +3074,9 @@
inkscape:export-ydpi="90"><tspan
sodipodi:role="line"
id="tspan4270-1"
- x="308.98245"
+ x="292.98245"
y="626.58685"
- style="fill:#ffffff">XREP</tspan></text>
+ style="fill:#ffffff">ROUTER</tspan></text>
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
@@ -3148,13 +3148,14 @@
y="222.01678" /></flowRegion><flowPara
id="flowPara3620"
style="font-size:28px;font-weight:bold">Front-end</flowPara></flowRoot> <path
- style="fill:#05ff00;stroke:#2af510;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;fill-opacity:1"
+ style="fill:#05ff00;fill-opacity:1;stroke:#2af510;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 373.73648,243.10253 -0.11904,-45.00016"
id="path3711"
inkscape:connector-type="polyline"
inkscape:export-filename="/home/jtriley/Documents/path10411-0-4-9.png"
inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
<rect
style="fill:#00ff00;fill-opacity:1"
id="rect3884"
@@ -3192,7 +3193,7 @@
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
- x="454.03732"
+ x="444.03732"
y="345.68896"
id="text4861-2"
inkscape:export-filename="/home/jtriley/Documents/path10411-0-4-9.png"
@@ -3200,9 +3201,9 @@
inkscape:export-ydpi="90"><tspan
sodipodi:role="line"
id="tspan4863-6"
- x="454.03732"
+ x="444.03732"
y="345.68896"
- style="font-size:28px;fill:#ffffff">REP</tspan></text>
+ style="font-size:28px;fill:#ffffff">DEAL</tspan></text>
<rect
style="fill:#ff0000;fill-opacity:1"
id="rect4859-9-4"
@@ -3250,7 +3251,7 @@
id="tspan4863-6-97"
x="239.47998"
y="344.35312"
- style="font-size:28px;fill:#ffffff">XREQ</tspan></text>
+ style="font-size:28px;fill:#ffffff">DEAL</tspan></text>
<rect
style="fill:#0000ff;fill-rule:evenodd;stroke:#000000;stroke-width:0.80252945px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="rect2816-3"
@@ -3281,7 +3282,8 @@
style="fill:none;stroke:#06ff00;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 728.27256,243.10253 -0.1191,-45.00015"
id="path3711-4"
- inkscape:connector-type="polyline" />
+ inkscape:connector-type="polyline"
+ inkscape:connector-curvature="0" />
<rect
style="fill:#00ff00;fill-opacity:1"
id="rect3884-4"
@@ -3335,7 +3337,7 @@
id="tspan4863-6-97-6"
x="631.95612"
y="344.35312"
- style="font-size:28px;fill:#ffffff">XREQ</tspan></text>
+ style="font-size:28px;fill:#ffffff">DEAL</tspan></text>
<rect
style="fill:#0000ff;fill-rule:evenodd;stroke:#000000;stroke-width:0.80252945px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="rect2816-3-6"
@@ -3367,7 +3369,8 @@
d="m 37.276897,243.10252 -0.11904,-45.00015"
id="path3711-4-8"
inkscape:connector-type="polyline"
- sodipodi:nodetypes="cc" />
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
<rect
style="fill:#00ff00;fill-opacity:1"
id="rect3884-4-1"
@@ -3421,10 +3424,10 @@
id="tspan4863-6-97-6-1"
x="-59.039528"
y="344.35312"
- style="font-size:28px;fill:#ffffff">XREQ</tspan></text>
+ style="font-size:28px;fill:#ffffff">DEAL</tspan></text>
<path
style="fill:#ff0000;stroke:#ff0000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-mid:url(#Arrow1Mstart)"
- d="m 123.8316,357.91004 355.72174,187.40953 50.81739,26.77279"
+ d="M 123.8316,357.91004 530.37073,572.09236"
id="path10788"
inkscape:connector-type="polyline"
inkscape:connection-start="#rect4859-9-4-5-6"
@@ -3432,10 +3435,13 @@
sodipodi:nodetypes="ccc"
inkscape:export-filename="/home/jtriley/Documents/path10411-0-4-9.png"
inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
+ inkscape:export-ydpi="90"
+ inkscape:connection-start-point="d4"
+ inkscape:connection-end-point="d4"
+ inkscape:connector-curvature="0" />
<path
style="fill:#d40000;fill-opacity:1;stroke:#ff0000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-mid:url(#Arrow1Mstart)"
- d="M 759.43823,357.91004 696.80284,461.72488 634.16746,565.53973"
+ d="M 759.43823,357.91004 634.16746,565.53973"
id="path10790"
inkscape:connector-type="polyline"
inkscape:connection-start="#rect4859-9-4-5"
@@ -3443,10 +3449,13 @@
sodipodi:nodetypes="ccc"
inkscape:export-filename="/home/jtriley/Documents/path10411-0-4-9.png"
inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
+ inkscape:export-ydpi="90"
+ inkscape:connection-start-point="d4"
+ inkscape:connection-end-point="d4"
+ inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#278900;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-mid:url(#Arrow1Mstart)"
- d="M 10.376699,357.91004 297.06778,565.53973"
+ d="M 11.518036,357.91004 308.91123,565.53973"
id="path10792"
inkscape:connector-type="polyline"
inkscape:connection-start="#rect4859-9-3-5-8"
@@ -3454,10 +3463,13 @@
sodipodi:nodetypes="ccc"
inkscape:export-filename="/home/jtriley/Documents/path10411-0-4-9.png"
inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
+ inkscape:export-ydpi="90"
+ inkscape:connection-start-point="d4"
+ inkscape:connection-end-point="d4"
+ inkscape:connector-curvature="0" />
<path
style="fill:#008000;fill-opacity:1;stroke:#238800;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-mid:url(#Arrow1Mstart)"
- d="M 645.98339,357.91004 413.30206,565.53973"
+ d="M 647.12473,357.91004 425.14551,565.53973"
id="path10794"
inkscape:connector-type="polyline"
inkscape:connection-start="#rect4859-9-3-5"
@@ -3465,10 +3477,13 @@
sodipodi:nodetypes="ccc"
inkscape:export-filename="/home/jtriley/Documents/path10411-0-4-9.png"
inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
+ inkscape:export-ydpi="90"
+ inkscape:connection-start-point="d4"
+ inkscape:connection-end-point="d4"
+ inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#ff0000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-mid:url(#Arrow1Mstart)"
- d="m 398.42235,357.91004 127.29423,155.72226 42.43141,51.90743"
+ d="M 398.42235,357.91004 568.14799,565.53973"
id="path10796"
inkscape:connector-type="polyline"
inkscape:connection-start="#rect4859-9-4"
@@ -3476,10 +3491,13 @@
sodipodi:nodetypes="ccc"
inkscape:export-filename="/home/jtriley/Documents/path10411-0-4-9.png"
inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
+ inkscape:export-ydpi="90"
+ inkscape:connection-start-point="d4"
+ inkscape:connection-end-point="d4"
+ inkscape:connector-curvature="0" />
<path
style="fill:#280b0b;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-mid:none"
- d="M 179.80746,565.53973 452.88606,357.62577"
+ d="M 191.65337,565.53973 454.02622,357.62577"
id="path10800"
inkscape:connector-type="polyline"
inkscape:connection-start="#rect4235"
@@ -3487,10 +3505,13 @@
sodipodi:nodetypes="ccc"
inkscape:export-filename="/home/jtriley/Documents/path10411-0-4-9.png"
inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
+ inkscape:export-ydpi="90"
+ inkscape:connection-start-point="d4"
+ inkscape:connection-end-point="d4"
+ inkscape:connector-curvature="0" />
<path
style="fill:#ff0000;stroke:#449900;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-mid:url(#Arrow1Mend)"
- d="M 347.28257,565.53973 284.96744,357.91004"
+ d="M 359.12602,565.53973 286.10878,357.91004"
id="path10802"
inkscape:connector-type="polyline"
inkscape:connection-start="#rect4235-2"
@@ -3498,7 +3519,10 @@
sodipodi:nodetypes="ccc"
inkscape:export-filename="/home/jtriley/Documents/path10411-0-4-9.png"
inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
+ inkscape:export-ydpi="90"
+ inkscape:connection-start-point="d4"
+ inkscape:connection-end-point="d4"
+ inkscape:connector-curvature="0" />
<rect
style="fill:#000000;fill-opacity:1;stroke:none"
id="rect11963"
@@ -6717,20 +6741,28 @@
id="path6285"
inkscape:connector-type="polyline"
inkscape:connection-start="#rect4497"
- inkscape:connection-end="#rect3695" />
+ inkscape:connection-end="#rect3695"
+ inkscape:connection-start-point="d4"
+ inkscape:connection-end-point="d4"
+ inkscape:connector-curvature="0" />
<path
- style="fill:none;stroke:#07ff00;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ style="fill:none;stroke:#07ff00;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 728.98863,98.204487 0.69887,46.345193"
id="path7136"
inkscape:connector-type="polyline"
- inkscape:connection-start="#g6750" />
+ inkscape:connection-start="#g6750"
+ inkscape:connection-start-point="d4"
+ inkscape:connector-curvature="0" />
<path
- style="fill:none;stroke:#06ff00;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ style="fill:none;stroke:#06ff00;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 37.066258,97.891987 0.09752,46.781813"
id="path5028"
inkscape:connector-type="polyline"
inkscape:connection-end="#rect3695-4-1"
- inkscape:connection-start="#g4874" />
+ inkscape:connection-start="#g4874"
+ inkscape:connection-start-point="d4"
+ inkscape:connection-end-point="d4"
+ inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:3.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Send-9);marker-mid:none;marker-end:url(#Arrow1Mend)"
d="m 97.76109,405.78583 c 49.81163,34.41382 20.9084,50.49106 -23.630766,17.69543"
50 docs/source/development/messaging.txt
View
@@ -31,30 +31,30 @@ The basic design is explained in the following diagram:
A single kernel can be simultaneously connected to one or more frontends. The
kernel has three sockets that serve the following functions:
-1. REQ: this socket is connected to a *single* frontend at a time, and it allows
- the kernel to request input from a frontend when :func:`raw_input` is called.
- The frontend holding the matching REP socket acts as a 'virtual keyboard'
+1. stdin: this ROUTER socket is connected to all frontends, and it allows
+ the kernel to request input from the active frontend when :func:`raw_input` is called.
+ The frontend that executed the code has a DEALER socket that acts as a 'virtual keyboard'
for the kernel while this communication is happening (illustrated in the
figure by the black outline around the central keyboard). In practice,
frontends may display such kernel requests using a special input widget or
otherwise indicating that the user is to type input for the kernel instead
of normal commands in the frontend.
-2. ROUTER: this single sockets allows multiple incoming connections from
+2. Shell: this single ROUTER socket allows multiple incoming connections from
frontends, and this is the socket where requests for code execution, object
information, prompts, etc. are made to the kernel by any frontend. The
communication on this socket is a sequence of request/reply actions from
each frontend and the kernel.
-3. PUB: this socket is the 'broadcast channel' where the kernel publishes all
+3. IOPub: this socket is the 'broadcast channel' where the kernel publishes all
side effects (stdout, stderr, etc.) as well as the requests coming from any
- client over the ROUTER socket and its own requests on the REP socket. There
+ client over the shell socket and its own requests on the stdin socket. There
are a number of actions in Python which generate side effects: :func:`print`
writes to ``sys.stdout``, errors generate tracebacks, etc. Additionally, in
a multi-client scenario, we want all frontends to be able to know what each
other has sent to the kernel (this can be useful in collaborative scenarios,
for example). This socket allows both side effects and the information
- about communications taking place with one client over the ROUTER/DEALER channel
+ about communications taking place with one client over the shell channel
to be made available to all clients in a uniform manner.
All messages are tagged with enough information (details below) for clients
@@ -126,8 +126,8 @@ For each message type, the actual content will differ and all existing message
types are specified in what follows of this document.
-Messages on the ROUTER/DEALER socket
-================================
+Messages on the shell ROUTER/DEALER sockets
+===========================================
.. _execute:
@@ -162,6 +162,12 @@ Message type: ``execute_request``::
# Similarly, a dict mapping names to expressions to be evaluated in the
# user's dict.
'user_expressions' : dict,
+
+ # Some frontends (e.g. the Notebook) do not support stdin requests. If
+ # raw_input is called from code executed from such a frontend, a
+ # StdinNotImplementedError will be raised.
+ 'allow_stdin' : True,
+
}
The ``code`` field contains a single string (possibly multiline). The kernel
@@ -637,7 +643,7 @@ Connect
When a client connects to the request/reply socket of the kernel, it can issue
a connect request to get basic information about the kernel, such as the ports
the other ZeroMQ sockets are listening on. This allows clients to only have
-to know about a single port (the DEALER/ROUTER channel) to connect to a kernel.
+to know about a single port (the shell channel) to connect to a kernel.
Message type: ``connect_request``::
@@ -647,9 +653,9 @@ Message type: ``connect_request``::
Message type: ``connect_reply``::
content = {
- 'xrep_port' : int # The port the ROUTER socket is listening on.
- 'pub_port' : int # The port the PUB socket is listening on.
- 'req_port' : int # The port the REQ socket is listening on.
+ 'shell_port' : int # The port the shell ROUTER socket is listening on.
+ 'iopub_port' : int # The port the PUB socket is listening on.
+ 'stdin_port' : int # The port the stdin ROUTER socket is listening on.
'hb_port' : int # The port the heartbeat socket is listening on.
}
@@ -863,15 +869,17 @@ Message type: ``file``::
'data' : str,
}
-
-Messages on the REQ/REP socket
-==============================
-This is a socket that goes in the opposite direction: from the kernel to a
-*single* frontend, and its purpose is to allow ``raw_input`` and similar
-operations that read from ``sys.stdin`` on the kernel to be fulfilled by the
-client. For now we will keep these messages as simple as possible, since they
-basically only mean to convey the ``raw_input(prompt)`` call.
+Messages on the stdin ROUTER/DEALER sockets
+===========================================
+
+This is a socket where the request/reply pattern goes in the opposite direction:
+from the kernel to a *single* frontend, and its purpose is to allow
+``raw_input`` and similar operations that read from ``sys.stdin`` on the kernel
+to be fulfilled by the client. The request should be made to the frontend that
+made the execution request that prompted ``raw_input`` to be called. For now we
+will keep these messages as simple as possible, since they only mean to convey
+the ``raw_input(prompt)`` call.
Message type: ``input_request``::
Please sign in to comment.
Something went wrong with that request. Please try again.