##// END OF EJS Templates
Refactor and simplification of zmqterminal.
Refactor and simplification of zmqterminal.

File last commit:

r5596:1f9a029b
r5596:1f9a029b
Show More
frontend.py
266 lines | 10.4 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
#-----------------------------------------------------------------------------
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
Thomas Kluyver
Separate out frontend.zmqterminal package.
r5592 from IPython.frontend.zmqterminal.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
self.session = kernelmanager.session
self.request_socket = self.km.xreq_channel.socket
self.sub_socket = self.km.sub_channel.socket
self.reply_socket = self.km.rep_channel.socket
Omar Andres Zapata Mesa
tab completion is not working yet, unknow error
r5585 self.msg_header = self.km.session.msg_header()
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:
Omar Andres Zapata Mesa
working in tab completion
r5580 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():
Omar Andres Zapata Mesa
working in tab completion
r5580 self.code = raw_input('.....:'+' '*self._splitter.indent_spaces)
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 """
self.km.xreq_channel.execute(source, hidden)
while not self.km.xreq_channel.msg_ready():
try:
self.handle_rep_channel(timeout=0.1)
except Empty:
pass
self.handle_xreq_channel()
Omar Andres Zapata Mesa
completer not working fine
r5581
Thomas Kluyver
Refactor and simplification of zmqterminal.
r5596 def handle_xreq_channel(self):
self.msg_xreq = self.km.xreq_channel.get_msg()
if self.msg_header["session"] == self.msg_xreq["parent_header"]["session"]:
if self.msg_xreq["content"]["status"] == 'ok' :
if self.msg_xreq["msg_type"] == "execute_reply" :
self.handle_sub_channel()
self.prompt_count = self.msg_xreq["content"]["execution_count"]+1
else:
etb = self.msg_xreq["content"]["traceback"]
print >> sys.stderr, etb[0]
try: # These bits aren't there for a SyntaxError
print >> sys.stderr, etb[1]
print >> sys.stderr, etb[2]
except IndexError:
pass
self.prompt_count = self.msg_xreq["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
Minor tidying up of zmqterminal.frontend
r5594 if self.msg_header["username"] == sub_msg['parent_header']['username'] and \
self.km.session.session == 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
if sub_msg['msg_type'] == 'stream' :
if sub_msg["content"]["name"] == "stdout":
print >> sys.stdout,sub_msg["content"]["data"]
sys.stdout.flush()
Omar Andres Zapata Mesa
working in tab completion
r5580 if sub_msg["content"]["name"] == "stderr" :
Omar Andres Zapata Mesa
working in handlers
r5579 print >> sys.stderr,sub_msg["content"]["data"]
sys.stderr.flush()
if sub_msg['msg_type'] == 'pyout' :
Omar Andres Zapata Mesa
little bug fixed in pyout message print.
r5587 print >> sys.stdout,"Out[%i]:"%sub_msg["content"]["execution_count"], sub_msg["content"]["data"]["text/plain"]
Omar Andres Zapata Mesa
working in handlers
r5579 sys.stdout.flush()
Thomas Kluyver
Refactor and simplification of zmqterminal.
r5596 def handle_rep_channel(self, timeout=0.1):
""" Method to capture raw_input
"""
self.msg_rep = self.km.rep_channel.get_msg(timeout=timeout)
if self.msg_header["session"] == self.msg_rep["parent_header"]["session"] :
raw_data = raw_input(self.msg_rep["content"]["prompt"])
self.km.rep_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!")
kgroup.add_argument('--xreq', type=int, metavar='PORT', default=0,
help='set the XREQ channel port [default random]')
kgroup.add_argument('--sub', type=int, metavar='PORT', default=0,
help='set the SUB channel port [default random]')
kgroup.add_argument('--rep', type=int, metavar='PORT', default=0,
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.
kernel_manager = KernelManager(xreq_address=(args.ip, args.xreq),
sub_address=(args.ip, args.sub),
rep_address=(args.ip, args.rep),
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)
kwargs = dict(ip=args.ip)
if args.pure:
kwargs['ipython']=False
else:
kwargs['colors']=colors
if args.pylab:
kwargs['pylab']=args.pylab
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()