|
from jupyter_client import KernelManager |
|
import threading |
|
import re |
|
|
|
|
|
class JupyterNotebook: |
|
def __init__(self): |
|
self.km = KernelManager() |
|
self.km.start_kernel() |
|
self.kc = self.km.client() |
|
|
|
def clean_output(self, outputs): |
|
outputs_only_str = list() |
|
for i in outputs: |
|
if type(i) == dict: |
|
if "text/plain" in list(i.keys()): |
|
outputs_only_str.append(i["text/plain"]) |
|
elif type(i) == str: |
|
outputs_only_str.append(i) |
|
elif type(i) == list: |
|
error_msg = "\n".join(i) |
|
error_msg = re.sub(r"\x1b\[.*?m", "", error_msg) |
|
outputs_only_str.append(error_msg) |
|
|
|
return "\n".join(outputs_only_str).strip() |
|
|
|
def add_and_run(self, code_string): |
|
|
|
def run_code_in_thread(): |
|
nonlocal outputs, error_flag |
|
|
|
|
|
msg_id = self.kc.execute(code_string) |
|
|
|
while True: |
|
try: |
|
msg = self.kc.get_iopub_msg(timeout=20) |
|
|
|
msg_type = msg["header"]["msg_type"] |
|
content = msg["content"] |
|
|
|
if msg_type == "execute_result": |
|
outputs.append(content["data"]) |
|
elif msg_type == "stream": |
|
outputs.append(content["text"]) |
|
elif msg_type == "error": |
|
error_flag = True |
|
outputs.append(content["traceback"]) |
|
|
|
|
|
if msg_type == "status" and content["execution_state"] == "idle": |
|
break |
|
except: |
|
break |
|
|
|
outputs = [] |
|
error_flag = False |
|
|
|
|
|
thread = threading.Thread(target=run_code_in_thread) |
|
thread.start() |
|
|
|
|
|
thread.join(timeout=10) |
|
|
|
|
|
if thread.is_alive(): |
|
outputs = ["Timeout after 10 seconds"] |
|
error_flag = True |
|
|
|
return self.clean_output(outputs), error_flag |
|
|
|
def close(self): |
|
"""Shutdown the kernel.""" |
|
self.km.shutdown_kernel() |
|
|