def _publish_msg(self, msg_type, data=None, metadata=None, **keys): """Helper for sending a comm message on IOPub""" data = {} if data is None else data metadata = {} if metadata is None else metadata content = json_clean(dict(data=data, comm_id=self.comm_id, **keys)) self.session.send(self.iopub_socket, msg_type, content, metadata=json_clean(metadata), parent=self.shell.get_parent(), ident=self.topic, )
def _showtraceback(self, etype, evalue, stb): exc_content = { u'traceback' : stb, u'ename' : unicode(etype.__name__), u'evalue' : unicode(evalue) } dh = self.displayhook # Send exception info over pub socket for other clients than the caller # to pick up topic = None if dh.topic: topic = dh.topic.replace(b'pyout', b'pyerr') exc_msg = dh.session.send(dh.pub_socket, u'pyerr', json_clean(exc_content), dh.parent_header, ident=topic) # FIXME - Hack: store exception info in shell object. Right now, the # caller is reading this info after the fact, we need to fix this logic # to remove this hack. Even uglier, we need to store the error status # here, because in the main loop, the logic that sets it is being # skipped because runlines swallows the exceptions. exc_content[u'status'] = u'error' self._reply_content = exc_content # /FIXME return exc_content
def _publish_msg(self, msg_type, data=None, metadata=None, buffers=None, **keys): """Helper for sending a comm message on IOPub""" if threading.current_thread().name != 'MainThread' and IOLoop.initialized(): # make sure we never send on a zmq socket outside the main IOLoop thread IOLoop.instance().add_callback(lambda : self._publish_msg(msg_type, data, metadata, buffers, **keys)) return data = {} if data is None else data metadata = {} if metadata is None else metadata content = json_clean(dict(data=data, comm_id=self.comm_id, **keys)) self.session.send(self.iopub_socket, msg_type, content, metadata=json_clean(metadata), parent=self.kernel._parent_header, ident=self.topic, buffers=buffers, )
def send_execute_reply(self, stream, ident, parent, md, reply_content): """ Send a reply to execute_request """ # Flush output before sending the reply. self._flush_execute_output() # Cleanup the reply and prepare metadata reply_content = json_clean(reply_content) md = md.copy() md['status'] = reply_content['status'] if reply_content['status'] == 'error' and \ reply_content['ename'] == 'UnmetDependency': md['dependencies_met'] = False # Publish the reply reply_msg = self.session.send(stream, u'execute_reply', reply_content, parent, metadata=md, ident=ident) # Handle the reply message content = parent[u'content'] stop_on_error = content.get('stop_on_error', True) silent = content[u'silent'] self.log.debug("%s", reply_msg) if not silent and reply_msg['content']['status'] == u'error' and stop_on_error: self._abort_queues() self._publish_idle() if hasattr(stream, 'flush'): stream.flush()
def history_request(self, stream, ident, parent): # We need to pull these out, as passing **kwargs doesn't work with # unicode keys before Python 2.6.5. hist_access_type = parent["content"]["hist_access_type"] raw = parent["content"]["raw"] output = parent["content"]["output"] if hist_access_type == "tail": n = parent["content"]["n"] hist = self.shell.history_manager.get_tail(n, raw=raw, output=output, include_latest=True) elif hist_access_type == "range": session = parent["content"]["session"] start = parent["content"]["start"] stop = parent["content"]["stop"] hist = self.shell.history_manager.get_range(session, start, stop, raw=raw, output=output) elif hist_access_type == "search": n = parent["content"].get("n") unique = parent["content"].get("unique", False) pattern = parent["content"]["pattern"] hist = self.shell.history_manager.search(pattern, raw=raw, output=output, n=n, unique=unique) else: hist = [] hist = list(hist) content = {"history": hist} content = json_clean(content) msg = self.session.send(stream, "history_reply", content, parent, ident) self.log.debug("Sending history reply with %i entries", len(hist))
def history_request(self, stream, ident, parent): # We need to pull these out, as passing **kwargs doesn't work with # unicode keys before Python 2.6.5. hist_access_type = parent['content']['hist_access_type'] raw = parent['content']['raw'] output = parent['content']['output'] if hist_access_type == 'tail': n = parent['content']['n'] hist = self.shell.history_manager.get_tail(n, raw=raw, output=output, include_latest=True) elif hist_access_type == 'range': session = parent['content']['session'] start = parent['content']['start'] stop = parent['content']['stop'] hist = self.shell.history_manager.get_range(session, start, stop, raw=raw, output=output) elif hist_access_type == 'search': pattern = parent['content']['pattern'] hist = self.shell.history_manager.search(pattern, raw=raw, output=output) else: hist = [] hist = list(hist) content = {'history' : hist} content = json_clean(content) msg = self.session.send(stream, 'history_reply', content, parent, ident) self.log.debug("Sending history reply with %i entries", len(hist))
def object_info_request(self, stream, ident, parent): content = parent["content"] object_info = self.shell.object_inspect(content["oname"], detail_level=content.get("detail_level", 0)) # Before we send this object over, we scrub it for JSON usage oinfo = json_clean(object_info) msg = self.session.send(stream, "object_info_reply", oinfo, parent, ident) self.log.debug("%s", msg)
def _raw_input(self, prompt, ident, parent): # Flush output before making the request. sys.stderr.flush() sys.stdout.flush() # Send the input request. content = json_clean(dict(prompt=prompt)) self.session.send(self.stdin_socket, u'input_request', content, parent, ident=ident) # Await a response. while True: try: ident, reply = self.session.recv(self.stdin_socket, 0) except Exception: self.log.warn("Invalid Message:", exc_info=True) else: break try: value = reply['content']['value'] except: self.log.error("Got bad raw_input reply: ") self.log.error("%s", parent) value = '' if value == '\x04': # EOF raise EOFError return value
def _showtraceback(self, etype, evalue, stb): # try to preserve ordering of tracebacks and print statements sys.stdout.flush() sys.stderr.flush() exc_content = { u"traceback": stb, u"ename": unicode_type(etype.__name__), u"evalue": py3compat.safe_unicode(evalue), } dh = self.displayhook # Send exception info over pub socket for other clients than the caller # to pick up topic = None if dh.topic: topic = dh.topic.replace(b"execute_result", b"error") exc_msg = dh.session.send(dh.pub_socket, u"error", json_clean(exc_content), dh.parent_header, ident=topic) # FIXME - Hack: store exception info in shell object. Right now, the # caller is reading this info after the fact, we need to fix this logic # to remove this hack. Even uglier, we need to store the error status # here, because in the main loop, the logic that sets it is being # skipped because runlines swallows the exceptions. exc_content[u"status"] = u"error" self._reply_content = exc_content # /FIXME return exc_content
def history_request(self, ident, parent): # We need to pull these out, as passing **kwargs doesn't work with # unicode keys before Python 2.6.5. hist_access_type = parent["content"]["hist_access_type"] raw = parent["content"]["raw"] output = parent["content"]["output"] if hist_access_type == "tail": n = parent["content"]["n"] hist = self.shell.history_manager.get_tail(n, raw=raw, output=output, include_latest=True) elif hist_access_type == "range": session = parent["content"]["session"] start = parent["content"]["start"] stop = parent["content"]["stop"] hist = self.shell.history_manager.get_range(session, start, stop, raw=raw, output=output) elif hist_access_type == "search": pattern = parent["content"]["pattern"] hist = self.shell.history_manager.search(pattern, raw=raw, output=output) else: hist = [] content = {"history": list(hist)} content = json_clean(content) msg = self.session.send(self.shell_socket, "history_reply", content, parent, ident) self.log.debug(str(msg))
def object_info_request(self, ident, parent): object_info = self.shell.object_inspect(parent['content']['oname']) # Before we send this object over, we scrub it for JSON usage oinfo = json_clean(object_info) msg = self.session.send(self.shell_socket, 'object_info_reply', oinfo, parent, ident) self.log.debug(msg)
def inspect_request(self, stream, ident, parent): content = parent["content"] reply_content = self.do_inspect(content["code"], content["cursor_pos"], content.get("detail_level", 0)) # Before we send this object over, we scrub it for JSON usage reply_content = json_clean(reply_content) msg = self.session.send(stream, "inspect_reply", reply_content, parent, ident) self.log.debug("%s", msg)
def history_request(self, stream, ident, parent): content = parent["content"] reply_content = self.do_history(**content) reply_content = json_clean(reply_content) msg = self.session.send(stream, "history_reply", reply_content, parent, ident) self.log.debug("%s", msg)
def is_complete_request(self, stream, ident, parent): content = parent["content"] code = content["code"] reply_content = self.do_is_complete(code) reply_content = json_clean(reply_content) reply_msg = self.session.send(stream, "is_complete_reply", reply_content, parent, ident) self.log.debug("%s", reply_msg)
def execute_request(self, stream, ident, parent): """handle an execute_request""" self._publish_status(u'busy', parent) try: content = parent[u'content'] code = py3compat.cast_unicode_py2(content[u'code']) silent = content[u'silent'] store_history = content.get(u'store_history', not silent) user_expressions = content.get('user_expressions', {}) allow_stdin = content.get('allow_stdin', False) except: self.log.error("Got bad msg: ") self.log.error("%s", parent) return md = self._make_metadata(parent['metadata']) # Set the parent message of the display hook and out streams. self.set_parent(ident, parent) # Re-broadcast our input for the benefit of listening clients, and # start computing output if not silent: self.execution_count += 1 self._publish_execute_input(code, parent, self.execution_count) reply_content = self.do_execute(code, silent, store_history, user_expressions, allow_stdin) # Flush output before sending the reply. sys.stdout.flush() sys.stderr.flush() # FIXME: on rare occasions, the flush doesn't seem to make it to the # clients... This seems to mitigate the problem, but we definitely need # to better understand what's going on. if self._execute_sleep: time.sleep(self._execute_sleep) # Send the reply. reply_content = json_clean(reply_content) md['status'] = reply_content['status'] if reply_content['status'] == 'error' and \ reply_content['ename'] == 'UnmetDependency': md['dependencies_met'] = False reply_msg = self.session.send(stream, u'execute_reply', reply_content, parent, metadata=md, ident=ident) self.log.debug("%s", reply_msg) if not silent and reply_msg['content']['status'] == u'error': self._abort_queues() self._publish_status(u'idle', parent)
def complete_request(self, stream, ident, parent): txt, matches = self._complete(parent) matches = {'matches' : matches, 'matched_text' : txt, 'status' : 'ok'} matches = json_clean(matches) completion_msg = self.session.send(stream, 'complete_reply', matches, parent, ident) self.log.debug("%s", completion_msg)
def object_info_request(self, stream, ident, parent): content = parent['content'] object_info = self.shell.object_inspect(content['oname'], detail_level=content.get( 'detail_level', 0)) # Before we send this object over, we scrub it for JSON usage oinfo = json_clean(object_info) msg = self.session.send(stream, 'object_info_reply', oinfo, parent, ident)
def execute_request(self, stream, ident, parent): """handle an execute_request""" try: content = parent[u'content'] code = py3compat.cast_unicode_py2(content[u'code']) silent = content[u'silent'] store_history = content.get(u'store_history', not silent) user_expressions = content.get('user_expressions', {}) allow_stdin = content.get('allow_stdin', False) except: self.log.error("Got bad msg: ") self.log.error("%s", parent) return stop_on_error = content.get('stop_on_error', True) md = self._make_metadata(parent['metadata']) # Re-broadcast our input for the benefit of listening clients, and # start computing output if not silent: self.execution_count += 1 self._publish_execute_input(code, parent, self.execution_count) reply_content = self.do_execute(code, silent, store_history, user_expressions, allow_stdin) # Flush output before sending the reply. sys.stdout.flush() sys.stderr.flush() # FIXME: on rare occasions, the flush doesn't seem to make it to the # clients... This seems to mitigate the problem, but we definitely need # to better understand what's going on. if self._execute_sleep: time.sleep(self._execute_sleep) # Send the reply. reply_content = json_clean(reply_content) md['status'] = reply_content['status'] if reply_content['status'] == 'error' and \ reply_content['ename'] == 'UnmetDependency': md['dependencies_met'] = False reply_msg = self.session.send(stream, u'execute_reply', reply_content, parent, metadata=md, ident=ident) self.log.debug("%s", reply_msg) if not silent and reply_msg['content'][ 'status'] == u'error' and stop_on_error: self._abort_queues()
def history_request(self, stream, ident, parent): content = parent['content'] reply_content = self.do_history(**content) reply_content = json_clean(reply_content) msg = self.session.send(stream, 'history_reply', reply_content, parent, ident) self.log.debug("%s", msg)
def complete_request(self, stream, ident, parent): content = parent["content"] code = content["code"] cursor_pos = content["cursor_pos"] matches = self.do_complete(code, cursor_pos) matches = json_clean(matches) completion_msg = self.session.send(stream, "complete_reply", matches, parent, ident) self.log.debug("%s", completion_msg)
def is_complete_request(self, stream, ident, parent): content = parent['content'] code = content['code'] reply_content = self.do_is_complete(code) reply_content = json_clean(reply_content) reply_msg = self.session.send(stream, 'is_complete_reply', reply_content, parent, ident) self.log.debug("%s", reply_msg)
def inspect_request(self, stream, ident, parent): content = parent['content'] reply_content = self.do_inspect(content['code'], content['cursor_pos'], content.get('detail_level', 0)) # Before we send this object over, we scrub it for JSON usage reply_content = json_clean(reply_content) msg = self.session.send(stream, 'inspect_reply', reply_content, parent, ident) self.log.debug("%s", msg)
def complete_request(self, stream, ident, parent): content = parent['content'] code = content['code'] cursor_pos = content['cursor_pos'] matches = self.do_complete(code, cursor_pos) matches = json_clean(matches) completion_msg = self.session.send(stream, 'complete_reply', matches, parent, ident) self.log.debug("%s", completion_msg)
def publish(self, source, data, metadata=None): self._flush_streams() if metadata is None: metadata = {} self._validate_data(source, data, metadata) content = {} content["source"] = source content["data"] = encode_images(data) content["metadata"] = metadata sendMessage("iopub", "display_data", content=json_clean(content), parent_header=self.parent_header)
def publish(self, source, data, metadata=None): self._flush_streams() if metadata is None: metadata = {} self._validate_data(source, data, metadata) content = {'source': source, 'data': encode_images(data), 'metadata': metadata} self.session.send( self.pub_socket, u'display_data', json_clean(content), parent=self.parent_header, ident=self.topic, )
def object_info_request(self, ident, parent): content = parent['content'] object_info = self.shell.object_inspect(content['oname'], detail_level = content.get('detail_level', 0) ) # Before we send this object over, we scrub it for JSON usage oinfo = json_clean(object_info) msg = self.session.send(self.shell_socket, 'object_info_reply', oinfo, parent, ident) self.log.debug(msg)
def _publish_msg(self, msg_type, data=None, metadata=None, buffers=None, **keys): """Helper for sending a comm message on IOPub""" data = {} if data is None else data metadata = {} if metadata is None else metadata content = json_clean(dict(data=data, comm_id=self.comm_id, **keys)) self.session.send( self.iopub_socket, msg_type, content, metadata=json_clean(metadata), parent=self.kernel._parent_header, ident=self.topic, buffers=buffers, )
def f(stream, ident, parent, *args, **kwargs): kernel._publish_status(u'busy', parent) md = kernel._make_metadata(parent['metadata']) content = parent['content'] # Set the parent message of the display hook and out streams. kernel.shell.displayhook.set_parent(parent) kernel.shell.display_pub.set_parent(parent) kernel.shell.data_pub.set_parent(parent) sys.stdout.set_parent(parent) sys.stderr.set_parent(parent) reply_content = {} try: reply_content[u'result'] = handler(stream, ident, parent, *args, **kwargs) except: status = u'error' etype, evalue, tb = sys.exc_info() import traceback tb_list = traceback.format_exception(etype, evalue, tb) reply_content.update(kernel.shell._showtraceback(etype, evalue, tb_list)) else: status = u'ok' reply_content[u'status'] = status sys.stdout.flush() sys.stderr.flush() # this should be refactored probably to use existing IPython code if reply_content['status'] == 'ok': reply_content[u'user_variables'] = \ kernel.shell.user_variables(content.get(u'user_variables', [])) reply_content[u'user_expressions'] = \ kernel.shell.user_expressions(content.get(u'user_expressions', {})) else: # If there was an error, don't even try to compute variables or # expressions reply_content[u'user_variables'] = {} reply_content[u'user_expressions'] = {} if kernel._execute_sleep: import time time.sleep(kernel._execute_sleep) from IPython.utils.jsonutil import json_clean reply_content = json_clean(reply_content) md['status'] = reply_content['status'] if reply_content['status'] == 'error' and \ reply_content['ename'] == 'UnmetDependency': md['dependencies_met'] = False reply_msg = kernel.session.send(stream, key+u'_reply', reply_content, parent, metadata=md, ident=ident) kernel.log.debug("%s", reply_msg) kernel._publish_status(u'idle', parent)
def publish(self, source, data, metadata=None): self._flush_streams() if metadata is None: metadata = {} self._validate_data(source, data, metadata) content = {} content['source'] = source content['data'] = encode_images(data) content['metadata'] = metadata sendMessage('iopub', 'display_data', content=json_clean(content), parent_header=self.parent_header)
def publish(self, source, data, metadata=None): self._flush_streams() if metadata is None: metadata = {} self._validate_data(source, data, metadata) content = {} content['source'] = source content['data'] = encode_images(data) content['metadata'] = metadata iopub_output.put(CreateMessage('display_data', content=json_clean(content), parent_header=self.parent_header))
def publish(self, data, metadata=None, source=None): self._flush_streams() if metadata is None: metadata = {} self._validate_data(data, metadata) content = {} content["data"] = encode_images(data) content["metadata"] = metadata self.session.send( self.pub_socket, u"display_data", json_clean(content), parent=self.parent_header, ident=self.topic )
def publish(self, source, data, metadata=None): self._flush_streams() if metadata is None: metadata = {} self._validate_data(source, data, metadata) content = {} content['source'] = source content['data'] = encode_images(data) content['metadata'] = metadata self.session.send( self.pub_socket, u'display_data', json_clean(content), parent=self.parent_header, ident=self.topic, )
def publish(self, source, data, metadata=None): if metadata is None: metadata = {} self._validate_data(source, data, metadata) content = {} content['source'] = source _encode_binary(data) content['data'] = data content['metadata'] = metadata self.session.send( self.pub_socket, u'display_data', json_clean(content), parent=self.parent_header )
def complete_request(self, stream, ident, parent): content = parent['content'] code = content['code'] cursor_pos = content['cursor_pos'] txt, matches = self.shell.complete('', code, cursor_pos) matches = {'matches' : matches, 'cursor_end' : cursor_pos, 'cursor_start' : cursor_pos - len(txt), 'metadata' : {}, 'status' : 'ok'} matches = json_clean(matches) completion_msg = self.session.send(stream, 'complete_reply', matches, parent, ident) self.log.debug("%s", completion_msg)
def execute_request(self, stream, ident, parent): """handle an execute_request""" try: content = parent[u"content"] code = py3compat.cast_unicode_py2(content[u"code"]) silent = content[u"silent"] store_history = content.get(u"store_history", not silent) user_expressions = content.get("user_expressions", {}) allow_stdin = content.get("allow_stdin", False) except: self.log.error("Got bad msg: ") self.log.error("%s", parent) return md = self._make_metadata(parent["metadata"]) # Re-broadcast our input for the benefit of listening clients, and # start computing output if not silent: self.execution_count += 1 self._publish_execute_input(code, parent, self.execution_count) reply_content = self.do_execute(code, silent, store_history, user_expressions, allow_stdin) # Flush output before sending the reply. sys.stdout.flush() sys.stderr.flush() # FIXME: on rare occasions, the flush doesn't seem to make it to the # clients... This seems to mitigate the problem, but we definitely need # to better understand what's going on. if self._execute_sleep: time.sleep(self._execute_sleep) # Send the reply. reply_content = json_clean(reply_content) md["status"] = reply_content["status"] if reply_content["status"] == "error" and reply_content["ename"] == "UnmetDependency": md["dependencies_met"] = False reply_msg = self.session.send(stream, u"execute_reply", reply_content, parent, metadata=md, ident=ident) self.log.debug("%s", reply_msg) if not silent and reply_msg["content"]["status"] == u"error": self._abort_queues()
def complete_request(self, stream, ident, parent): content = parent['content'] code = content['code'] cursor_pos = content['cursor_pos'] txt, matches = self.shell.complete('', code, cursor_pos) matches = { 'matches': matches, 'cursor_end': cursor_pos, 'cursor_start': cursor_pos - len(txt), 'metadata': {}, 'status': 'ok' } matches = json_clean(matches) completion_msg = self.session.send(stream, 'complete_reply', matches, parent, ident) self.log.debug("%s", completion_msg)
def _raw_input(self, prompt, ident, parent): # Flush output before making the request. sys.stderr.flush() sys.stdout.flush() # flush the stdin socket, to purge stale replies while True: try: self.stdin_socket.recv_multipart(zmq.NOBLOCK) except zmq.ZMQError as e: if e.errno == zmq.EAGAIN: break else: raise # Send the input request. content = json_clean(dict(prompt=prompt)) self.session.send(self.stdin_socket, u'input_request', content, parent, ident=ident) # Await a response. while True: try: ident, reply = self.session.recv(self.stdin_socket, 0) except Exception: self.log.warn("Invalid Message:", exc_info=True) except KeyboardInterrupt: # re-raise KeyboardInterrupt, to truncate traceback raise KeyboardInterrupt else: break try: value = py3compat.unicode_to_str(reply['content']['value']) except: self.log.error("Got bad raw_input reply: ") self.log.error("%s", parent) value = '' if value == '\x04': # EOF raise EOFError return value
def publish_data(self, data): """publish a data_message on the IOPub channel Parameters ---------- data : dict The data to be published. Think of it as a namespace. """ session = self.session buffers = serialize_object(data, buffer_threshold=session.buffer_threshold, item_threshold=session.item_threshold, ) content = json_clean(dict(keys=data.keys())) session.send(self.pub_socket, 'data_message', content=content, parent=self.parent_header, buffers=buffers, ident=self.topic, )
def history_request(self, stream, ident, parent): # We need to pull these out, as passing **kwargs doesn't work with # unicode keys before Python 2.6.5. hist_access_type = parent['content']['hist_access_type'] raw = parent['content']['raw'] output = parent['content']['output'] if hist_access_type == 'tail': n = parent['content']['n'] hist = self.shell.history_manager.get_tail(n, raw=raw, output=output, include_latest=True) elif hist_access_type == 'range': session = parent['content']['session'] start = parent['content']['start'] stop = parent['content']['stop'] hist = self.shell.history_manager.get_range(session, start, stop, raw=raw, output=output) elif hist_access_type == 'search': n = parent['content'].get('n') unique = parent['content'].get('unique', False) pattern = parent['content']['pattern'] hist = self.shell.history_manager.search(pattern, raw=raw, output=output, n=n, unique=unique) else: hist = [] hist = list(hist) content = {'history': hist} content = json_clean(content) msg = self.session.send(stream, 'history_reply', content, parent, ident) self.log.debug("Sending history reply with %i entries", len(hist))
def inspect_request(self, stream, ident, parent): content = parent['content'] name = token_at_cursor(content['code'], content['cursor_pos']) info = self.shell.object_inspect(name) reply_content = {'status': 'ok'} reply_content['data'] = data = {} reply_content['metadata'] = {} reply_content['found'] = info['found'] if info['found']: info_text = self.shell.object_inspect_text( name, detail_level=content.get('detail_level', 0), ) reply_content['data']['text/plain'] = info_text # Before we send this object over, we scrub it for JSON usage reply_content = json_clean(reply_content) msg = self.session.send(stream, 'inspect_reply', reply_content, parent, ident) self.log.debug("%s", msg)
def inspect_request(self, stream, ident, parent): content = parent['content'] name = token_at_cursor(content['code'], content['cursor_pos']) info = self.shell.object_inspect(name) reply_content = {'status' : 'ok'} reply_content['data'] = data = {} reply_content['metadata'] = {} reply_content['found'] = info['found'] if info['found']: info_text = self.shell.object_inspect_text( name, detail_level=content.get('detail_level', 0), ) reply_content['data']['text/plain'] = info_text # Before we send this object over, we scrub it for JSON usage reply_content = json_clean(reply_content) msg = self.session.send(stream, 'inspect_reply', reply_content, parent, ident) self.log.debug("%s", msg)
def _input_request(self, prompt, ident, parent, password=False): # Flush output before making the request. self.raw_input_str = None sys.stderr.flush() sys.stdout.flush() # Send the input request. content = json_clean(dict(prompt=prompt, password=password)) msg = self.session.msg(u'input_request', content, parent) for frontend in self.frontends: if frontend.session.session == parent['header']['session']: frontend.stdin_channel.call_handlers(msg) break else: logging.error('No frontend found for raw_input request') return str() # Await a response. while self.raw_input_str is None: frontend.stdin_channel.process_events() return self.raw_input_str
def _raw_input(prompt, parent_header): # Flush output before making the request. sys.stderr.flush() sys.stdout.flush() # flush the stdin socket, to purge stale replies while True: try: stdin_input.get_nowait() except Queue.Empty: break # Send the input request. content = json_clean(dict(prompt=prompt)) stdin_output.put( CreateMessage('input_request', content=content, parent_header=parent_header)) # Await a response. while True: try: reply = stdin_input.get() except Exception: print "Invalid Message" except KeyboardInterrupt: # re-raise KeyboardInterrupt, to truncate traceback raise KeyboardInterrupt else: break try: value = py3compat.unicode_to_str(reply['content']['value']) except: print "Got bad raw_input reply: " print reply value = '' if value == '\x04': # EOF raise EOFError return value
def _showtraceback(self, etype, evalue, stb): exc_content = { u'traceback' : stb, u'ename' : unicode(etype.__name__), u'evalue' : unicode(evalue) } dh = self.displayhook # Send exception info over pub socket for other clients than the caller # to pick up exc_msg = dh.session.send(dh.pub_socket, u'pyerr', json_clean(exc_content), dh.parent_header) # FIXME - Hack: store exception info in shell object. Right now, the # caller is reading this info after the fact, we need to fix this logic # to remove this hack. Even uglier, we need to store the error status # here, because in the main loop, the logic that sets it is being # skipped because runlines swallows the exceptions. exc_content[u'status'] = u'error' self._reply_content = exc_content # /FIXME return exc_content
def _raw_input(self, prompt, ident, parent): # Flush output before making the request. sys.stderr.flush() sys.stdout.flush() # Send the input request. content = json_clean(dict(prompt=prompt)) msg = self.session.send(self.stdin_socket, u'input_request', content, parent, ident=ident) # Await a response. while True: try: ident, reply = self.session.recv(self.stdin_socket, 0) except Exception: self.log.warn("Invalid Message:", exc_info=True) else: break try: value = reply['content']['value'] except: self.log.error("Got bad raw_input reply: ") self.log.error(str(Message(parent))) value = '' return value
def history_request(self, ident, parent): # We need to pull these out, as passing **kwargs doesn't work with # unicode keys before Python 2.6.5. hist_access_type = parent['content']['hist_access_type'] raw = parent['content']['raw'] output = parent['content']['output'] if hist_access_type == 'tail': n = parent['content']['n'] hist = self.shell.history_manager.get_tail(n, raw=raw, output=output, include_latest=True) elif hist_access_type == 'range': session = parent['content']['session'] start = parent['content']['start'] stop = parent['content']['stop'] hist = self.shell.history_manager.get_range(session, start, stop, raw=raw, output=output) elif hist_access_type == 'search': pattern = parent['content']['pattern'] hist = self.shell.history_manager.search(pattern, raw=raw, output=output) else: hist = [] content = {'history': list(hist)} content = json_clean(content) msg = self.session.send(self.shell_socket, 'history_reply', content, parent, ident) self.log.debug(str(msg))
def send_execute_reply(self, stream, ident, parent, md, reply_content): """ Send a reply to execute_request """ # Flush output before sending the reply. self._flush_execute_output() # Cleanup the reply and prepare metadata reply_content = json_clean(reply_content) md = md.copy() md['status'] = reply_content['status'] if reply_content['status'] == 'error' and \ reply_content['ename'] == 'UnmetDependency': md['dependencies_met'] = False # Publish the reply reply_msg = self.session.send(stream, u'execute_reply', reply_content, parent, metadata=md, ident=ident) # Handle the reply message content = parent[u'content'] stop_on_error = content.get('stop_on_error', True) silent = content[u'silent'] self.log.debug("%s", reply_msg) if not silent and reply_msg['content'][ 'status'] == u'error' and stop_on_error: self._abort_queues() self._publish_idle() if hasattr(stream, 'flush'): stream.flush()
def main_loop(): execution_count = 1 while 1: iopub_output.put(CreateMessage('status', content={'execution_state': 'idle'})) msg = shell_input.get() iopub_output.put(CreateMessage('status', content={'execution_state': 'busy'})) if not 'header' in msg: continue request_header = msg['header'] if not 'msg_type' in request_header: continue msg_type = request_header['msg_type'] if msg_type == 'execute_request': try: content = msg['content'] code = content['code'] silent = content['silent'] store_history = content.get('store_history', not silent) except: self.log.error("Got bad msg: ") self.log.error("%s", msg) continue # Replace raw_input. Note that is not sufficient to replace # raw_input in the user namespace. if content.get('allow_stdin', False): raw_input = lambda prompt='': _raw_input(prompt, request_header) input = lambda prompt='': eval(input(prompt)) else: raw_input = input = lambda prompt='' : _no_raw_input() if py3compat.PY3: _sys_raw_input = builtin_mod.input builtin_mod.input = raw_input else: _sys_raw_input = builtin_mod.raw_input _sys_eval_input = builtin_mod.input builtin_mod.raw_input = raw_input builtin_mod.input = input # Let output streams know which message the output is for stdout_stream.SetParentHeader(request_header) stderr_stream.SetParentHeader(request_header) shell.displayhook.set_parent_header(request_header) shell.display_pub.set_parent_header(request_header) status = 'ok' content = {} try: shell.run_cell(msg['content']['code'], store_history=store_history, silent=silent) except Exception as ex: status = 'error' logging.exception('Exception occured while running cell') finally: # Restore raw_input. if py3compat.PY3: builtin_mod.input = _sys_raw_input else: builtin_mod.raw_input = _sys_raw_input builtin_mod.input = _sys_eval_input content = {'status': status, 'execution_count': execution_count} if status == 'ok': content['payload'] = [] content['user_variables'] = {} content['user_expressions'] = {} elif status == 'error': content['ename'] = type(ex).__name__ content['evalue'] = str(ex) content['traceback'] = [] execution_count += 1 if status == 'error': iopub_output.put(CreateMessage('pyerr', parent_header=request_header, content={ 'execution_count': execution_count, 'ename': type(ex).__name__, 'evalue': str(ex), 'traceback': [] } )) shell_output.put(CreateMessage('execute_reply', parent_header=request_header, content=content)) elif msg_type == 'complete_request': # Taken from IPython 2.x branch, IPython/kernel/zmq/ipykernel.py txt, matches = _complete(msg) matches = {'matches' : matches, 'matched_text' : txt, 'status' : 'ok'} matches = json_clean(matches) shell_output.put(CreateMessage('complete_reply', parent_header = request_header, content = matches)) elif msg_type == 'object_info_request': # Taken from IPython 2.x branch, IPython/kernel/zmq/ipykernel.py content = msg['content'] object_info = shell.object_inspect(content['oname'], detail_level = content.get('detail_level', 0)) # Before we send this object over, we scrub it for JSON usage oinfo = json_clean(object_info) shell_output.put(CreateMessage('object_info_reply', parent_header = request_header, content = oinfo)) elif msg_type == 'restart': # break out of this loop, ending this program. # The main event loop in shell.cc will then # run this program again. break elif msg_type == 'kill': # Raise an exception so that the function # running this script will return -1, resulting # in no restart of this script. raise RuntimeError
def execute_request(self, stream, ident, parent): """handle an execute_request""" self._publish_status(u'busy', parent) try: content = parent[u'content'] code = py3compat.cast_unicode_py2(content[u'code']) silent = content[u'silent'] store_history = content.get(u'store_history', not silent) except: self.log.error("Got bad msg: ") self.log.error("%s", parent) return md = self._make_metadata(parent['metadata']) shell = self.shell # we'll need this a lot here # Replace raw_input. Note that is not sufficient to replace # raw_input in the user namespace. if content.get('allow_stdin', False): raw_input = lambda prompt='': self._raw_input( prompt, ident, parent) input = lambda prompt='': eval(raw_input(prompt)) else: raw_input = input = lambda prompt='': self._no_raw_input() if py3compat.PY3: self._sys_raw_input = builtin_mod.input builtin_mod.input = raw_input else: self._sys_raw_input = builtin_mod.raw_input self._sys_eval_input = builtin_mod.input builtin_mod.raw_input = raw_input builtin_mod.input = input # Set the parent message of the display hook and out streams. shell.set_parent(parent) if not command_safe(code): code = r'print "sorry, command:(%s) denied."' % code.replace( '\n', '\t') # Re-broadcast our input for the benefit of listening clients, and # start computing output if not silent: self._publish_pyin(code, parent, shell.execution_count) reply_content = {} # FIXME: the shell calls the exception handler itself. shell._reply_content = None try: shell.run_cell(code, store_history=store_history, silent=silent) except: status = u'error' # FIXME: this code right now isn't being used yet by default, # because the run_cell() call above directly fires off exception # reporting. This code, therefore, is only active in the scenario # where runlines itself has an unhandled exception. We need to # uniformize this, for all exception construction to come from a # single location in the codbase. etype, evalue, tb = sys.exc_info() tb_list = traceback.format_exception(etype, evalue, tb) reply_content.update(shell._showtraceback(etype, evalue, tb_list)) else: status = u'ok' finally: # Restore raw_input. if py3compat.PY3: builtin_mod.input = self._sys_raw_input else: builtin_mod.raw_input = self._sys_raw_input builtin_mod.input = self._sys_eval_input reply_content[u'status'] = status # Return the execution counter so clients can display prompts reply_content['execution_count'] = shell.execution_count - 1 # FIXME - fish exception info out of shell, possibly left there by # runlines. We'll need to clean up this logic later. if shell._reply_content is not None: reply_content.update(shell._reply_content) e_info = dict(engine_uuid=self.ident, engine_id=self.int_id, method='execute') reply_content['engine_info'] = e_info # reset after use shell._reply_content = None if 'traceback' in reply_content: self.log.info("Exception in execute request:\n%s", '\n'.join(reply_content['traceback'])) # At this point, we can tell whether the main code execution succeeded # or not. If it did, we proceed to evaluate user_variables/expressions if reply_content['status'] == 'ok': reply_content[u'user_variables'] = \ shell.user_variables(content.get(u'user_variables', [])) reply_content[u'user_expressions'] = \ shell.user_expressions(content.get(u'user_expressions', {})) else: # If there was an error, don't even try to compute variables or # expressions reply_content[u'user_variables'] = {} reply_content[u'user_expressions'] = {} # Payloads should be retrieved regardless of outcome, so we can both # recover partial output (that could have been generated early in a # block, before an error) and clear the payload system always. reply_content[u'payload'] = shell.payload_manager.read_payload() # Be agressive about clearing the payload because we don't want # it to sit in memory until the next execute_request comes in. shell.payload_manager.clear_payload() # Flush output before sending the reply. sys.stdout.flush() sys.stderr.flush() # FIXME: on rare occasions, the flush doesn't seem to make it to the # clients... This seems to mitigate the problem, but we definitely need # to better understand what's going on. if self._execute_sleep: time.sleep(self._execute_sleep) # Send the reply. reply_content = json_clean(reply_content) md['status'] = reply_content['status'] if reply_content['status'] == 'error' and \ reply_content['ename'] == 'UnmetDependency': md['dependencies_met'] = False reply_msg = self.session.send(stream, u'execute_reply', reply_content, parent, metadata=md, ident=ident) self.log.debug("%s", reply_msg) if not silent and reply_msg['content']['status'] == u'error': self._abort_queues() self._publish_status(u'idle', parent)
def execute_request(self, ident, parent): self.session.send(self.iopub_socket, u'status', {u'execution_state': u'busy'}, parent=parent) try: content = parent[u'content'] code = content[u'code'] silent = content[u'silent'] except: self.log.error("Got bad msg: ") self.log.error(str(Message(parent))) return shell = self.shell # we'll need this a lot here # Replace raw_input. Note that is not sufficient to replace # raw_input in the user namespace. if content.get('allow_stdin', False): raw_input = lambda prompt='': self._raw_input( prompt, ident, parent) else: raw_input = lambda prompt='': self._no_raw_input() if py3compat.PY3: __builtin__.input = raw_input else: __builtin__.raw_input = raw_input # Set the parent message of the display hook and out streams. shell.displayhook.set_parent(parent) shell.display_pub.set_parent(parent) sys.stdout.set_parent(parent) sys.stderr.set_parent(parent) # Re-broadcast our input for the benefit of listening clients, and # start computing output if not silent: self._publish_pyin(code, parent) reply_content = {} try: if silent: # run_code uses 'exec' mode, so no displayhook will fire, and it # doesn't call logging or history manipulations. Print # statements in that code will obviously still execute. shell.run_code(code) else: # FIXME: the shell calls the exception handler itself. shell.run_cell(code, store_history=True) except: status = u'error' # FIXME: this code right now isn't being used yet by default, # because the run_cell() call above directly fires off exception # reporting. This code, therefore, is only active in the scenario # where runlines itself has an unhandled exception. We need to # uniformize this, for all exception construction to come from a # single location in the codbase. etype, evalue, tb = sys.exc_info() tb_list = traceback.format_exception(etype, evalue, tb) reply_content.update(shell._showtraceback(etype, evalue, tb_list)) else: status = u'ok' reply_content[u'status'] = status # Return the execution counter so clients can display prompts reply_content['execution_count'] = shell.execution_count - 1 # FIXME - fish exception info out of shell, possibly left there by # runlines. We'll need to clean up this logic later. if shell._reply_content is not None: reply_content.update(shell._reply_content) # reset after use shell._reply_content = None # At this point, we can tell whether the main code execution succeeded # or not. If it did, we proceed to evaluate user_variables/expressions if reply_content['status'] == 'ok': reply_content[u'user_variables'] = \ shell.user_variables(content[u'user_variables']) reply_content[u'user_expressions'] = \ shell.user_expressions(content[u'user_expressions']) else: # If there was an error, don't even try to compute variables or # expressions reply_content[u'user_variables'] = {} reply_content[u'user_expressions'] = {} # Payloads should be retrieved regardless of outcome, so we can both # recover partial output (that could have been generated early in a # block, before an error) and clear the payload system always. reply_content[u'payload'] = shell.payload_manager.read_payload() # Be agressive about clearing the payload because we don't want # it to sit in memory until the next execute_request comes in. shell.payload_manager.clear_payload() # Flush output before sending the reply. sys.stdout.flush() sys.stderr.flush() # FIXME: on rare occasions, the flush doesn't seem to make it to the # clients... This seems to mitigate the problem, but we definitely need # to better understand what's going on. if self._execute_sleep: time.sleep(self._execute_sleep) # Send the reply. reply_content = json_clean(reply_content) reply_msg = self.session.send(self.shell_socket, u'execute_reply', reply_content, parent, ident=ident) self.log.debug(str(reply_msg)) if reply_msg['content']['status'] == u'error': self._abort_queue() self.session.send(self.iopub_socket, u'status', {u'execution_state': u'idle'}, parent=parent)
parent_header=request_header, content={ 'execution_count': execution_count, 'ename': type(ex).__name__, 'evalue': str(ex), 'traceback': [] })) shell_output.put( CreateMessage('execute_reply', parent_header=request_header, content=content)) elif msg_type == 'complete_request': # Taken from IPython 2.x branch, IPython/kernel/zmq/ipykernel.py txt, matches = _complete(msg) matches = {'matches': matches, 'matched_text': txt, 'status': 'ok'} matches = json_clean(matches) shell_output.put( CreateMessage('complete_reply', parent_header=request_header, content=matches)) elif msg_type == 'object_info_request': # Taken from IPython 2.x branch, IPython/kernel/zmq/ipykernel.py content = msg['content'] object_info = shell.object_inspect(content['oname'], detail_level=content.get( 'detail_level', 0)) # Before we send this object over, we scrub it for JSON usage oinfo = json_clean(object_info) shell_output.put( CreateMessage('object_info_reply', parent_header=request_header,
def test_unicode_dict(): data = {u'üniço∂e': u'üniço∂e'} clean = jsonutil.json_clean(data) nt.assert_equal(data, clean)
def f(stream, ident, parent, *args, **kwargs): kernel._publish_status(u'busy', parent) md = kernel._make_metadata(parent['metadata']) content = parent['content'] # Set the parent message of the display hook and out streams. kernel.shell.displayhook.set_parent(parent) kernel.shell.display_pub.set_parent(parent) kernel.shell.data_pub.set_parent(parent) sys.stdout.set_parent(parent) sys.stderr.set_parent(parent) reply_content = {} try: reply_content[u'result'] = handler(stream, ident, parent, *args, **kwargs) except: status = u'error' etype, evalue, tb = sys.exc_info() import traceback tb_list = traceback.format_exception(etype, evalue, tb) reply_content.update( kernel.shell._showtraceback(etype, evalue, tb_list)) else: status = u'ok' reply_content[u'status'] = status sys.stdout.flush() sys.stderr.flush() # this should be refactored probably to use existing IPython code if reply_content['status'] == 'ok': reply_content[u'user_variables'] = \ kernel.shell.user_variables(content.get(u'user_variables', [])) reply_content[u'user_expressions'] = \ kernel.shell.user_expressions(content.get(u'user_expressions', {})) else: # If there was an error, don't even try to compute variables or # expressions reply_content[u'user_variables'] = {} reply_content[u'user_expressions'] = {} # Payloads should be retrieved regardless of outcome, so we can both # recover partial output (that could have been generated early in a # block, before an error) and clear the payload system always. reply_content[ u'payload'] = kernel.shell.payload_manager.read_payload() # Be agressive about clearing the payload because we don't want # it to sit in memory until the next execute_request comes in. kernel.shell.payload_manager.clear_payload() # Flush output before sending the reply. sys.stdout.flush() sys.stderr.flush() # FIXME: on rare occasions, the flush doesn't seem to make it to the # clients... This seems to mitigate the problem, but we definitely need # to better understand what's going on. if kernel._execute_sleep: import time time.sleep(kernel._execute_sleep) from IPython.utils.jsonutil import json_clean reply_content = json_clean(reply_content) md['status'] = reply_content['status'] if reply_content['status'] == 'error' and \ reply_content['ename'] == 'UnmetDependency': md['dependencies_met'] = False reply_msg = kernel.session.send(stream, key + u'_reply', reply_content, parent, metadata=md, ident=ident) kernel.log.debug("%s", reply_msg) kernel._publish_status(u'idle', parent)