Show More
@@ -0,0 +1,223 | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | """Frontend of ipython working with python-zmq | |||
|
3 | ||||
|
4 | Ipython's frontend, is a ipython interface that send request to kernel and proccess the kernel's outputs. | |||
|
5 | ||||
|
6 | For more details, see the ipython-zmq design | |||
|
7 | """ | |||
|
8 | #----------------------------------------------------------------------------- | |||
|
9 | # Copyright (C) 2010 The IPython Development Team | |||
|
10 | # | |||
|
11 | # Distributed under the terms of the BSD License. The full license is in | |||
|
12 | # the file COPYING, distributed as part of this software. | |||
|
13 | #----------------------------------------------------------------------------- | |||
|
14 | ||||
|
15 | #----------------------------------------------------------------------------- | |||
|
16 | # Imports | |||
|
17 | #----------------------------------------------------------------------------- | |||
|
18 | ||||
|
19 | import __builtin__ | |||
|
20 | from contextlib import nested | |||
|
21 | import time | |||
|
22 | import sys | |||
|
23 | import os | |||
|
24 | import signal | |||
|
25 | import uuid | |||
|
26 | import cPickle as pickle | |||
|
27 | import code | |||
|
28 | import zmq | |||
|
29 | import rlcompleter | |||
|
30 | import time | |||
|
31 | ||||
|
32 | ||||
|
33 | #----------------------------------------------------------------------------- | |||
|
34 | # Imports from ipython | |||
|
35 | #----------------------------------------------------------------------------- | |||
|
36 | 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 InputSplitter | |||
|
44 | from IPython.frontend.terminal.kernelmanager import KernelManager2p as KernelManager | |||
|
45 | from IPython.zmq.session import Session | |||
|
46 | from IPython.zmq import completer | |||
|
47 | #----------------------------------------------------------------------------- | |||
|
48 | # Network Constants | |||
|
49 | #----------------------------------------------------------------------------- | |||
|
50 | ||||
|
51 | from IPython.utils.localinterfaces import LOCALHOST, LOCAL_IPS | |||
|
52 | class Frontend(object): | |||
|
53 | """ this class is a simple frontend to ipython-zmq | |||
|
54 | ||||
|
55 | NOTE: this class use kernelmanager to manipulate sockets | |||
|
56 | ||||
|
57 | Parameters: | |||
|
58 | ----------- | |||
|
59 | kernelmanager : object | |||
|
60 | instantiated object from class KernelManager in module kernelmanager | |||
|
61 | ||||
|
62 | """ | |||
|
63 | ||||
|
64 | def __init__(self,kernelmanager): | |||
|
65 | self.km = kernelmanager | |||
|
66 | self.session = kernelmanager.session | |||
|
67 | self.request_socket = self.km.xreq_channel.socket | |||
|
68 | self.sub_socket = self.km.sub_channel.socket | |||
|
69 | self.reply_socket = self.km.rep_channel.socket | |||
|
70 | ||||
|
71 | ||||
|
72 | self.completer = completer.ClientCompleter(self,self.session,self.request_socket) | |||
|
73 | rlcompleter.readline.parse_and_bind("tab: complete") | |||
|
74 | rlcompleter.readline.parse_and_bind('set show-all-if-ambiguous on') | |||
|
75 | rlcompleter.Completer = self.completer.complete | |||
|
76 | ||||
|
77 | history_path = os.path.expanduser('~/.ipython/history') | |||
|
78 | if os.path.isfile(history_path): | |||
|
79 | rlcompleter.readline.read_history_file(history_path) | |||
|
80 | else: | |||
|
81 | print("history file can not be readed.") | |||
|
82 | ||||
|
83 | self.messages = {} | |||
|
84 | self.prompt_count = 0 | |||
|
85 | self.backgrounded = 0 | |||
|
86 | self._splitter = InputSplitter() | |||
|
87 | ||||
|
88 | def interact(self): | |||
|
89 | """ let you get input from console using inputsplitter, then | |||
|
90 | while you enter code it can indent and set index id to any input | |||
|
91 | ||||
|
92 | """ | |||
|
93 | try: | |||
|
94 | self._splitter.push(raw_input('In[%i]:'%self.prompt_count)) | |||
|
95 | while self._splitter.push_accepts_more(): | |||
|
96 | code = raw_input('.....:'+' '*self._splitter.indent_spaces) | |||
|
97 | self._splitter.push(' '*self._splitter.indent_spaces+code) | |||
|
98 | self._execute(self._splitter.source,False) | |||
|
99 | self._splitter.reset() | |||
|
100 | except KeyboardInterrupt: | |||
|
101 | print('\nKeyboardInterrupt\n') | |||
|
102 | pass | |||
|
103 | ||||
|
104 | def start(self): | |||
|
105 | """ init a bucle that call interact method to get code. | |||
|
106 | ||||
|
107 | """ | |||
|
108 | while True: | |||
|
109 | try: | |||
|
110 | self.interact() | |||
|
111 | except EOFError: | |||
|
112 | answer = '' | |||
|
113 | while True: | |||
|
114 | answer = raw_input('\nDo you really want to exit ([y]/n)?') | |||
|
115 | if answer == 'y' or answer == '' : | |||
|
116 | self.km.shutdown_kernel() | |||
|
117 | sys.exit() | |||
|
118 | elif answer == 'n': | |||
|
119 | break | |||
|
120 | def _execute(self, source, hidden = True): | |||
|
121 | """ Execute 'source'. If 'hidden', do not show any output. | |||
|
122 | ||||
|
123 | See parent class :meth:`execute` docstring for full details. | |||
|
124 | """ | |||
|
125 | msg_id = self.km.xreq_channel.execute(source, hidden) | |||
|
126 | if self.km.xreq_channel.was_called(): | |||
|
127 | msg_xreq = self.km.xreq_channel.get_msg() | |||
|
128 | print "xreq not implemented yet" | |||
|
129 | ||||
|
130 | if self.km.rep_channel.was_called(): | |||
|
131 | msg_rep = self.km.rep_channel.get_msg() | |||
|
132 | print "rep hadler not implemented yet" | |||
|
133 | ||||
|
134 | while True: | |||
|
135 | if not self.km.sub_channel.was_called(): | |||
|
136 | break | |||
|
137 | print "calles sub0" | |||
|
138 | sub_msg = self.km.sub_channel.get_msg() | |||
|
139 | if self.km.session.username == sub_msg['parent_header']['username'] and self.km.session.session == sub_msg['parent_header']['session']: | |||
|
140 | print "calles sub1" | |||
|
141 | ||||
|
142 | ||||
|
143 | def handle_sub_msg(self,msg): | |||
|
144 | if msg['content'] == '': | |||
|
145 | pass | |||
|
146 | ||||
|
147 | def start_frontend(): | |||
|
148 | """ Entry point for application. | |||
|
149 | """ | |||
|
150 | # Parse command line arguments. | |||
|
151 | parser = ArgumentParser() | |||
|
152 | kgroup = parser.add_argument_group('kernel options') | |||
|
153 | kgroup.add_argument('-e', '--existing', action='store_true', | |||
|
154 | help='connect to an existing kernel') | |||
|
155 | kgroup.add_argument('--ip', type=str, default=LOCALHOST, | |||
|
156 | help=\ | |||
|
157 | "set the kernel\'s IP address [default localhost].\ | |||
|
158 | If the IP address is something other than localhost, then \ | |||
|
159 | Consoles on other machines will be able to connect\ | |||
|
160 | to the Kernel, so be careful!") | |||
|
161 | kgroup.add_argument('--xreq', type=int, metavar='PORT', default=0, | |||
|
162 | help='set the XREQ channel port [default random]') | |||
|
163 | kgroup.add_argument('--sub', type=int, metavar='PORT', default=0, | |||
|
164 | help='set the SUB channel port [default random]') | |||
|
165 | kgroup.add_argument('--rep', type=int, metavar='PORT', default=0, | |||
|
166 | help='set the REP channel port [default random]') | |||
|
167 | kgroup.add_argument('--hb', type=int, metavar='PORT', default=0, | |||
|
168 | help='set the heartbeat port [default random]') | |||
|
169 | ||||
|
170 | egroup = kgroup.add_mutually_exclusive_group() | |||
|
171 | egroup.add_argument('--pure', action='store_true', help = \ | |||
|
172 | 'use a pure Python kernel instead of an IPython kernel') | |||
|
173 | egroup.add_argument('--pylab', type=str, metavar='GUI', nargs='?', | |||
|
174 | const='auto', help = \ | |||
|
175 | "Pre-load matplotlib and numpy for interactive use. If GUI is not \ | |||
|
176 | given, the GUI backend is matplotlib's, otherwise use one of: \ | |||
|
177 | ['tk', 'gtk', 'qt', 'wx', 'inline'].") | |||
|
178 | egroup.add_argument('--colors', type=str, | |||
|
179 | help="Set the color scheme (LightBG,Linux,NoColor). This is guessed\ | |||
|
180 | based on the pygments style if not set.") | |||
|
181 | ||||
|
182 | args = parser.parse_args() | |||
|
183 | ||||
|
184 | # parse the colors arg down to current known labels | |||
|
185 | if args.colors: | |||
|
186 | colors=args.colors.lower() | |||
|
187 | if colors in ('lightbg', 'light'): | |||
|
188 | colors='lightbg' | |||
|
189 | elif colors in ('dark', 'linux'): | |||
|
190 | colors='linux' | |||
|
191 | else: | |||
|
192 | colors='nocolor' | |||
|
193 | else: | |||
|
194 | colors=None | |||
|
195 | ||||
|
196 | # Create a KernelManager and start a kernel. | |||
|
197 | kernel_manager = KernelManager(xreq_address=(args.ip, args.xreq), | |||
|
198 | sub_address=(args.ip, args.sub), | |||
|
199 | rep_address=(args.ip, args.rep), | |||
|
200 | hb_address=(args.ip, args.hb)) | |||
|
201 | if not args.existing: | |||
|
202 | # if not args.ip in LOCAL_IPS+ALL_ALIAS: | |||
|
203 | # raise ValueError("Must bind a local ip, such as: %s"%LOCAL_IPS) | |||
|
204 | ||||
|
205 | kwargs = dict(ip=args.ip) | |||
|
206 | if args.pure: | |||
|
207 | kwargs['ipython']=False | |||
|
208 | else: | |||
|
209 | kwargs['colors']=colors | |||
|
210 | if args.pylab: | |||
|
211 | kwargs['pylab']=args.pylab | |||
|
212 | kernel_manager.start_kernel(**kwargs) | |||
|
213 | ||||
|
214 | ||||
|
215 | kernel_manager.start_channels() | |||
|
216 | time.sleep(4) | |||
|
217 | ||||
|
218 | frontend=Frontend(kernel_manager) | |||
|
219 | return frontend | |||
|
220 | ||||
|
221 | if __name__ == "__main__" : | |||
|
222 | frontend=start_frontend() | |||
|
223 | frontend.start() No newline at end of file |
@@ -0,0 +1,93 | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | ||||
|
3 | from Queue import Queue | |||
|
4 | from IPython.zmq.session import Session, Message, extract_header | |||
|
5 | from IPython.utils.traitlets import Type, HasTraits, TraitType | |||
|
6 | from IPython.zmq.kernelmanager import KernelManager, SubSocketChannel, \ | |||
|
7 | XReqSocketChannel, RepSocketChannel, HBSocketChannel | |||
|
8 | MetaHasTraits = type(HasTraits) | |||
|
9 | ||||
|
10 | ||||
|
11 | class SubSocketChannel2p(SubSocketChannel): | |||
|
12 | #--------------------------------------------------------------------------- | |||
|
13 | # 'SubSocketChannel' interface | |||
|
14 | #--------------------------------------------------------------------------- | |||
|
15 | _msg = None | |||
|
16 | queue = Queue(-1) | |||
|
17 | def call_handlers(self, msg): | |||
|
18 | self.queue.put(Message(msg)) | |||
|
19 | ||||
|
20 | def get_msg(self): | |||
|
21 | return self.queue.get() | |||
|
22 | ||||
|
23 | def was_called(self): | |||
|
24 | return not self.queue.empty() | |||
|
25 | ||||
|
26 | class XReqSocketChannel2p(XReqSocketChannel): | |||
|
27 | #--------------------------------------------------------------------------- | |||
|
28 | # 'XReqSocketChannel' interface | |||
|
29 | #--------------------------------------------------------------------------- | |||
|
30 | _msg = None | |||
|
31 | _called = False | |||
|
32 | def call_handlers(self, msg): | |||
|
33 | self._called = True | |||
|
34 | self._msg = Message(msg) | |||
|
35 | ||||
|
36 | def get_msg(self): | |||
|
37 | self._called = False | |||
|
38 | return self._msg | |||
|
39 | ||||
|
40 | def was_called(self): | |||
|
41 | return self._called | |||
|
42 | ||||
|
43 | class RepSocketChannel2p(RepSocketChannel): | |||
|
44 | #--------------------------------------------------------------------------- | |||
|
45 | # 'XReqSocketChannel' interface | |||
|
46 | #--------------------------------------------------------------------------- | |||
|
47 | _msg = None | |||
|
48 | _called = False | |||
|
49 | def call_handlers(self, msg): | |||
|
50 | self._called = True | |||
|
51 | self._msg = Message(msg) | |||
|
52 | ||||
|
53 | def get_msg(self): | |||
|
54 | self._called = False | |||
|
55 | return self._msg | |||
|
56 | ||||
|
57 | def was_called(self): | |||
|
58 | return self._called | |||
|
59 | ||||
|
60 | class HBSocketChannel2p(HBSocketChannel): | |||
|
61 | #--------------------------------------------------------------------------- | |||
|
62 | # 'XReqSocketChannel' interface | |||
|
63 | #--------------------------------------------------------------------------- | |||
|
64 | _msg = None | |||
|
65 | _called = False | |||
|
66 | def call_handlers(self, msg): | |||
|
67 | self._called = True | |||
|
68 | self._msg = Message(msg) | |||
|
69 | ||||
|
70 | def get_msg(self): | |||
|
71 | self._called = False | |||
|
72 | return self._msg | |||
|
73 | ||||
|
74 | def was_called(self): | |||
|
75 | return self._called | |||
|
76 | ||||
|
77 | class KernelManager2p(KernelManager): | |||
|
78 | sub_channel_class = Type(SubSocketChannel2p) | |||
|
79 | xreq_channel_class = Type(XReqSocketChannel2p) | |||
|
80 | rep_channel_class = Type(RepSocketChannel2p) | |||
|
81 | hb_channel_class = Type(HBSocketChannel2p) | |||
|
82 | ||||
|
83 | def start_kernel(self, *args, **kw): | |||
|
84 | """ Reimplemented for proper heartbeat management. | |||
|
85 | """ | |||
|
86 | if self._xreq_channel is not None: | |||
|
87 | self._xreq_channel.reset_first_reply() | |||
|
88 | super(KernelManager2p, self).start_kernel(*args, **kw) | |||
|
89 | ||||
|
90 | ||||
|
91 | ||||
|
92 | ||||
|
93 | No newline at end of file |
General Comments 0
You need to be logged in to leave comments.
Login now