##// END OF EJS Templates
Merge pull request #864 from ipython/termzmq...
Merge pull request #864 from ipython/termzmq Two-process terminal frontend: this branch adds a new IPython frontend, invoked via ipython console that behaves much like the regular, old ipython, but runs over zeromq in two processes. This means that such a client can connect to existing kernels initiated by the Qt console, the notebook or standalone (i.e. via `ipython kernel`). We still have some internal architectural cleanups to perform to simplify how the various frontends talk to the kernels, but by having this main piece in, the complete picture is clearer, and that refactoring work can be carried post-0.12. This frontend should still be considered experimental.

File last commit:

r5620:5e833cd7
r5633:afa2b63b merge
Show More
app.py
152 lines | 5.1 KiB | text/x-python | PythonLexer
Paul Ivanov
zmqterminal now uses the zmq mixin app
r5604 """ A minimal application using the ZMQ-based terminal IPython frontend.
MinRK
zmqterminal subclasses TerminalInteractiveShell/IPApp...
r5600
Paul Ivanov
zmqterminal now uses the zmq mixin app
r5604 This is not a complete console app, as subprocess will not be able to receive
input, there is no real readline support, among other limitations.
Authors:
* Min RK
* Paul Ivanov
"""
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
MinRK
zmqterminal subclasses TerminalInteractiveShell/IPApp...
r5600 import signal
import sys
import time
MinRK
update flags&aliases for two-process apps...
r5610 from IPython.frontend.terminal.ipapp import TerminalIPythonApp, frontend_flags as term_flags
MinRK
zmqterminal subclasses TerminalInteractiveShell/IPApp...
r5600
from IPython.utils.traitlets import (
Dict, List, Unicode, Int, CaselessStrEnum, CBool, Any
)
MinRK
Adjustment to console signal-handling...
r5615 from IPython.utils.warn import warn,error
Paul Ivanov
zmqterminal now uses the zmq mixin app
r5604 from IPython.zmq.ipkernel import IPKernelApp
from IPython.zmq.session import Session, default_secure
MinRK
zmqterminal subclasses TerminalInteractiveShell/IPApp...
r5600 from IPython.zmq.zmqshell import ZMQInteractiveShell
MinRK
rename IPythonMixinConsoleApp to IPythonConsoleApp...
r5618 from IPython.frontend.consoleapp import (
IPythonConsoleApp, app_aliases, app_flags, aliases, app_aliases, flags
Paul Ivanov
zmqterminal now uses the zmq mixin app
r5604 )
MinRK
Move IPython.frontend.zmqterminal to IPython.frontend.terminal.console
r5611 from IPython.frontend.terminal.console.interactiveshell import ZMQTerminalInteractiveShell
MinRK
zmqterminal subclasses TerminalInteractiveShell/IPApp...
r5600
#-----------------------------------------------------------------------------
Paul Ivanov
zmqterminal now uses the zmq mixin app
r5604 # Globals
MinRK
zmqterminal subclasses TerminalInteractiveShell/IPApp...
r5600 #-----------------------------------------------------------------------------
Paul Ivanov
zmqterminal now uses the zmq mixin app
r5604 _examples = """
ipython console # start the ZMQ-based console
Paul Ivanov
documentation update
r5607 ipython console --existing # connect to an existing ipython session
Paul Ivanov
zmqterminal now uses the zmq mixin app
r5604 """
MinRK
zmqterminal subclasses TerminalInteractiveShell/IPApp...
r5600
#-----------------------------------------------------------------------------
# Flags and Aliases
#-----------------------------------------------------------------------------
MinRK
update flags&aliases for two-process apps...
r5610 # copy flags from mixin:
flags = dict(flags)
# start with mixin frontend flags:
frontend_flags = dict(app_flags)
# add TerminalIPApp flags:
frontend_flags.update(term_flags)
# pylab is not frontend-specific in two-process IPython
frontend_flags.pop('pylab')
# disable quick startup, as it won't propagate to the kernel anyway
frontend_flags.pop('quick')
# update full dict with frontend flags:
MinRK
zmqterminal subclasses TerminalInteractiveShell/IPApp...
r5600 flags.update(frontend_flags)
Paul Ivanov
zmqterminal now uses the zmq mixin app
r5604
MinRK
update flags&aliases for two-process apps...
r5610 # copy flags from mixin
aliases = dict(aliases)
# start with mixin frontend flags
frontend_aliases = dict(app_aliases)
# load updated frontend flags into full dict
aliases.update(frontend_aliases)
Paul Ivanov
zmqterminal now uses the zmq mixin app
r5604
MinRK
update flags&aliases for two-process apps...
r5610 # get flags&aliases into sets, and remove a couple that
# shouldn't be scrubbed from backend flags:
frontend_aliases = set(frontend_aliases.keys())
frontend_flags = set(frontend_flags.keys())
MinRK
zmqterminal subclasses TerminalInteractiveShell/IPApp...
r5600
#-----------------------------------------------------------------------------
# Classes
#-----------------------------------------------------------------------------
MinRK
rename IPythonMixinConsoleApp to IPythonConsoleApp...
r5618 class ZMQTerminalIPythonApp(TerminalIPythonApp, IPythonConsoleApp):
MinRK
update flags&aliases for two-process apps...
r5610 name = "ipython-console"
MinRK
zmqterminal subclasses TerminalInteractiveShell/IPApp...
r5600 """Start a terminal frontend to the IPython zmq kernel."""
Paul Ivanov
documentation update
r5607
description = """
The IPython terminal-based Console.
This launches a Console application inside a terminal.
The Console supports various extra features beyond the traditional
single-process Terminal IPython shell, such as connecting to an
existing ipython session, via:
ipython console --existing
where the previous session could have been created by another ipython
console, an ipython qtconsole, or by opening an ipython notebook.
"""
examples = _examples
MinRK
update flags&aliases for two-process apps...
r5610 classes = List([IPKernelApp, ZMQTerminalInteractiveShell, Session])
MinRK
zmqterminal subclasses TerminalInteractiveShell/IPApp...
r5600 flags = Dict(flags)
aliases = Dict(aliases)
MinRK
Split swallow_argv into standalone function in lib.kernel...
r5620 frontend_aliases = Any(frontend_aliases)
frontend_flags = Any(frontend_flags)
Paul Ivanov
documentation update
r5607 subcommands = Dict()
MinRK
update flags&aliases for two-process apps...
r5610
MinRK
zmqterminal subclasses TerminalInteractiveShell/IPApp...
r5600 def parse_command_line(self, argv=None):
super(ZMQTerminalIPythonApp, self).parse_command_line(argv)
MinRK
Split swallow_argv into standalone function in lib.kernel...
r5620 self.build_kernel_argv(argv)
MinRK
zmqterminal subclasses TerminalInteractiveShell/IPApp...
r5600
def init_shell(self):
MinRK
rename IPythonMixinConsoleApp to IPythonConsoleApp...
r5618 IPythonConsoleApp.initialize(self)
Paul Ivanov
restore KeyboardInterrupt capability
r5605 # relay sigint to kernel
signal.signal(signal.SIGINT, self.handle_sigint)
MinRK
zmqterminal subclasses TerminalInteractiveShell/IPApp...
r5600 self.shell = ZMQTerminalInteractiveShell.instance(config=self.config,
display_banner=False, profile_dir=self.profile_dir,
ipython_dir=self.ipython_dir, kernel_manager=self.kernel_manager)
Paul Ivanov
zmqterminal now uses the zmq mixin app
r5604
MinRK
zmqterminal subclasses TerminalInteractiveShell/IPApp...
r5600 def handle_sigint(self, *args):
MinRK
Adjustment to console signal-handling...
r5615 if self.shell._executing:
if self.kernel_manager.has_kernel:
# interrupt already gets passed to subprocess by signal handler.
# Only if we prevent that should we need to explicitly call
# interrupt_kernel, until which time, this would result in a
# double-interrupt:
# self.kernel_manager.interrupt_kernel()
pass
else:
self.shell.write_err('\n')
error("Cannot interrupt kernels we didn't start.\n")
Paul Ivanov
report inability to signal --existing kernels
r5608 else:
MinRK
Adjustment to console signal-handling...
r5615 # raise the KeyboardInterrupt if we aren't waiting for execution,
# so that the interact loop advances, and prompt is redrawn, etc.
raise KeyboardInterrupt
Paul Ivanov
zmqterminal now uses the zmq mixin app
r5604
MinRK
zmqterminal subclasses TerminalInteractiveShell/IPApp...
r5600 def init_code(self):
# no-op in the frontend, code gets run in the backend
pass
def launch_new_instance():
"""Create and run a full blown IPython instance"""
app = ZMQTerminalIPythonApp.instance()
app.initialize()
app.start()
if __name__ == '__main__':
launch_new_instance()