| | 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() |
| |
|