|
@@
-17,32
+17,18
b' For more details, see the ipython-zmq design'
|
|
17
|
#-----------------------------------------------------------------------------
|
|
17
|
#-----------------------------------------------------------------------------
|
|
18
|
|
|
18
|
|
|
19
|
import __builtin__
|
|
19
|
import __builtin__
|
|
20
|
from contextlib import nested
|
|
|
|
|
21
|
import time
|
|
|
|
|
22
|
import sys
|
|
20
|
import sys
|
|
23
|
import os
|
|
21
|
import os
|
|
24
|
import signal
|
|
22
|
from Queue import Empty
|
|
25
|
import uuid
|
|
|
|
|
26
|
import cPickle as pickle
|
|
|
|
|
27
|
import code
|
|
|
|
|
28
|
import zmq
|
|
|
|
|
29
|
import readline
|
|
23
|
import readline
|
|
30
|
import rlcompleter
|
|
24
|
import rlcompleter
|
|
31
|
import time
|
|
|
|
|
32
|
|
|
25
|
|
|
33
|
#-----------------------------------------------------------------------------
|
|
26
|
#-----------------------------------------------------------------------------
|
|
34
|
# Imports from ipython
|
|
27
|
# Imports from ipython
|
|
35
|
#-----------------------------------------------------------------------------
|
|
28
|
#-----------------------------------------------------------------------------
|
|
36
|
from IPython.external.argparse import ArgumentParser
|
|
29
|
from IPython.external.argparse import ArgumentParser
|
|
37
|
from IPython.utils.traitlets import (
|
|
|
|
|
38
|
Int, Str, CBool, CaselessStrEnum, Enum, List, Unicode
|
|
|
|
|
39
|
)
|
|
|
|
|
40
|
from IPython.core.interactiveshell import get_default_colors
|
|
|
|
|
41
|
from IPython.core.excolors import exception_colors
|
|
|
|
|
42
|
from IPython.utils import PyColorize
|
|
|
|
|
43
|
from IPython.core.inputsplitter import IPythonInputSplitter
|
|
30
|
from IPython.core.inputsplitter import IPythonInputSplitter
|
|
44
|
from IPython.frontend.zmqterminal.kernelmanager import KernelManager2p as KernelManager
|
|
31
|
from IPython.zmq.blockingkernelmanager import BlockingKernelManager as KernelManager
|
|
45
|
from IPython.zmq.session import Session
|
|
|
|
|
46
|
from IPython.frontend.zmqterminal.completer import ClientCompleter2p
|
|
32
|
from IPython.frontend.zmqterminal.completer import ClientCompleter2p
|
|
47
|
|
|
33
|
|
|
48
|
#-----------------------------------------------------------------------------
|
|
34
|
#-----------------------------------------------------------------------------
|
|
@@
-51,7
+37,7
b' from IPython.frontend.zmqterminal.completer import ClientCompleter2p'
|
|
51
|
|
|
37
|
|
|
52
|
from IPython.utils.localinterfaces import LOCALHOST, LOCAL_IPS
|
|
38
|
from IPython.utils.localinterfaces import LOCALHOST, LOCAL_IPS
|
|
53
|
class Frontend(object):
|
|
39
|
class Frontend(object):
|
|
54
|
"""This class is a simple frontend to ipython-zmq
|
|
40
|
"""This class is a simple frontend to ipython-zmq
|
|
55
|
|
|
41
|
|
|
56
|
NOTE: this class uses kernelmanager to manipulate sockets
|
|
42
|
NOTE: this class uses kernelmanager to manipulate sockets
|
|
57
|
|
|
43
|
|
|
@@
-60,16
+46,16
b' class Frontend(object):'
|
|
60
|
kernelmanager : object
|
|
46
|
kernelmanager : object
|
|
61
|
instantiated object from class KernelManager in module kernelmanager
|
|
47
|
instantiated object from class KernelManager in module kernelmanager
|
|
62
|
|
|
48
|
|
|
63
|
"""
|
|
49
|
"""
|
|
64
|
|
|
50
|
|
|
65
|
def __init__(self, kernelmanager):
|
|
51
|
def __init__(self, kernelmanager):
|
|
66
|
self.km = kernelmanager
|
|
52
|
self.km = kernelmanager
|
|
67
|
self.session = kernelmanager.session
|
|
53
|
self.session = kernelmanager.session
|
|
68
|
self.request_socket = self.km.xreq_channel.socket
|
|
54
|
self.request_socket = self.km.xreq_channel.socket
|
|
69
|
self.sub_socket = self.km.sub_channel.socket
|
|
55
|
self.sub_socket = self.km.sub_channel.socket
|
|
70
|
self.reply_socket = self.km.rep_channel.socket
|
|
56
|
self.reply_socket = self.km.rep_channel.socket
|
|
71
|
self.msg_header = self.km.session.msg_header()
|
|
57
|
self.msg_header = self.km.session.msg_header()
|
|
72
|
self.completer = ClientCompleter2p(self,self.km)
|
|
58
|
self.completer = ClientCompleter2p(self, self.km)
|
|
73
|
readline.parse_and_bind("tab: complete")
|
|
59
|
readline.parse_and_bind("tab: complete")
|
|
74
|
readline.parse_and_bind('set show-all-if-ambiguous on')
|
|
60
|
readline.parse_and_bind('set show-all-if-ambiguous on')
|
|
75
|
readline.set_completer(self.completer.complete)
|
|
61
|
readline.set_completer(self.completer.complete)
|
|
@@
-88,10
+74,10
b' class Frontend(object):'
|
|
88
|
self.prompt_count = 0
|
|
74
|
self.prompt_count = 0
|
|
89
|
self._get_initial_prompt()
|
|
75
|
self._get_initial_prompt()
|
|
90
|
|
|
76
|
|
|
91
|
def _get_initial_prompt(self):
|
|
77
|
def _get_initial_prompt(self):
|
|
92
|
self._execute('', hidden=True)
|
|
78
|
self._execute('', hidden=True)
|
|
93
|
|
|
79
|
|
|
94
|
def interact(self):
|
|
80
|
def interact(self):
|
|
95
|
"""Gets input from console using inputsplitter, then
|
|
81
|
"""Gets input from console using inputsplitter, then
|
|
96
|
while you enter code it can indent and set index id to any input
|
|
82
|
while you enter code it can indent and set index id to any input
|
|
97
|
"""
|
|
83
|
"""
|
|
@@
-108,7
+94,7
b' class Frontend(object):'
|
|
108
|
pass
|
|
94
|
pass
|
|
109
|
|
|
95
|
|
|
110
|
|
|
96
|
|
|
111
|
def start(self):
|
|
97
|
def start(self):
|
|
112
|
"""Start the interaction loop, calling the .interact() method for each
|
|
98
|
"""Start the interaction loop, calling the .interact() method for each
|
|
113
|
input cell.
|
|
99
|
input cell.
|
|
114
|
"""
|
|
100
|
"""
|
|
@@
-128,37
+114,39
b' class Frontend(object):'
|
|
128
|
elif answer == 'n':
|
|
114
|
elif answer == 'n':
|
|
129
|
break
|
|
115
|
break
|
|
130
|
|
|
116
|
|
|
131
|
def _execute(self, source, hidden = True):
|
|
117
|
def _execute(self, source, hidden = True):
|
|
132
|
""" Execute 'source'. If 'hidden', do not show any output.
|
|
118
|
""" Execute 'source'. If 'hidden', do not show any output.
|
|
133
|
|
|
119
|
|
|
134
|
See parent class :meth:`execute` docstring for full details.
|
|
120
|
See parent class :meth:`execute` docstring for full details.
|
|
135
|
"""
|
|
121
|
"""
|
|
136
|
self.km.xreq_channel.execute(source, hidden)
|
|
122
|
self.km.xreq_channel.execute(source, hidden)
|
|
137
|
self.handle_xreq_channel()
|
|
123
|
while not self.km.xreq_channel.msg_ready():
|
|
138
|
self.handle_rep_channel()
|
|
124
|
try:
|
|
|
|
|
125
|
self.handle_rep_channel(timeout=0.1)
|
|
|
|
|
126
|
except Empty:
|
|
|
|
|
127
|
pass
|
|
|
|
|
128
|
self.handle_xreq_channel()
|
|
139
|
|
|
129
|
|
|
140
|
def handle_xreq_channel(self):
|
|
130
|
def handle_xreq_channel(self):
|
|
141
|
# Give the kernel up to 0.5s to respond
|
|
131
|
self.msg_xreq = self.km.xreq_channel.get_msg()
|
|
142
|
for i in range(5):
|
|
132
|
if self.msg_header["session"] == self.msg_xreq["parent_header"]["session"]:
|
|
143
|
if self.km.xreq_channel.was_called():
|
|
133
|
if self.msg_xreq["content"]["status"] == 'ok' :
|
|
144
|
self.msg_xreq = self.km.xreq_channel.get_msg()
|
|
134
|
if self.msg_xreq["msg_type"] == "execute_reply" :
|
|
145
|
if self.msg_header["session"] == self.msg_xreq["parent_header"]["session"] :
|
|
135
|
self.handle_sub_channel()
|
|
146
|
if self.msg_xreq["content"]["status"] == 'ok' :
|
|
136
|
self.prompt_count = self.msg_xreq["content"]["execution_count"]+1
|
|
147
|
if self.msg_xreq["msg_type"] == "execute_reply" :
|
|
137
|
|
|
148
|
self.handle_sub_channel()
|
|
138
|
else:
|
|
149
|
self.prompt_count = self.msg_xreq["content"]["execution_count"]+1
|
|
139
|
etb = self.msg_xreq["content"]["traceback"]
|
|
150
|
|
|
140
|
print >> sys.stderr, etb[0]
|
|
151
|
else:
|
|
141
|
try: # These bits aren't there for a SyntaxError
|
|
152
|
etb = self.msg_xreq["content"]["traceback"]
|
|
142
|
print >> sys.stderr, etb[1]
|
|
153
|
print >> sys.stderr, etb[0]
|
|
143
|
print >> sys.stderr, etb[2]
|
|
154
|
print >> sys.stderr, etb[1]
|
|
144
|
except IndexError:
|
|
155
|
print >> sys.stderr, etb[2]
|
|
145
|
pass
|
|
156
|
self.prompt_count = self.msg_xreq["content"]["execution_count"]+1
|
|
146
|
self.prompt_count = self.msg_xreq["content"]["execution_count"]+1
|
|
157
|
break
|
|
|
|
|
158
|
time.sleep(0.1)
|
|
|
|
|
159
|
|
|
147
|
|
|
160
|
|
|
148
|
|
|
161
|
def handle_sub_channel(self):
|
|
149
|
def handle_sub_channel(self):
|
|
162
|
""" Method to procces subscribe channel's messages
|
|
150
|
""" Method to procces subscribe channel's messages
|
|
163
|
|
|
151
|
|
|
164
|
This method reads a message and processes the content in different
|
|
152
|
This method reads a message and processes the content in different
|
|
@@
-168,7
+156,7
b' class Frontend(object):'
|
|
168
|
sub_msg: message receive from kernel in the sub socket channel
|
|
156
|
sub_msg: message receive from kernel in the sub socket channel
|
|
169
|
capture by kernel manager.
|
|
157
|
capture by kernel manager.
|
|
170
|
"""
|
|
158
|
"""
|
|
171
|
while self.km.sub_channel.was_called():
|
|
159
|
while self.km.sub_channel.msg_ready():
|
|
172
|
sub_msg = self.km.sub_channel.get_msg()
|
|
160
|
sub_msg = self.km.sub_channel.get_msg()
|
|
173
|
if self.msg_header["username"] == sub_msg['parent_header']['username'] and \
|
|
161
|
if self.msg_header["username"] == sub_msg['parent_header']['username'] and \
|
|
174
|
self.km.session.session == sub_msg['parent_header']['session']:
|
|
162
|
self.km.session.session == sub_msg['parent_header']['session']:
|
|
@@
-188,14
+176,13
b' class Frontend(object):'
|
|
188
|
print >> sys.stdout,"Out[%i]:"%sub_msg["content"]["execution_count"], sub_msg["content"]["data"]["text/plain"]
|
|
176
|
print >> sys.stdout,"Out[%i]:"%sub_msg["content"]["execution_count"], sub_msg["content"]["data"]["text/plain"]
|
|
189
|
sys.stdout.flush()
|
|
177
|
sys.stdout.flush()
|
|
190
|
|
|
178
|
|
|
191
|
def handle_rep_channel(self):
|
|
179
|
def handle_rep_channel(self, timeout=0.1):
|
|
192
|
""" Method to capture raw_input
|
|
180
|
""" Method to capture raw_input
|
|
193
|
"""
|
|
181
|
"""
|
|
194
|
if self.km.rep_channel.was_called() :
|
|
182
|
self.msg_rep = self.km.rep_channel.get_msg(timeout=timeout)
|
|
195
|
self.msg_rep = self.km.rep_channel.get_msg()
|
|
183
|
if self.msg_header["session"] == self.msg_rep["parent_header"]["session"] :
|
|
196
|
if self.msg_header["session"] == self.msg_rep["parent_header"]["session"] :
|
|
184
|
raw_data = raw_input(self.msg_rep["content"]["prompt"])
|
|
197
|
raw_data = raw_input(self.msg_rep["content"]["prompt"])
|
|
185
|
self.km.rep_channel.input(raw_data)
|
|
198
|
self.km.rep_channel.input(raw_data)
|
|
|
|
|
199
|
|
|
186
|
|
|
200
|
|
|
187
|
|
|
201
|
|
|
188
|
|
|
@@
-270,7
+257,6
b' def start_frontend():'
|
|
270
|
|
|
257
|
|
|
271
|
|
|
258
|
|
|
272
|
kernel_manager.start_channels()
|
|
259
|
kernel_manager.start_channels()
|
|
273
|
time.sleep(4)
|
|
|
|
|
274
|
|
|
260
|
|
|
275
|
frontend=Frontend(kernel_manager)
|
|
261
|
frontend=Frontend(kernel_manager)
|
|
276
|
return frontend
|
|
262
|
return frontend
|