##// END OF EJS Templates
* Added a function for spawning a localhost kernel in a new process on random ports....
epatters -
Show More
@@ -62,21 +62,34 b' class IPythonWidget(FrontendWidget):'
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
@@ -11,18 +11,21 b' Things to do:'
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
@@ -267,34 +270,38 b' class Kernel(object):'
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
@@ -306,6 +313,37 b' def main():'
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