Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(482)

Side by Side Diff: ports/ipython_extension/simple_shell_main.py

Issue 165473002: Adds an IPython kernel running in NaCl, and a wrapper as a Chrome extension. Base URL: https://naclports.googlecode.com/svn/trunk/src
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 """A simple shell that uses the IPython messaging system."""
Sam Clegg 2014/02/18 23:39:31 Copyright
2
3 import json
4 import logging
5 import sys
6
7 import IPython
8 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
9 from IPython.utils.traitlets import Type, Dict, Instance
10 from IPython.core.displayhook import DisplayHook
11 from IPython.utils.jsonutil import json_clean, encode_images
12 from IPython.core.displaypub import DisplayPublisher
13 from IPython.config.configurable import Configurable
14
15 # module defined in shell.cc for communicating via pepper API
16 import ppmessage
17
18 def sendMessage(socket_name, msg_type, parent_header=None, content=None):
19 if parent_header is None:
20 parent_header = {}
21 if content is None:
22 content = {}
23 msg = {
24 'header': {'msg_type': msg_type},
25 'parent_header': parent_header,
26 'content': content
27 }
28 ppmessage._PostJSONMessage(socket_name, json.dumps(msg))
29
30 class MsgOutStream(object):
31 """Class to overrides stderr and stdout."""
32
33 def __init__(self, stream_name):
34 self._stream_name = stream_name
35 self._parent_header = {}
36
37 def SetParentHeader(self, parent_header):
38 self._parent_header = parent_header
39
40 def close(self):
41 pass
42
43 def flush(self):
44 pass
45
46 def write(self, string):
47 sendMessage('iopub', 'stream', parent_header=self._parent_header,
48 content={'name': self._stream_name, 'data': string})
49
50 def writelines(self, sequence):
51 for string in sequence:
52 self.write(string)
53
54 # override sys.stdout and sys.stderr to broadcast on iopub
55 stdout_stream = MsgOutStream('stdout')
56 stderr_stream = MsgOutStream('stderr')
57 sys_stdout = sys.stdout
58 sys_stderr = sys.stderr
59 sys.stdout = stdout_stream
60 sys.stderr = stderr_stream
61
62
63
64 class PepperShellDisplayHook(DisplayHook):
65 parent_header = Dict({})
66
67 def set_parent_header(self, parent_header):
68 """Set the parent for outbound messages."""
69 self.parent_header = parent_header
70
71 def start_displayhook(self):
72 self.content = {}
73
74 def write_output_prompt(self):
75 self.content['execution_count'] = self.prompt_count
76
77 def write_format_data(self, format_dict, md_dict=None):
78 self.content['data'] = encode_images(format_dict)
79 self.content['metadata'] = md_dict
80
81 def finish_displayhook(self):
82 sys.stdout.flush()
83 sys.stderr.flush()
84 sendMessage('iopub', 'pyout', parent_header=self.parent_header,
85 content=self.content)
86 self.content = None
87
88
89 class PepperDisplayPublisher(DisplayPublisher):
90 parent_header = Dict({})
91
92 def set_parent_header(self, parent_header):
93 self.parent_header = parent_header
94
95 def _flush_streams(self):
96 """flush IO Streams prior to display"""
97 sys.stdout.flush()
98 sys.stderr.flush()
99
100 def publish(self, source, data, metadata=None):
101 self._flush_streams()
102 if metadata is None:
103 metadata = {}
104 self._validate_data(source, data, metadata)
105 content = {}
106 content['source'] = source
107 content['data'] = encode_images(data)
108 content['metadata'] = metadata
109 sendMessage('iopub', 'display_data', content=json_clean(content),
110 parent_header=self.parent_header)
111
112 def clear_output(self, stdout=True, stderr=True, other=True):
113 content = dict(stdout=stdout, stderr=stderr, other=other)
114
115 if stdout:
116 sys.stdout.write('\r')
117 if stderr:
118 sys.stderr.write('\r')
119
120 self._flush_streams()
121 sendMessage('iopub', 'clear_output', content=content,
122 parent_header=self.parent_header)
123
124
125 class PepperInteractiveShell(InteractiveShell):
126 """A subclass of InteractiveShell for the Pepper Messagin API."""
127 displayhook_class = Type(PepperShellDisplayHook)
128 display_pub_class = Type(PepperDisplayPublisher)
129 @staticmethod
130 def enable_gui(gui):
131 pass
132
133
134 InteractiveShellABC.register(PepperInteractiveShell)
135
136 class PepperKernel(Configurable):
137 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
138 shell_class = Type(PepperInteractiveShell)
139
140 def __init__(self):
141 self.shell = self.shell_class.instance(parent=self)
142 self.shell.run_cell("""
143 import os
144 matplotlib_config_dir = '/mplconfigdir'
145 os.environ['XDG_CONFIG_HOME'] = matplotlib_config_dir
146 os.environ['TMP'] = ''
147 import matplotlib
148 import matplotlib.cbook
149 """)
150
151 execution_count = 1
152
153 shell = PepperKernel().shell
154
155 while 1:
156 sendMessage('iopub', 'status', content={'execution_state': 'idle'})
157 msg = json.loads(ppmessage._AcquireJSONMessageWait())
158 sendMessage('iopub', 'status', content={'execution_state': 'busy'})
159
160 if not 'header' in msg:
161 continue
162 request_header = msg['header']
163 if not 'msg_type' in request_header:
164 continue
165 msg_type = request_header['msg_type']
166 if msg_type == 'execute_request':
167 try:
168 content = msg[u'content']
169 code = content[u'code']
170 silent = content[u'silent']
171 store_history = content.get(u'store_history', not silent)
172 except:
173 self.log.error("Got bad msg: ")
174 self.log.error("%s", msg)
175 continue
176
177 # Let output streams know which message the output is for
178 stdout_stream.SetParentHeader(request_header)
179 stderr_stream.SetParentHeader(request_header)
180 shell.displayhook.set_parent_header(request_header)
181 shell.display_pub.set_parent_header(request_header)
182
183 status = 'ok'
184 content = {}
185 try:
186 shell.run_cell(msg['content']['code'],
187 store_history=store_history,
188 silent=silent)
189 except Exception, ex:
190 status = 'error'
191 logging.exception('Exception occured while running cell')
192
193 content = {'status': status,
194 'execution_count': execution_count}
195
196 if status == 'ok':
197 content['payload'] = []
198 content['user_variables'] = {}
199 content['user_expressions'] = {}
200 elif status == 'error':
201 content['ename'] = type(ex).__name__
202 content['evalue'] = str(ex)
203 content['traceback'] = []
204
205 execution_count += 1
206 if status == 'error':
207 sendMessage('iopub', 'pyerr', parent_header=request_header,
208 content={
209 'execution_count': execution_count,
210 'ename': type(ex).__name__,
211 'evalue': str(ex),
212 'traceback': []
213 }
214 )
215 sendMessage('shell', 'execute_reply', parent_header=request_header,
216 content=content)
217 elif msg_type == 'complete_request':
218 c = msg['content']
219 try:
220 cpos = int(c['cursor_pos'])
221 except:
222 cpos = len(c['text'])
223 if cpos == 0:
224 cpos = len(c['line'])
225 txt, matches = shell.complete(c['text'], c['line'], cpos)
226 sendMessage('shell', 'complete_reply',
227 parent_header = request_header,
228 content = {
229 'matches': matches,
230 'matched_text': txt,
231 'status': 'ok'
232 })
233 elif msg_type == 'restart':
234 # break out of this loop, ending this program.
235 # The main event loop in shell.cc will then
236 # run this program again.
237 break
238 elif msg_type == 'kill':
239 # Raise an exception so that the function
240 # running this script will return -1, resulting
241 # in no restart of this script.
242 raise RuntimeError
OLDNEW
« ports/ipython_extension/python.cc ('K') | « ports/ipython_extension/python.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698