##// END OF EJS Templates
two-process interactive shell progress...
two-process interactive shell progress * execute payloads (e.g. page/pinfo output) are displayed and paged. * aborted replies don't crash frontend. * intermediate iopub is displayed as it comes * wait for kernel to start before printing first prompt. This gets the right number on the first prompt, and also avoids the log output from being drawn after the first prompt. * protect most of the interact block from keyboard interrupts, which could cause weird errors if ctrl-C was held for a while. * separate restart/wait prompt when kernel dies.

File last commit:

r5611:fd342639
r5616:7431cd60
Show More
frontend.py
253 lines | 9.7 KiB | text/x-python | PythonLexer
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578 # -*- coding: utf-8 -*-
"""Frontend of ipython working with python-zmq
Ipython's frontend, is a ipython interface that send request to kernel and proccess the kernel's outputs.
For more details, see the ipython-zmq design
"""
#-----------------------------------------------------------------------------
# Copyright (C) 2010 The IPython Development Team
#
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
Thomas Kluyver
Nicer prompt formatting in zmqterminal, and use print_function.
r5598 from __future__ import print_function
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578
import __builtin__
import sys
import os
Thomas Kluyver
Refactor and simplification of zmqterminal.
r5596 from Queue import Empty
Omar Andres Zapata Mesa
raw_input captured and working fine
r5583 import readline
Omar Andres Zapata Mesa
tab completion is not working yet, unknow error
r5585 import rlcompleter
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578
#-----------------------------------------------------------------------------
# Imports from ipython
#-----------------------------------------------------------------------------
from IPython.external.argparse import ArgumentParser
Thomas Kluyver
zmqterminal frontend now uses IPythonInputSplitter, and non-ascii characters work.
r5593 from IPython.core.inputsplitter import IPythonInputSplitter
Thomas Kluyver
Refactor and simplification of zmqterminal.
r5596 from IPython.zmq.blockingkernelmanager import BlockingKernelManager as KernelManager
MinRK
Move IPython.frontend.zmqterminal to IPython.frontend.terminal.console
r5611 from IPython.frontend.terminal.console.completer import ClientCompleter2p
Omar Andres Zapata Mesa
tab completion is not working yet, unknow error
r5585
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578 #-----------------------------------------------------------------------------
# Network Constants
#-----------------------------------------------------------------------------
from IPython.utils.localinterfaces import LOCALHOST, LOCAL_IPS
class Frontend(object):
Thomas Kluyver
Refactor and simplification of zmqterminal.
r5596 """This class is a simple frontend to ipython-zmq
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578
Thomas Kluyver
Minor tidying up of zmqterminal.frontend
r5594 NOTE: this class uses kernelmanager to manipulate sockets
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578
Parameters:
-----------
kernelmanager : object
instantiated object from class KernelManager in module kernelmanager
Thomas Kluyver
Refactor and simplification of zmqterminal.
r5596 """
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578
Thomas Kluyver
Refactor and simplification of zmqterminal.
r5596 def __init__(self, kernelmanager):
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578 self.km = kernelmanager
Thomas Kluyver
Simplify handling of messaging in zmqterminal.
r5597 self.session_id = self.km.session.session
Thomas Kluyver
Refactor and simplification of zmqterminal.
r5596 self.completer = ClientCompleter2p(self, self.km)
Omar Andres Zapata Mesa
raw_input captured and working fine
r5583 readline.parse_and_bind("tab: complete")
readline.parse_and_bind('set show-all-if-ambiguous on')
Omar Andres Zapata Mesa
tab completion is not working yet, unknow error
r5585 readline.set_completer(self.completer.complete)
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578 history_path = os.path.expanduser('~/.ipython/history')
if os.path.isfile(history_path):
rlcompleter.readline.read_history_file(history_path)
else:
Thomas Kluyver
Minor tidying up of zmqterminal.frontend
r5594 print("history file cannot be read.")
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578
self.messages = {}
Omar Andres Zapata Mesa
working in handlers
r5579
Thomas Kluyver
zmqterminal frontend now uses IPythonInputSplitter, and non-ascii characters work.
r5593 self._splitter = IPythonInputSplitter()
Omar Andres Zapata Mesa
working in tab completion
r5580 self.code = ""
Omar Andres Zapata Mesa
bug fixed prompt count using differents clients
r5588
Thomas Kluyver
Minor tidying up of zmqterminal.frontend
r5594 self.prompt_count = 0
self._get_initial_prompt()
Omar Andres Zapata Mesa
bug fixed prompt count using differents clients
r5588
Thomas Kluyver
Refactor and simplification of zmqterminal.
r5596 def _get_initial_prompt(self):
Omar Andres Zapata Mesa
bug fixed prompt count using differents clients
r5588 self._execute('', hidden=True)
Thomas Kluyver
Refactor and simplification of zmqterminal.
r5596 def interact(self):
Thomas Kluyver
Minor tidying up of zmqterminal.frontend
r5594 """Gets input from console using inputsplitter, then
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578 while you enter code it can indent and set index id to any input
"""
Omar Andres Zapata Mesa
working in tab completion
r5580
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578 try:
Thomas Kluyver
Nicer prompt formatting in zmqterminal, and use print_function.
r5598 print()
MinRK
rebased and updated to master
r5599 self._splitter.push(raw_input('In [%i]: '%self.prompt_count+self.code))
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578 while self._splitter.push_accepts_more():
MinRK
rebased and updated to master
r5599 self.code = raw_input('.....: '+' '*self._splitter.indent_spaces)
Omar Andres Zapata Mesa
working in tab completion
r5580 self._splitter.push(' '*self._splitter.indent_spaces+self.code)
self._execute(self._splitter.source,False)
self._splitter.reset()
Thomas Kluyver
Minor tidying up of zmqterminal.frontend
r5594 except KeyboardInterrupt:
Omar Andres Zapata Mesa
working in handlers
r5579 print('\nKeyboardInterrupt\n')
pass
Omar Andres Zapata Mesa
working in tab completion
r5580
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578
Thomas Kluyver
Refactor and simplification of zmqterminal.
r5596 def start(self):
Thomas Kluyver
Minor tidying up of zmqterminal.frontend
r5594 """Start the interaction loop, calling the .interact() method for each
input cell.
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578 """
while True:
try:
Omar Andres Zapata Mesa
working in handlers
r5579 self.interact()
Thomas Kluyver
Minor tidying up of zmqterminal.frontend
r5594 except KeyboardInterrupt:
Omar Andres Zapata Mesa
working in handlers
r5579 print('\nKeyboardInterrupt\n')
pass
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578 except EOFError:
answer = ''
while True:
answer = raw_input('\nDo you really want to exit ([y]/n)?')
if answer == 'y' or answer == '' :
Thomas Kluyver
Replace tabs with spaces
r5591 self.km.shutdown_kernel()
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578 sys.exit()
elif answer == 'n':
break
Omar Andres Zapata Mesa
tab completion is not working yet, unknow error
r5585
Thomas Kluyver
Refactor and simplification of zmqterminal.
r5596 def _execute(self, source, hidden = True):
""" Execute 'source'. If 'hidden', do not show any output.
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578
See parent class :meth:`execute` docstring for full details.
Thomas Kluyver
Refactor and simplification of zmqterminal.
r5596 """
MinRK
rebased and updated to master
r5599 msg_id = self.km.shell_channel.execute(source, hidden)
while not self.km.shell_channel.msg_ready():
Thomas Kluyver
Refactor and simplification of zmqterminal.
r5596 try:
MinRK
rebased and updated to master
r5599 self.handle_stdin_channel(timeout=0.1)
Thomas Kluyver
Refactor and simplification of zmqterminal.
r5596 except Empty:
pass
Thomas Kluyver
Simplify handling of messaging in zmqterminal.
r5597 self.handle_execute_reply(msg_id)
def handle_execute_reply(self, msg_id):
MinRK
rebased and updated to master
r5599 msg = self.km.shell_channel.get_msg()
if msg["parent_header"]["msg_id"] == msg_id:
if msg["content"]["status"] == 'ok' :
Thomas Kluyver
Simplify handling of messaging in zmqterminal.
r5597 self.handle_sub_channel()
Thomas Kluyver
Refactor and simplification of zmqterminal.
r5596
MinRK
rebased and updated to master
r5599 elif msg["content"]["status"] == 'error':
for frame in msg["content"]["traceback"]:
Thomas Kluyver
Nicer prompt formatting in zmqterminal, and use print_function.
r5598 print(frame, file=sys.stderr)
MinRK
rebased and updated to master
r5599 self.prompt_count = msg["content"]["execution_count"] + 1
Omar Andres Zapata Mesa
working in handlers
r5579
Thomas Kluyver
Refactor and simplification of zmqterminal.
r5596 def handle_sub_channel(self):
Omar Andres Zapata Mesa
working in handlers
r5579 """ Method to procces subscribe channel's messages
Thomas Kluyver
Minor tidying up of zmqterminal.frontend
r5594 This method reads a message and processes the content in different
outputs like stdout, stderr, pyout and status
Omar Andres Zapata Mesa
working in handlers
r5579
Arguments:
sub_msg: message receive from kernel in the sub socket channel
capture by kernel manager.
"""
Thomas Kluyver
Refactor and simplification of zmqterminal.
r5596 while self.km.sub_channel.msg_ready():
Omar Andres Zapata Mesa
working in handlers
r5579 sub_msg = self.km.sub_channel.get_msg()
Thomas Kluyver
Simplify handling of messaging in zmqterminal.
r5597 if self.session_id == sub_msg['parent_header']['session']:
Omar Andres Zapata Mesa
working in handlers
r5579 if sub_msg['msg_type'] == 'status' :
if sub_msg["content"]["execution_state"] == "busy" :
pass
Thomas Kluyver
Simplify handling of messaging in zmqterminal.
r5597 elif sub_msg['msg_type'] == 'stream' :
Omar Andres Zapata Mesa
working in handlers
r5579 if sub_msg["content"]["name"] == "stdout":
Thomas Kluyver
Nicer prompt formatting in zmqterminal, and use print_function.
r5598 print(sub_msg["content"]["data"], file=sys.stdout, end="")
Omar Andres Zapata Mesa
working in handlers
r5579 sys.stdout.flush()
Thomas Kluyver
Simplify handling of messaging in zmqterminal.
r5597 elif sub_msg["content"]["name"] == "stderr" :
Thomas Kluyver
Nicer prompt formatting in zmqterminal, and use print_function.
r5598 print(sub_msg["content"]["data"], file=sys.stderr, end="")
Omar Andres Zapata Mesa
working in handlers
r5579 sys.stderr.flush()
Thomas Kluyver
Simplify handling of messaging in zmqterminal.
r5597 elif sub_msg['msg_type'] == 'pyout' :
Thomas Kluyver
Nicer prompt formatting in zmqterminal, and use print_function.
r5598 print("Out[%i]:"%sub_msg["content"]["execution_count"],
sub_msg["content"]["data"]["text/plain"],
file=sys.stdout)
Omar Andres Zapata Mesa
working in handlers
r5579 sys.stdout.flush()
MinRK
rebased and updated to master
r5599 def handle_stdin_channel(self, timeout=0.1):
Thomas Kluyver
Refactor and simplification of zmqterminal.
r5596 """ Method to capture raw_input
"""
MinRK
rebased and updated to master
r5599 msg_rep = self.km.stdin_channel.get_msg(timeout=timeout)
Thomas Kluyver
Simplify handling of messaging in zmqterminal.
r5597 if self.session_id == msg_rep["parent_header"]["session"] :
raw_data = raw_input(msg_rep["content"]["prompt"])
MinRK
rebased and updated to master
r5599 self.km.stdin_channel.input(raw_data)
Thomas Kluyver
Replace tabs with spaces
r5591
Omar Andres Zapata Mesa
raw_input captured and working fine
r5583
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578
def start_frontend():
""" Entry point for application.
Omar Andres Zapata Mesa
working in handlers
r5579
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578 """
# Parse command line arguments.
parser = ArgumentParser()
kgroup = parser.add_argument_group('kernel options')
kgroup.add_argument('-e', '--existing', action='store_true',
help='connect to an existing kernel')
kgroup.add_argument('--ip', type=str, default=LOCALHOST,
help=\
"set the kernel\'s IP address [default localhost].\
If the IP address is something other than localhost, then \
Consoles on other machines will be able to connect\
to the Kernel, so be careful!")
MinRK
rebased and updated to master
r5599 kgroup.add_argument('--shell', type=int, metavar='PORT', default=0,
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578 help='set the XREQ channel port [default random]')
MinRK
rebased and updated to master
r5599 kgroup.add_argument('--iopub', type=int, metavar='PORT', default=0,
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578 help='set the SUB channel port [default random]')
MinRK
rebased and updated to master
r5599 kgroup.add_argument('--stdin', type=int, metavar='PORT', default=0,
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578 help='set the REP channel port [default random]')
kgroup.add_argument('--hb', type=int, metavar='PORT', default=0,
help='set the heartbeat port [default random]')
egroup = kgroup.add_mutually_exclusive_group()
egroup.add_argument('--pure', action='store_true', help = \
'use a pure Python kernel instead of an IPython kernel')
egroup.add_argument('--pylab', type=str, metavar='GUI', nargs='?',
const='auto', help = \
"Pre-load matplotlib and numpy for interactive use. If GUI is not \
given, the GUI backend is matplotlib's, otherwise use one of: \
['tk', 'gtk', 'qt', 'wx', 'inline'].")
egroup.add_argument('--colors', type=str,
help="Set the color scheme (LightBG,Linux,NoColor). This is guessed\
based on the pygments style if not set.")
args = parser.parse_args()
# parse the colors arg down to current known labels
if args.colors:
colors=args.colors.lower()
if colors in ('lightbg', 'light'):
colors='lightbg'
elif colors in ('dark', 'linux'):
colors='linux'
else:
colors='nocolor'
else:
colors=None
# Create a KernelManager and start a kernel.
MinRK
rebased and updated to master
r5599 kernel_manager = KernelManager(shell_address=(args.ip, args.shell),
sub_address=(args.ip, args.iopub),
stdin_address=(args.ip, args.stdin),
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578 hb_address=(args.ip, args.hb))
if not args.existing:
# if not args.ip in LOCAL_IPS+ALL_ALIAS:
# raise ValueError("Must bind a local ip, such as: %s"%LOCAL_IPS)
MinRK
rebased and updated to master
r5599 kwargs = dict(ip=args.ip, ipython=True)
Omar Andres Zapata Mesa
basic kernelmanager and frontend wrote, support indentation but it dont run code yet
r5578 kernel_manager.start_kernel(**kwargs)
kernel_manager.start_channels()
frontend=Frontend(kernel_manager)
return frontend
if __name__ == "__main__" :
frontend=start_frontend()
Thomas Kluyver
Replace tabs with spaces
r5591 frontend.start()