##// END OF EJS Templates
Replace tabs with spaces
Thomas Kluyver -
Show More
@@ -1,52 +1,52 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 import readline
2 import readline
3 import time
3 import time
4 import sys
4 import sys
5 stdout = sys.stdout
5 stdout = sys.stdout
6 class ClientCompleter2p(object):
6 class ClientCompleter2p(object):
7 """Client-side completion machinery.
7 """Client-side completion machinery.
8
8
9 How it works: self.complete will be called multiple times, with
9 How it works: self.complete will be called multiple times, with
10 state=0,1,2,... When state=0 it should compute ALL the completion matches,
10 state=0,1,2,... When state=0 it should compute ALL the completion matches,
11 and then return them for each value of state."""
11 and then return them for each value of state."""
12
12
13 def __init__(self,client, km):
13 def __init__(self,client, km):
14 self.km = km
14 self.km = km
15 self.matches = []
15 self.matches = []
16 self.client = client
16 self.client = client
17
17
18 def complete_request(self,text):
18 def complete_request(self,text):
19 line = readline.get_line_buffer()
19 line = readline.get_line_buffer()
20 #msg_id = self.km.xreq_channel.complete(text=text,line=line)#this method is not working, the code not continue
20 #msg_id = self.km.xreq_channel.complete(text=text,line=line)#this method is not working, the code not continue
21 msg = self.km.session.send(self.km.xreq_channel.socket,
21 msg = self.km.session.send(self.km.xreq_channel.socket,
22 'complete_request',
22 'complete_request',
23 dict(text=text, line=line))
23 dict(text=text, line=line))
24 # send completion request to kernel
24 # send completion request to kernel
25 # Give the kernel up to 0.5s to respond
25 # Give the kernel up to 0.5s to respond
26 msg_matches = None
26 msg_matches = None
27 for i in range(5):
27 for i in range(5):
28 if self.km.xreq_channel.was_called():
28 if self.km.xreq_channel.was_called():
29 msg_xreq = self.km.xreq_channel.get_msg()
29 msg_xreq = self.km.xreq_channel.get_msg()
30 if msg["header"]['session'] == msg_xreq["parent_header"]['session'] :
30 if msg["header"]['session'] == msg_xreq["parent_header"]['session'] :
31 if msg_xreq["content"]["status"] == 'ok' :
31 if msg_xreq["content"]["status"] == 'ok' :
32 if msg_xreq["msg_type"] == "complete_reply" :
32 if msg_xreq["msg_type"] == "complete_reply" :
33 msg_matches = msg_xreq["content"]["matches"]
33 msg_matches = msg_xreq["content"]["matches"]
34 #break
34 #break
35 time.sleep(0.1)
35 time.sleep(0.1)
36 return msg_matches
36 return msg_matches
37
37
38 def complete(self, text, state):
38 def complete(self, text, state):
39 if state == 0 :
39 if state == 0 :
40 self.matches = self.complete_request(text)
40 self.matches = self.complete_request(text)
41
41
42 if self.matches is None:
42 if self.matches is None:
43 self.matches = []
43 self.matches = []
44 print('WARNING: Kernel timeout on tab completion.')
44 print('WARNING: Kernel timeout on tab completion.')
45 #print self.matches
45 #print self.matches
46 try:
46 try:
47 return self.matches[state]
47 return self.matches[state]
48 except IndexError:
48 except IndexError:
49 return None
49 return None
50
50
51
51
52
52
@@ -1,283 +1,282 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Frontend of ipython working with python-zmq
2 """Frontend of ipython working with python-zmq
3
3
4 Ipython's frontend, is a ipython interface that send request to kernel and proccess the kernel's outputs.
4 Ipython's frontend, is a ipython interface that send request to kernel and proccess the kernel's outputs.
5
5
6 For more details, see the ipython-zmq design
6 For more details, see the ipython-zmq design
7 """
7 """
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2010 The IPython Development Team
9 # Copyright (C) 2010 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 import __builtin__
19 import __builtin__
20 from contextlib import nested
20 from contextlib import nested
21 import time
21 import time
22 import sys
22 import sys
23 import os
23 import os
24 import signal
24 import signal
25 import uuid
25 import uuid
26 import cPickle as pickle
26 import cPickle as pickle
27 import code
27 import code
28 import zmq
28 import zmq
29 import readline
29 import readline
30 import rlcompleter
30 import rlcompleter
31 import time
31 import time
32
32
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34 # Imports from ipython
34 # Imports from ipython
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36 from IPython.external.argparse import ArgumentParser
36 from IPython.external.argparse import ArgumentParser
37 from IPython.utils.traitlets import (
37 from IPython.utils.traitlets import (
38 Int, Str, CBool, CaselessStrEnum, Enum, List, Unicode
38 Int, Str, CBool, CaselessStrEnum, Enum, List, Unicode
39 )
39 )
40 from IPython.core.interactiveshell import get_default_colors
40 from IPython.core.interactiveshell import get_default_colors
41 from IPython.core.excolors import exception_colors
41 from IPython.core.excolors import exception_colors
42 from IPython.utils import PyColorize
42 from IPython.utils import PyColorize
43 from IPython.core.inputsplitter import InputSplitter
43 from IPython.core.inputsplitter import InputSplitter
44 from IPython.frontend.terminal.kernelmanager import KernelManager2p as KernelManager
44 from IPython.frontend.terminal.kernelmanager import KernelManager2p as KernelManager
45 from IPython.zmq.session import Session
45 from IPython.zmq.session import Session
46 from IPython.frontend.terminal.completer import ClientCompleter2p
46 from IPython.frontend.terminal.completer import ClientCompleter2p
47
47
48 #-----------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
49 # Network Constants
49 # Network Constants
50 #-----------------------------------------------------------------------------
50 #-----------------------------------------------------------------------------
51
51
52 from IPython.utils.localinterfaces import LOCALHOST, LOCAL_IPS
52 from IPython.utils.localinterfaces import LOCALHOST, LOCAL_IPS
53 class Frontend(object):
53 class Frontend(object):
54 """ this class is a simple frontend to ipython-zmq
54 """ this class is a simple frontend to ipython-zmq
55
55
56 NOTE: this class use kernelmanager to manipulate sockets
56 NOTE: this class use kernelmanager to manipulate sockets
57
57
58 Parameters:
58 Parameters:
59 -----------
59 -----------
60 kernelmanager : object
60 kernelmanager : object
61 instantiated object from class KernelManager in module kernelmanager
61 instantiated object from class KernelManager in module kernelmanager
62
62
63 """
63 """
64
64
65 def __init__(self,kernelmanager):
65 def __init__(self,kernelmanager):
66 self.km = kernelmanager
66 self.km = kernelmanager
67 self.session = kernelmanager.session
67 self.session = kernelmanager.session
68 self.request_socket = self.km.xreq_channel.socket
68 self.request_socket = self.km.xreq_channel.socket
69 self.sub_socket = self.km.sub_channel.socket
69 self.sub_socket = self.km.sub_channel.socket
70 self.reply_socket = self.km.rep_channel.socket
70 self.reply_socket = self.km.rep_channel.socket
71 self.msg_header = self.km.session.msg_header()
71 self.msg_header = self.km.session.msg_header()
72 self.completer = ClientCompleter2p(self,self.km)
72 self.completer = ClientCompleter2p(self,self.km)
73 readline.parse_and_bind("tab: complete")
73 readline.parse_and_bind("tab: complete")
74 readline.parse_and_bind('set show-all-if-ambiguous on')
74 readline.parse_and_bind('set show-all-if-ambiguous on')
75 readline.set_completer(self.completer.complete)
75 readline.set_completer(self.completer.complete)
76
76
77 history_path = os.path.expanduser('~/.ipython/history')
77 history_path = os.path.expanduser('~/.ipython/history')
78 if os.path.isfile(history_path):
78 if os.path.isfile(history_path):
79 rlcompleter.readline.read_history_file(history_path)
79 rlcompleter.readline.read_history_file(history_path)
80 else:
80 else:
81 print("history file can not be readed.")
81 print("history file can not be readed.")
82
82
83 self.messages = {}
83 self.messages = {}
84
84
85 self._splitter = InputSplitter()
85 self._splitter = InputSplitter()
86 self.code = ""
86 self.code = ""
87
87
88 self.prompt_count = 0
88 self.prompt_count = 0
89 self._get_initail_promt()
89 self._get_initail_promt()
90
90
91 def _get_initail_promt(self):
91 def _get_initail_promt(self):
92 self._execute('', hidden=True)
92 self._execute('', hidden=True)
93
93
94 def interact(self):
94 def interact(self):
95 """ let you get input from console using inputsplitter, then
95 """ let you get input from console using inputsplitter, then
96 while you enter code it can indent and set index id to any input
96 while you enter code it can indent and set index id to any input
97
97
98 """
98 """
99
99
100 try:
100 try:
101 self._splitter.push(raw_input('In[%i]:'%self.prompt_count+self.code))
101 self._splitter.push(raw_input('In[%i]:'%self.prompt_count+self.code))
102 while self._splitter.push_accepts_more():
102 while self._splitter.push_accepts_more():
103 self.code = raw_input('.....:'+' '*self._splitter.indent_spaces)
103 self.code = raw_input('.....:'+' '*self._splitter.indent_spaces)
104 self._splitter.push(' '*self._splitter.indent_spaces+self.code)
104 self._splitter.push(' '*self._splitter.indent_spaces+self.code)
105 self._execute(self._splitter.source,False)
105 self._execute(self._splitter.source,False)
106 self._splitter.reset()
106 self._splitter.reset()
107 except KeyboardInterrupt:
107 except KeyboardInterrupt:
108 print('\nKeyboardInterrupt\n')
108 print('\nKeyboardInterrupt\n')
109 pass
109 pass
110
110
111
111
112 def start(self):
112 def start(self):
113 """ init a bucle that call interact method to get code.
113 """ init a bucle that call interact method to get code.
114
114
115 """
115 """
116 while True:
116 while True:
117 try:
117 try:
118 self.interact()
118 self.interact()
119 except KeyboardInterrupt:
119 except KeyboardInterrupt:
120 print('\nKeyboardInterrupt\n')
120 print('\nKeyboardInterrupt\n')
121 pass
121 pass
122 except EOFError:
122 except EOFError:
123 answer = ''
123 answer = ''
124 while True:
124 while True:
125 answer = raw_input('\nDo you really want to exit ([y]/n)?')
125 answer = raw_input('\nDo you really want to exit ([y]/n)?')
126 if answer == 'y' or answer == '' :
126 if answer == 'y' or answer == '' :
127 self.km.shutdown_kernel()
127 self.km.shutdown_kernel()
128 sys.exit()
128 sys.exit()
129 elif answer == 'n':
129 elif answer == 'n':
130 break
130 break
131
131
132 def _execute(self, source, hidden = True):
132 def _execute(self, source, hidden = True):
133 """ Execute 'source'. If 'hidden', do not show any output.
133 """ Execute 'source'. If 'hidden', do not show any output.
134
134
135 See parent class :meth:`execute` docstring for full details.
135 See parent class :meth:`execute` docstring for full details.
136 """
136 """
137 self.km.xreq_channel.execute(source, hidden)
137 self.km.xreq_channel.execute(source, hidden)
138 self.handle_xreq_channel()
138 self.handle_xreq_channel()
139 self.handle_rep_channel()
139 self.handle_rep_channel()
140
140
141 def handle_xreq_channel(self):
141 def handle_xreq_channel(self):
142 # Give the kernel up to 0.5s to respond
142 # Give the kernel up to 0.5s to respond
143 for i in range(5):
143 for i in range(5):
144 if self.km.xreq_channel.was_called():
144 if self.km.xreq_channel.was_called():
145 self.msg_xreq = self.km.xreq_channel.get_msg()
145 self.msg_xreq = self.km.xreq_channel.get_msg()
146 if self.msg_header["session"] == self.msg_xreq["parent_header"]["session"] :
146 if self.msg_header["session"] == self.msg_xreq["parent_header"]["session"] :
147 if self.msg_xreq["content"]["status"] == 'ok' :
147 if self.msg_xreq["content"]["status"] == 'ok' :
148 if self.msg_xreq["msg_type"] == "execute_reply" :
148 if self.msg_xreq["msg_type"] == "execute_reply" :
149 self.handle_sub_channel()
149 self.handle_sub_channel()
150 self.prompt_count = self.msg_xreq["content"]["execution_count"]+1
150 self.prompt_count = self.msg_xreq["content"]["execution_count"]+1
151
151
152 else:
152 else:
153 etb = self.msg_xreq["content"]["traceback"]
153 etb = self.msg_xreq["content"]["traceback"]
154 print >> sys.stderr, etb[0]
154 print >> sys.stderr, etb[0]
155 print >> sys.stderr, etb[1]
155 print >> sys.stderr, etb[1]
156 print >> sys.stderr, etb[2]
156 print >> sys.stderr, etb[2]
157 self.prompt_count = self.msg_xreq["content"]["execution_count"]+1
157 self.prompt_count = self.msg_xreq["content"]["execution_count"]+1
158 break
158 break
159 time.sleep(0.1)
159 time.sleep(0.1)
160
161
160
162
161
163 def handle_sub_channel(self):
162 def handle_sub_channel(self):
164 """ Method to procces subscribe channel's messages
163 """ Method to procces subscribe channel's messages
165
164
166 this method read a message and procces the content
165 this method read a message and procces the content
167 in differents outputs like stdout, stderr, pyout
166 in differents outputs like stdout, stderr, pyout
168 and status
167 and status
169
168
170 Arguments:
169 Arguments:
171 sub_msg: message receive from kernel in the sub socket channel
170 sub_msg: message receive from kernel in the sub socket channel
172 capture by kernel manager.
171 capture by kernel manager.
173
172
174 """
173 """
175 while self.km.sub_channel.was_called():
174 while self.km.sub_channel.was_called():
176 sub_msg = self.km.sub_channel.get_msg()
175 sub_msg = self.km.sub_channel.get_msg()
177 if self.msg_header["username"] == sub_msg['parent_header']['username'] and self.km.session.session == sub_msg['parent_header']['session']:
176 if self.msg_header["username"] == sub_msg['parent_header']['username'] and self.km.session.session == sub_msg['parent_header']['session']:
178 if sub_msg['msg_type'] == 'status' :
177 if sub_msg['msg_type'] == 'status' :
179 if sub_msg["content"]["execution_state"] == "busy" :
178 if sub_msg["content"]["execution_state"] == "busy" :
180 pass
179 pass
181
180
182 if sub_msg['msg_type'] == 'stream' :
181 if sub_msg['msg_type'] == 'stream' :
183 if sub_msg["content"]["name"] == "stdout":
182 if sub_msg["content"]["name"] == "stdout":
184 print >> sys.stdout,sub_msg["content"]["data"]
183 print >> sys.stdout,sub_msg["content"]["data"]
185 sys.stdout.flush()
184 sys.stdout.flush()
186 if sub_msg["content"]["name"] == "stderr" :
185 if sub_msg["content"]["name"] == "stderr" :
187 print >> sys.stderr,sub_msg["content"]["data"]
186 print >> sys.stderr,sub_msg["content"]["data"]
188 sys.stderr.flush()
187 sys.stderr.flush()
189
188
190 if sub_msg['msg_type'] == 'pyout' :
189 if sub_msg['msg_type'] == 'pyout' :
191 print >> sys.stdout,"Out[%i]:"%sub_msg["content"]["execution_count"], sub_msg["content"]["data"]["text/plain"]
190 print >> sys.stdout,"Out[%i]:"%sub_msg["content"]["execution_count"], sub_msg["content"]["data"]["text/plain"]
192 sys.stdout.flush()
191 sys.stdout.flush()
193
192
194 def handle_rep_channel(self):
193 def handle_rep_channel(self):
195 """ Method to capture raw_input
194 """ Method to capture raw_input
196 """
195 """
197 if self.km.rep_channel.was_called() :
196 if self.km.rep_channel.was_called() :
198 self.msg_rep = self.km.rep_channel.get_msg()
197 self.msg_rep = self.km.rep_channel.get_msg()
199 if self.msg_header["session"] == self.msg_rep["parent_header"]["session"] :
198 if self.msg_header["session"] == self.msg_rep["parent_header"]["session"] :
200 raw_data = raw_input(self.msg_rep["content"]["prompt"])
199 raw_data = raw_input(self.msg_rep["content"]["prompt"])
201 self.km.rep_channel.input(raw_data)
200 self.km.rep_channel.input(raw_data)
202
201
203
202
204
203
205
204
206 def start_frontend():
205 def start_frontend():
207 """ Entry point for application.
206 """ Entry point for application.
208
207
209 """
208 """
210 # Parse command line arguments.
209 # Parse command line arguments.
211 parser = ArgumentParser()
210 parser = ArgumentParser()
212 kgroup = parser.add_argument_group('kernel options')
211 kgroup = parser.add_argument_group('kernel options')
213 kgroup.add_argument('-e', '--existing', action='store_true',
212 kgroup.add_argument('-e', '--existing', action='store_true',
214 help='connect to an existing kernel')
213 help='connect to an existing kernel')
215 kgroup.add_argument('--ip', type=str, default=LOCALHOST,
214 kgroup.add_argument('--ip', type=str, default=LOCALHOST,
216 help=\
215 help=\
217 "set the kernel\'s IP address [default localhost].\
216 "set the kernel\'s IP address [default localhost].\
218 If the IP address is something other than localhost, then \
217 If the IP address is something other than localhost, then \
219 Consoles on other machines will be able to connect\
218 Consoles on other machines will be able to connect\
220 to the Kernel, so be careful!")
219 to the Kernel, so be careful!")
221 kgroup.add_argument('--xreq', type=int, metavar='PORT', default=0,
220 kgroup.add_argument('--xreq', type=int, metavar='PORT', default=0,
222 help='set the XREQ channel port [default random]')
221 help='set the XREQ channel port [default random]')
223 kgroup.add_argument('--sub', type=int, metavar='PORT', default=0,
222 kgroup.add_argument('--sub', type=int, metavar='PORT', default=0,
224 help='set the SUB channel port [default random]')
223 help='set the SUB channel port [default random]')
225 kgroup.add_argument('--rep', type=int, metavar='PORT', default=0,
224 kgroup.add_argument('--rep', type=int, metavar='PORT', default=0,
226 help='set the REP channel port [default random]')
225 help='set the REP channel port [default random]')
227 kgroup.add_argument('--hb', type=int, metavar='PORT', default=0,
226 kgroup.add_argument('--hb', type=int, metavar='PORT', default=0,
228 help='set the heartbeat port [default random]')
227 help='set the heartbeat port [default random]')
229
228
230 egroup = kgroup.add_mutually_exclusive_group()
229 egroup = kgroup.add_mutually_exclusive_group()
231 egroup.add_argument('--pure', action='store_true', help = \
230 egroup.add_argument('--pure', action='store_true', help = \
232 'use a pure Python kernel instead of an IPython kernel')
231 'use a pure Python kernel instead of an IPython kernel')
233 egroup.add_argument('--pylab', type=str, metavar='GUI', nargs='?',
232 egroup.add_argument('--pylab', type=str, metavar='GUI', nargs='?',
234 const='auto', help = \
233 const='auto', help = \
235 "Pre-load matplotlib and numpy for interactive use. If GUI is not \
234 "Pre-load matplotlib and numpy for interactive use. If GUI is not \
236 given, the GUI backend is matplotlib's, otherwise use one of: \
235 given, the GUI backend is matplotlib's, otherwise use one of: \
237 ['tk', 'gtk', 'qt', 'wx', 'inline'].")
236 ['tk', 'gtk', 'qt', 'wx', 'inline'].")
238 egroup.add_argument('--colors', type=str,
237 egroup.add_argument('--colors', type=str,
239 help="Set the color scheme (LightBG,Linux,NoColor). This is guessed\
238 help="Set the color scheme (LightBG,Linux,NoColor). This is guessed\
240 based on the pygments style if not set.")
239 based on the pygments style if not set.")
241
240
242 args = parser.parse_args()
241 args = parser.parse_args()
243
242
244 # parse the colors arg down to current known labels
243 # parse the colors arg down to current known labels
245 if args.colors:
244 if args.colors:
246 colors=args.colors.lower()
245 colors=args.colors.lower()
247 if colors in ('lightbg', 'light'):
246 if colors in ('lightbg', 'light'):
248 colors='lightbg'
247 colors='lightbg'
249 elif colors in ('dark', 'linux'):
248 elif colors in ('dark', 'linux'):
250 colors='linux'
249 colors='linux'
251 else:
250 else:
252 colors='nocolor'
251 colors='nocolor'
253 else:
252 else:
254 colors=None
253 colors=None
255
254
256 # Create a KernelManager and start a kernel.
255 # Create a KernelManager and start a kernel.
257 kernel_manager = KernelManager(xreq_address=(args.ip, args.xreq),
256 kernel_manager = KernelManager(xreq_address=(args.ip, args.xreq),
258 sub_address=(args.ip, args.sub),
257 sub_address=(args.ip, args.sub),
259 rep_address=(args.ip, args.rep),
258 rep_address=(args.ip, args.rep),
260 hb_address=(args.ip, args.hb))
259 hb_address=(args.ip, args.hb))
261 if not args.existing:
260 if not args.existing:
262 # if not args.ip in LOCAL_IPS+ALL_ALIAS:
261 # if not args.ip in LOCAL_IPS+ALL_ALIAS:
263 # raise ValueError("Must bind a local ip, such as: %s"%LOCAL_IPS)
262 # raise ValueError("Must bind a local ip, such as: %s"%LOCAL_IPS)
264
263
265 kwargs = dict(ip=args.ip)
264 kwargs = dict(ip=args.ip)
266 if args.pure:
265 if args.pure:
267 kwargs['ipython']=False
266 kwargs['ipython']=False
268 else:
267 else:
269 kwargs['colors']=colors
268 kwargs['colors']=colors
270 if args.pylab:
269 if args.pylab:
271 kwargs['pylab']=args.pylab
270 kwargs['pylab']=args.pylab
272 kernel_manager.start_kernel(**kwargs)
271 kernel_manager.start_kernel(**kwargs)
273
272
274
273
275 kernel_manager.start_channels()
274 kernel_manager.start_channels()
276 time.sleep(4)
275 time.sleep(4)
277
276
278 frontend=Frontend(kernel_manager)
277 frontend=Frontend(kernel_manager)
279 return frontend
278 return frontend
280
279
281 if __name__ == "__main__" :
280 if __name__ == "__main__" :
282 frontend=start_frontend()
281 frontend=start_frontend()
283 frontend.start() No newline at end of file
282 frontend.start()
General Comments 0
You need to be logged in to leave comments. Login now