##// END OF EJS Templates
* Added a function for spawning a localhost kernel in a new process on random ports....
epatters -
Show More
@@ -1,82 +1,95 b''
1 # System library imports
1 # System library imports
2 from PyQt4 import QtCore, QtGui
2 from PyQt4 import QtCore, QtGui
3
3
4 # Local imports
4 # Local imports
5 from frontend_widget import FrontendWidget
5 from frontend_widget import FrontendWidget
6
6
7
7
8 class IPythonWidget(FrontendWidget):
8 class IPythonWidget(FrontendWidget):
9 """ A FrontendWidget for an IPython kernel.
9 """ A FrontendWidget for an IPython kernel.
10 """
10 """
11
11
12 #---------------------------------------------------------------------------
12 #---------------------------------------------------------------------------
13 # 'FrontendWidget' interface
13 # 'FrontendWidget' interface
14 #---------------------------------------------------------------------------
14 #---------------------------------------------------------------------------
15
15
16 def __init__(self, kernel_manager, parent=None):
16 def __init__(self, kernel_manager, parent=None):
17 super(IPythonWidget, self).__init__(kernel_manager, parent)
17 super(IPythonWidget, self).__init__(kernel_manager, parent)
18
18
19 self._magic_overrides = {}
19 self._magic_overrides = {}
20
20
21 def execute_source(self, source, hidden=False, interactive=False):
21 def execute_source(self, source, hidden=False, interactive=False):
22 """ Reimplemented to override magic commands.
22 """ Reimplemented to override magic commands.
23 """
23 """
24 magic_source = source.strip()
24 magic_source = source.strip()
25 if magic_source.startswith('%'):
25 if magic_source.startswith('%'):
26 magic_source = magic_source[1:]
26 magic_source = magic_source[1:]
27 magic, sep, arguments = magic_source.partition(' ')
27 magic, sep, arguments = magic_source.partition(' ')
28 if not magic:
28 if not magic:
29 magic = magic_source
29 magic = magic_source
30
30
31 callback = self._magic_overrides.get(magic)
31 callback = self._magic_overrides.get(magic)
32 if callback:
32 if callback:
33 output = callback(arguments)
33 output = callback(arguments)
34 if output:
34 if output:
35 self.appendPlainText(output)
35 self.appendPlainText(output)
36 self._show_prompt('>>> ')
36 self._show_prompt('>>> ')
37 return True
37 return True
38 else:
38 else:
39 return super(IPythonWidget, self).execute_source(source, hidden,
39 return super(IPythonWidget, self).execute_source(source, hidden,
40 interactive)
40 interactive)
41
41
42 #---------------------------------------------------------------------------
42 #---------------------------------------------------------------------------
43 # 'IPythonWidget' interface
43 # 'IPythonWidget' interface
44 #---------------------------------------------------------------------------
44 #---------------------------------------------------------------------------
45
45
46 def set_magic_override(self, magic, callback):
46 def set_magic_override(self, magic, callback):
47 """ Overrides an IPython magic command. This magic will be intercepted
47 """ Overrides an IPython magic command. This magic will be intercepted
48 by the frontend rather than passed on to the kernel and 'callback'
48 by the frontend rather than passed on to the kernel and 'callback'
49 will be called with a single argument: a string of argument(s) for
49 will be called with a single argument: a string of argument(s) for
50 the magic. The callback can (optionally) return text to print to the
50 the magic. The callback can (optionally) return text to print to the
51 console.
51 console.
52 """
52 """
53 self._magic_overrides[magic] = callback
53 self._magic_overrides[magic] = callback
54
54
55 def remove_magic_override(self, magic):
55 def remove_magic_override(self, magic):
56 """ Removes the override for the specified magic, if there is one.
56 """ Removes the override for the specified magic, if there is one.
57 """
57 """
58 try:
58 try:
59 del self._magic_overrides[magic]
59 del self._magic_overrides[magic]
60 except KeyError:
60 except KeyError:
61 pass
61 pass
62
62
63
63
64 if __name__ == '__main__':
64 if __name__ == '__main__':
65 import sys
65 from IPython.external.argparse import ArgumentParser
66 from IPython.frontend.qt.kernelmanager import QtKernelManager
66 from IPython.frontend.qt.kernelmanager import QtKernelManager
67
67
68 # Don't let Qt swallow KeyboardInterupts.
69 import signal
70 signal.signal(signal.SIGINT, signal.SIG_DFL)
71
72 # Parse command line arguments.
73 parser = ArgumentParser()
74 parser.add_argument('--ip', type=str, default='127.0.0.1',
75 help='set the kernel\'s IP address [default localhost]')
76 parser.add_argument('--xreq', type=int, metavar='PORT', default=5575,
77 help='set the XREQ Channel port [default %(default)i]')
78 parser.add_argument('--sub', type=int, metavar='PORT', default=5576,
79 help='set the SUB Channel port [default %(default)i]')
80 namespace = parser.parse_args()
81
68 # Create KernelManager
82 # Create KernelManager
69 kernel_manager = QtKernelManager(xreq_address = ('127.0.0.1', 5575),
83 ip = namespace.ip
70 sub_address = ('127.0.0.1', 5576),
84 kernel_manager = QtKernelManager(xreq_address = (ip, namespace.xreq),
71 rep_address = ('127.0.0.1', 5577))
85 sub_address = (ip, namespace.sub))
72 kernel_manager.sub_channel.start()
86 kernel_manager.start_listening()
73 kernel_manager.xreq_channel.start()
74
87
75 # Launch application
88 # Launch application
76 app = QtGui.QApplication(sys.argv)
89 app = QtGui.QApplication([])
77 widget = IPythonWidget(kernel_manager)
90 widget = IPythonWidget(kernel_manager)
78 widget.setWindowTitle('Python')
91 widget.setWindowTitle('Python')
79 widget.resize(640, 480)
92 widget.resize(640, 480)
80 widget.show()
93 widget.show()
81 sys.exit(app.exec_())
94 app.exec_()
82
95
@@ -1,311 +1,349 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 """A simple interactive kernel that talks to a frontend over 0MQ.
2 """A simple interactive kernel that talks to a frontend over 0MQ.
3
3
4 Things to do:
4 Things to do:
5
5
6 * Finish implementing `raw_input`.
6 * Finish implementing `raw_input`.
7 * Implement `set_parent` logic. Right before doing exec, the Kernel should
7 * Implement `set_parent` logic. Right before doing exec, the Kernel should
8 call set_parent on all the PUB objects with the message about to be executed.
8 call set_parent on all the PUB objects with the message about to be executed.
9 * Implement random port and security key logic.
9 * Implement random port and security key logic.
10 * Implement control messages.
10 * Implement control messages.
11 * Implement event loop and poll version.
11 * Implement event loop and poll version.
12 """
12 """
13
13
14 # Standard library imports.
14 import __builtin__
15 import __builtin__
15 import sys
16 import sys
16 import time
17 import time
17 import traceback
18 import traceback
18
19 from code import CommandCompiler
19 from code import CommandCompiler
20
20
21 # System library imports.
21 import zmq
22 import zmq
22
23
24 # Local imports.
23 from session import Session, Message, extract_header
25 from session import Session, Message, extract_header
24 from completer import KernelCompleter
26 from completer import KernelCompleter
25
27
28
26 class OutStream(object):
29 class OutStream(object):
27 """A file like object that publishes the stream to a 0MQ PUB socket."""
30 """A file like object that publishes the stream to a 0MQ PUB socket."""
28
31
29 def __init__(self, session, pub_socket, name, max_buffer=200):
32 def __init__(self, session, pub_socket, name, max_buffer=200):
30 self.session = session
33 self.session = session
31 self.pub_socket = pub_socket
34 self.pub_socket = pub_socket
32 self.name = name
35 self.name = name
33 self._buffer = []
36 self._buffer = []
34 self._buffer_len = 0
37 self._buffer_len = 0
35 self.max_buffer = max_buffer
38 self.max_buffer = max_buffer
36 self.parent_header = {}
39 self.parent_header = {}
37
40
38 def set_parent(self, parent):
41 def set_parent(self, parent):
39 self.parent_header = extract_header(parent)
42 self.parent_header = extract_header(parent)
40
43
41 def close(self):
44 def close(self):
42 self.pub_socket = None
45 self.pub_socket = None
43
46
44 def flush(self):
47 def flush(self):
45 if self.pub_socket is None:
48 if self.pub_socket is None:
46 raise ValueError(u'I/O operation on closed file')
49 raise ValueError(u'I/O operation on closed file')
47 else:
50 else:
48 if self._buffer:
51 if self._buffer:
49 data = ''.join(self._buffer)
52 data = ''.join(self._buffer)
50 content = {u'name':self.name, u'data':data}
53 content = {u'name':self.name, u'data':data}
51 msg = self.session.msg(u'stream', content=content,
54 msg = self.session.msg(u'stream', content=content,
52 parent=self.parent_header)
55 parent=self.parent_header)
53 print>>sys.__stdout__, Message(msg)
56 print>>sys.__stdout__, Message(msg)
54 self.pub_socket.send_json(msg)
57 self.pub_socket.send_json(msg)
55 self._buffer_len = 0
58 self._buffer_len = 0
56 self._buffer = []
59 self._buffer = []
57
60
58 def isattr(self):
61 def isattr(self):
59 return False
62 return False
60
63
61 def next(self):
64 def next(self):
62 raise IOError('Read not supported on a write only stream.')
65 raise IOError('Read not supported on a write only stream.')
63
66
64 def read(self, size=None):
67 def read(self, size=None):
65 raise IOError('Read not supported on a write only stream.')
68 raise IOError('Read not supported on a write only stream.')
66
69
67 readline=read
70 readline=read
68
71
69 def write(self, s):
72 def write(self, s):
70 if self.pub_socket is None:
73 if self.pub_socket is None:
71 raise ValueError('I/O operation on closed file')
74 raise ValueError('I/O operation on closed file')
72 else:
75 else:
73 self._buffer.append(s)
76 self._buffer.append(s)
74 self._buffer_len += len(s)
77 self._buffer_len += len(s)
75 self._maybe_send()
78 self._maybe_send()
76
79
77 def _maybe_send(self):
80 def _maybe_send(self):
78 if '\n' in self._buffer[-1]:
81 if '\n' in self._buffer[-1]:
79 self.flush()
82 self.flush()
80 if self._buffer_len > self.max_buffer:
83 if self._buffer_len > self.max_buffer:
81 self.flush()
84 self.flush()
82
85
83 def writelines(self, sequence):
86 def writelines(self, sequence):
84 if self.pub_socket is None:
87 if self.pub_socket is None:
85 raise ValueError('I/O operation on closed file')
88 raise ValueError('I/O operation on closed file')
86 else:
89 else:
87 for s in sequence:
90 for s in sequence:
88 self.write(s)
91 self.write(s)
89
92
90
93
91 class DisplayHook(object):
94 class DisplayHook(object):
92
95
93 def __init__(self, session, pub_socket):
96 def __init__(self, session, pub_socket):
94 self.session = session
97 self.session = session
95 self.pub_socket = pub_socket
98 self.pub_socket = pub_socket
96 self.parent_header = {}
99 self.parent_header = {}
97
100
98 def __call__(self, obj):
101 def __call__(self, obj):
99 if obj is None:
102 if obj is None:
100 return
103 return
101
104
102 __builtin__._ = obj
105 __builtin__._ = obj
103 msg = self.session.msg(u'pyout', {u'data':repr(obj)},
106 msg = self.session.msg(u'pyout', {u'data':repr(obj)},
104 parent=self.parent_header)
107 parent=self.parent_header)
105 self.pub_socket.send_json(msg)
108 self.pub_socket.send_json(msg)
106
109
107 def set_parent(self, parent):
110 def set_parent(self, parent):
108 self.parent_header = extract_header(parent)
111 self.parent_header = extract_header(parent)
109
112
110
113
111 class RawInput(object):
114 class RawInput(object):
112
115
113 def __init__(self, session, socket):
116 def __init__(self, session, socket):
114 self.session = session
117 self.session = session
115 self.socket = socket
118 self.socket = socket
116
119
117 def __call__(self, prompt=None):
120 def __call__(self, prompt=None):
118 msg = self.session.msg(u'raw_input')
121 msg = self.session.msg(u'raw_input')
119 self.socket.send_json(msg)
122 self.socket.send_json(msg)
120 while True:
123 while True:
121 try:
124 try:
122 reply = self.socket.recv_json(zmq.NOBLOCK)
125 reply = self.socket.recv_json(zmq.NOBLOCK)
123 except zmq.ZMQError, e:
126 except zmq.ZMQError, e:
124 if e.errno == zmq.EAGAIN:
127 if e.errno == zmq.EAGAIN:
125 pass
128 pass
126 else:
129 else:
127 raise
130 raise
128 else:
131 else:
129 break
132 break
130 return reply[u'content'][u'data']
133 return reply[u'content'][u'data']
131
134
132
135
133 class Kernel(object):
136 class Kernel(object):
134
137
135 def __init__(self, session, reply_socket, pub_socket):
138 def __init__(self, session, reply_socket, pub_socket):
136 self.session = session
139 self.session = session
137 self.reply_socket = reply_socket
140 self.reply_socket = reply_socket
138 self.pub_socket = pub_socket
141 self.pub_socket = pub_socket
139 self.user_ns = {}
142 self.user_ns = {}
140 self.history = []
143 self.history = []
141 self.compiler = CommandCompiler()
144 self.compiler = CommandCompiler()
142 self.completer = KernelCompleter(self.user_ns)
145 self.completer = KernelCompleter(self.user_ns)
143
146
144 # Build dict of handlers for message types
147 # Build dict of handlers for message types
145 msg_types = [ 'execute_request', 'complete_request',
148 msg_types = [ 'execute_request', 'complete_request',
146 'object_info_request' ]
149 'object_info_request' ]
147 self.handlers = {}
150 self.handlers = {}
148 for msg_type in msg_types:
151 for msg_type in msg_types:
149 self.handlers[msg_type] = getattr(self, msg_type)
152 self.handlers[msg_type] = getattr(self, msg_type)
150
153
151 def abort_queue(self):
154 def abort_queue(self):
152 while True:
155 while True:
153 try:
156 try:
154 ident = self.reply_socket.recv(zmq.NOBLOCK)
157 ident = self.reply_socket.recv(zmq.NOBLOCK)
155 except zmq.ZMQError, e:
158 except zmq.ZMQError, e:
156 if e.errno == zmq.EAGAIN:
159 if e.errno == zmq.EAGAIN:
157 break
160 break
158 else:
161 else:
159 assert self.reply_socket.rcvmore(), "Unexpected missing message part."
162 assert self.reply_socket.rcvmore(), "Unexpected missing message part."
160 msg = self.reply_socket.recv_json()
163 msg = self.reply_socket.recv_json()
161 print>>sys.__stdout__, "Aborting:"
164 print>>sys.__stdout__, "Aborting:"
162 print>>sys.__stdout__, Message(msg)
165 print>>sys.__stdout__, Message(msg)
163 msg_type = msg['msg_type']
166 msg_type = msg['msg_type']
164 reply_type = msg_type.split('_')[0] + '_reply'
167 reply_type = msg_type.split('_')[0] + '_reply'
165 reply_msg = self.session.msg(reply_type, {'status' : 'aborted'}, msg)
168 reply_msg = self.session.msg(reply_type, {'status' : 'aborted'}, msg)
166 print>>sys.__stdout__, Message(reply_msg)
169 print>>sys.__stdout__, Message(reply_msg)
167 self.reply_socket.send(ident,zmq.SNDMORE)
170 self.reply_socket.send(ident,zmq.SNDMORE)
168 self.reply_socket.send_json(reply_msg)
171 self.reply_socket.send_json(reply_msg)
169 # We need to wait a bit for requests to come in. This can probably
172 # We need to wait a bit for requests to come in. This can probably
170 # be set shorter for true asynchronous clients.
173 # be set shorter for true asynchronous clients.
171 time.sleep(0.1)
174 time.sleep(0.1)
172
175
173 def execute_request(self, ident, parent):
176 def execute_request(self, ident, parent):
174 try:
177 try:
175 code = parent[u'content'][u'code']
178 code = parent[u'content'][u'code']
176 except:
179 except:
177 print>>sys.__stderr__, "Got bad msg: "
180 print>>sys.__stderr__, "Got bad msg: "
178 print>>sys.__stderr__, Message(parent)
181 print>>sys.__stderr__, Message(parent)
179 return
182 return
180 pyin_msg = self.session.msg(u'pyin',{u'code':code}, parent=parent)
183 pyin_msg = self.session.msg(u'pyin',{u'code':code}, parent=parent)
181 self.pub_socket.send_json(pyin_msg)
184 self.pub_socket.send_json(pyin_msg)
182 try:
185 try:
183 comp_code = self.compiler(code, '<zmq-kernel>')
186 comp_code = self.compiler(code, '<zmq-kernel>')
184 sys.displayhook.set_parent(parent)
187 sys.displayhook.set_parent(parent)
185 exec comp_code in self.user_ns, self.user_ns
188 exec comp_code in self.user_ns, self.user_ns
186 except:
189 except:
187 result = u'error'
190 result = u'error'
188 etype, evalue, tb = sys.exc_info()
191 etype, evalue, tb = sys.exc_info()
189 tb = traceback.format_exception(etype, evalue, tb)
192 tb = traceback.format_exception(etype, evalue, tb)
190 exc_content = {
193 exc_content = {
191 u'status' : u'error',
194 u'status' : u'error',
192 u'traceback' : tb,
195 u'traceback' : tb,
193 u'etype' : unicode(etype),
196 u'etype' : unicode(etype),
194 u'evalue' : unicode(evalue)
197 u'evalue' : unicode(evalue)
195 }
198 }
196 exc_msg = self.session.msg(u'pyerr', exc_content, parent)
199 exc_msg = self.session.msg(u'pyerr', exc_content, parent)
197 self.pub_socket.send_json(exc_msg)
200 self.pub_socket.send_json(exc_msg)
198 reply_content = exc_content
201 reply_content = exc_content
199 else:
202 else:
200 reply_content = {'status' : 'ok'}
203 reply_content = {'status' : 'ok'}
201 reply_msg = self.session.msg(u'execute_reply', reply_content, parent)
204 reply_msg = self.session.msg(u'execute_reply', reply_content, parent)
202 print>>sys.__stdout__, Message(reply_msg)
205 print>>sys.__stdout__, Message(reply_msg)
203 self.reply_socket.send(ident, zmq.SNDMORE)
206 self.reply_socket.send(ident, zmq.SNDMORE)
204 self.reply_socket.send_json(reply_msg)
207 self.reply_socket.send_json(reply_msg)
205 if reply_msg['content']['status'] == u'error':
208 if reply_msg['content']['status'] == u'error':
206 self.abort_queue()
209 self.abort_queue()
207
210
208 def complete_request(self, ident, parent):
211 def complete_request(self, ident, parent):
209 matches = {'matches' : self.complete(parent),
212 matches = {'matches' : self.complete(parent),
210 'status' : 'ok'}
213 'status' : 'ok'}
211 completion_msg = self.session.send(self.reply_socket, 'complete_reply',
214 completion_msg = self.session.send(self.reply_socket, 'complete_reply',
212 matches, parent, ident)
215 matches, parent, ident)
213 print >> sys.__stdout__, completion_msg
216 print >> sys.__stdout__, completion_msg
214
217
215 def complete(self, msg):
218 def complete(self, msg):
216 return self.completer.complete(msg.content.line, msg.content.text)
219 return self.completer.complete(msg.content.line, msg.content.text)
217
220
218 def object_info_request(self, ident, parent):
221 def object_info_request(self, ident, parent):
219 context = parent['content']['oname'].split('.')
222 context = parent['content']['oname'].split('.')
220 object_info = self.object_info(context)
223 object_info = self.object_info(context)
221 msg = self.session.send(self.reply_socket, 'object_info_reply',
224 msg = self.session.send(self.reply_socket, 'object_info_reply',
222 object_info, parent, ident)
225 object_info, parent, ident)
223 print >> sys.__stdout__, msg
226 print >> sys.__stdout__, msg
224
227
225 def object_info(self, context):
228 def object_info(self, context):
226 symbol, leftover = self.symbol_from_context(context)
229 symbol, leftover = self.symbol_from_context(context)
227 if symbol is not None and not leftover:
230 if symbol is not None and not leftover:
228 doc = getattr(symbol, '__doc__', '')
231 doc = getattr(symbol, '__doc__', '')
229 else:
232 else:
230 doc = ''
233 doc = ''
231 object_info = dict(docstring = doc)
234 object_info = dict(docstring = doc)
232 return object_info
235 return object_info
233
236
234 def symbol_from_context(self, context):
237 def symbol_from_context(self, context):
235 if not context:
238 if not context:
236 return None, context
239 return None, context
237
240
238 base_symbol_string = context[0]
241 base_symbol_string = context[0]
239 symbol = self.user_ns.get(base_symbol_string, None)
242 symbol = self.user_ns.get(base_symbol_string, None)
240 if symbol is None:
243 if symbol is None:
241 symbol = __builtin__.__dict__.get(base_symbol_string, None)
244 symbol = __builtin__.__dict__.get(base_symbol_string, None)
242 if symbol is None:
245 if symbol is None:
243 return None, context
246 return None, context
244
247
245 context = context[1:]
248 context = context[1:]
246 for i, name in enumerate(context):
249 for i, name in enumerate(context):
247 new_symbol = getattr(symbol, name, None)
250 new_symbol = getattr(symbol, name, None)
248 if new_symbol is None:
251 if new_symbol is None:
249 return symbol, context[i:]
252 return symbol, context[i:]
250 else:
253 else:
251 symbol = new_symbol
254 symbol = new_symbol
252
255
253 return symbol, []
256 return symbol, []
254
257
255 def start(self):
258 def start(self):
256 while True:
259 while True:
257 ident = self.reply_socket.recv()
260 ident = self.reply_socket.recv()
258 assert self.reply_socket.rcvmore(), "Unexpected missing message part."
261 assert self.reply_socket.rcvmore(), "Unexpected missing message part."
259 msg = self.reply_socket.recv_json()
262 msg = self.reply_socket.recv_json()
260 omsg = Message(msg)
263 omsg = Message(msg)
261 print>>sys.__stdout__
264 print>>sys.__stdout__
262 print>>sys.__stdout__, omsg
265 print>>sys.__stdout__, omsg
263 handler = self.handlers.get(omsg.msg_type, None)
266 handler = self.handlers.get(omsg.msg_type, None)
264 if handler is None:
267 if handler is None:
265 print >> sys.__stderr__, "UNKNOWN MESSAGE TYPE:", omsg
268 print >> sys.__stderr__, "UNKNOWN MESSAGE TYPE:", omsg
266 else:
269 else:
267 handler(ident, omsg)
270 handler(ident, omsg)
268
271
269
272
270 def main():
273 def bind_port(socket, ip, port):
271 c = zmq.Context()
274 """ Binds the specified ZMQ socket. If the port is less than zero, a random
272
275 port is chosen. Returns the port that was bound.
273 ip = '127.0.0.1'
276 """
274 port_base = 5575
277 connection = 'tcp://%s' % ip
275 connection = ('tcp://%s' % ip) + ':%i'
278 if port < 0:
276 rep_conn = connection % port_base
279 port = socket.bind_to_random_port(connection)
277 pub_conn = connection % (port_base+1)
280 else:
278
281 connection += ':%i' % port
282 socket.bind(connection)
283 return port
284
285 def main(ip='127.0.0.1', rep_port=-1, pub_port=-1):
286 """ Start a kernel on 'ip' (default localhost) at the specified ports. If
287 ports are not specified, they are chosen at random.
288 """
279 print >>sys.__stdout__, "Starting the kernel..."
289 print >>sys.__stdout__, "Starting the kernel..."
280 print >>sys.__stdout__, "XREP Channel:", rep_conn
281 print >>sys.__stdout__, "PUB Channel:", pub_conn
282
290
291 context = zmq.Context()
283 session = Session(username=u'kernel')
292 session = Session(username=u'kernel')
284
293
285 reply_socket = c.socket(zmq.XREP)
294 reply_socket = context.socket(zmq.XREP)
286 reply_socket.bind(rep_conn)
295 rep_port = bind_port(reply_socket, ip, rep_port)
287
296 print >>sys.__stdout__, "XREP Channel on port", rep_port
288 pub_socket = c.socket(zmq.PUB)
289 pub_socket.bind(pub_conn)
290
297
291 stdout = OutStream(session, pub_socket, u'stdout')
298 pub_socket = context.socket(zmq.PUB)
292 stderr = OutStream(session, pub_socket, u'stderr')
299 pub_port = bind_port(pub_socket, ip, pub_port)
293 sys.stdout = stdout
300 print >>sys.__stdout__, "PUB Channel on port", pub_port
294 sys.stderr = stderr
295
301
296 display_hook = DisplayHook(session, pub_socket)
302 sys.stdout = OutStream(session, pub_socket, u'stdout')
297 sys.displayhook = display_hook
303 sys.stderr = OutStream(session, pub_socket, u'stderr')
304 sys.displayhook = DisplayHook(session, pub_socket)
298
305
299 kernel = Kernel(session, reply_socket, pub_socket)
306 kernel = Kernel(session, reply_socket, pub_socket)
300
307
301 # For debugging convenience, put sleep and a string in the namespace, so we
308 # For debugging convenience, put sleep and a string in the namespace, so we
302 # have them every time we start.
309 # have them every time we start.
303 kernel.user_ns['sleep'] = time.sleep
310 kernel.user_ns['sleep'] = time.sleep
304 kernel.user_ns['s'] = 'Test string'
311 kernel.user_ns['s'] = 'Test string'
305
312
306 print >>sys.__stdout__, "Use Ctrl-\\ (NOT Ctrl-C!) to terminate."
313 print >>sys.__stdout__, "Use Ctrl-\\ (NOT Ctrl-C!) to terminate."
307 kernel.start()
314 kernel.start()
308
315
316 def launch_kernel():
317 """ Launches a kernel on this machine and binds its to channels to open
318 ports as it determined by the OS.
319
320 Returns a tuple of form:
321 (kernel_process [Popen], rep_port [int], sub_port [int])
322 """
323 import socket
324 from subprocess import Popen
325
326 # Find some open ports.
327 ports = []
328 for i in xrange(2):
329 sock = socket.socket()
330 sock.bind(('', 0))
331 ports.append(sock)
332 for i, sock in enumerate(ports):
333 port = sock.getsockname()[1]
334 sock.close()
335 ports[i] = port
336 rep_port, sub_port = ports
337
338 # Spawn a kernel.
339 command = 'from IPython.zmq.kernel import main;' \
340 'main(rep_port=%i, pub_port=%i)'
341 proc = Popen([sys.executable, '-c', command % (rep_port, sub_port)])
342
343 return proc, rep_port, sub_port
344
309
345
310 if __name__ == '__main__':
346 if __name__ == '__main__':
311 main()
347 base_port = 5575
348 main(rep_port = base_port,
349 pub_port = base_port + 1)
General Comments 0
You need to be logged in to leave comments. Login now