app.py
156 lines
| 5.2 KiB
| text/x-python
|
PythonLexer
Paul Ivanov
|
r5604 | """ A minimal application using the ZMQ-based terminal IPython frontend. | ||
MinRK
|
r5600 | |||
Paul Ivanov
|
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
|
r5600 | import signal | ||
import sys | ||||
import time | ||||
MinRK
|
r5610 | from IPython.frontend.terminal.ipapp import TerminalIPythonApp, frontend_flags as term_flags | ||
MinRK
|
r5600 | |||
from IPython.utils.traitlets import ( | ||||
Dict, List, Unicode, Int, CaselessStrEnum, CBool, Any | ||||
) | ||||
MinRK
|
r5615 | from IPython.utils.warn import warn,error | ||
Paul Ivanov
|
r5604 | from IPython.zmq.ipkernel import IPKernelApp | ||
from IPython.zmq.session import Session, default_secure | ||||
MinRK
|
r5600 | from IPython.zmq.zmqshell import ZMQInteractiveShell | ||
MinRK
|
r5618 | from IPython.frontend.consoleapp import ( | ||
IPythonConsoleApp, app_aliases, app_flags, aliases, app_aliases, flags | ||||
Paul Ivanov
|
r5604 | ) | ||
MinRK
|
r5611 | from IPython.frontend.terminal.console.interactiveshell import ZMQTerminalInteractiveShell | ||
MinRK
|
r5600 | |||
#----------------------------------------------------------------------------- | ||||
Paul Ivanov
|
r5604 | # Globals | ||
MinRK
|
r5600 | #----------------------------------------------------------------------------- | ||
Paul Ivanov
|
r5604 | _examples = """ | ||
ipython console # start the ZMQ-based console | ||||
Paul Ivanov
|
r5607 | ipython console --existing # connect to an existing ipython session | ||
Paul Ivanov
|
r5604 | """ | ||
MinRK
|
r5600 | |||
#----------------------------------------------------------------------------- | ||||
# Flags and Aliases | ||||
#----------------------------------------------------------------------------- | ||||
MinRK
|
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
|
r5600 | flags.update(frontend_flags) | ||
Paul Ivanov
|
r5604 | |||
MinRK
|
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
|
r5604 | |||
MinRK
|
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
|
r5600 | |||
#----------------------------------------------------------------------------- | ||||
# Classes | ||||
#----------------------------------------------------------------------------- | ||||
MinRK
|
r5618 | class ZMQTerminalIPythonApp(TerminalIPythonApp, IPythonConsoleApp): | ||
MinRK
|
r5610 | name = "ipython-console" | ||
MinRK
|
r5600 | """Start a terminal frontend to the IPython zmq kernel.""" | ||
Paul Ivanov
|
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
|
r5610 | classes = List([IPKernelApp, ZMQTerminalInteractiveShell, Session]) | ||
MinRK
|
r5600 | flags = Dict(flags) | ||
aliases = Dict(aliases) | ||||
MinRK
|
r5620 | frontend_aliases = Any(frontend_aliases) | ||
frontend_flags = Any(frontend_flags) | ||||
Paul Ivanov
|
r5607 | subcommands = Dict() | ||
MinRK
|
r5610 | |||
MinRK
|
r5600 | def parse_command_line(self, argv=None): | ||
super(ZMQTerminalIPythonApp, self).parse_command_line(argv) | ||||
MinRK
|
r5620 | self.build_kernel_argv(argv) | ||
MinRK
|
r5600 | |||
def init_shell(self): | ||||
MinRK
|
r5618 | IPythonConsoleApp.initialize(self) | ||
Paul Ivanov
|
r5605 | # relay sigint to kernel | ||
signal.signal(signal.SIGINT, self.handle_sigint) | ||||
MinRK
|
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
|
r5604 | |||
MinRK
|
r5764 | def init_gui_pylab(self): | ||
# no-op, because we don't want to import matplotlib in the frontend. | ||||
pass | ||||
MinRK
|
r5600 | def handle_sigint(self, *args): | ||
MinRK
|
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
|
r5608 | else: | ||
MinRK
|
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
|
r5604 | |||
MinRK
|
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() | ||||