class Kernel: name: str init_code: str = "" language: str = "" manager: Optional[KernelManager] = field(default=None, init=False) client: Optional[KernelClient] = field(default=None, init=False) report: Dict[str, Any] = field(default_factory=dict, init=False) def __post_init__(self): self.report["total"] = datetime.timedelta(0) kernel_spec = get_kernel_spec(self.name) self.language = kernel_spec.language if self.language == "python": self.init_code = ( "from pheasant.renderers.jupyter.ipython import register_formatters\n" "register_formatters()") def shutdown(): # pragma: no cover if self.manager: print(f"Shutting down kernel [{self.name}]...", end="") self.manager.shutdown_kernel() print("Done.") atexit.register(shutdown) def start(self, timeout=10, silent=True) -> KernelClient: if self.manager: if self.manager.is_alive(): return self.client else: # pragma: no cover raise RuntimeError(f"Kernel {self.name} is not alive.") def start(): self.manager = KernelManager(kernel_name=self.name) self.manager.start_kernel() self.client = self.manager.blocking_client() self.client.start_channels() try: self.client.wait_for_ready(timeout=timeout) except TimeoutError: # pragma: no cover self.manager.shutdown_kernel() return False else: self.client.execute_interactive(self.init_code) return self.client init = f"Starting kernel [{self.name}]" progress_bar = progress_bar_factory(total=3, init=init) now = datetime.datetime.now() def message(result): dt = format_timedelta_human(datetime.datetime.now() - now) return f"Kernel [{self.name}] started ({dt})" if result else "Retrying..." for k in range(progress_bar.total): if silent and start(): break elif silent: continue elif progress_bar.progress(start, message): progress_bar.finish() break else: raise TimeoutError # pragma: no cover return self.client def shutdown(self) -> None: if self.manager: self.manager.shutdown_kernel() del self.client self.client = None del self.manager self.manager = None def restart(self) -> None: if self.manager: self.manager.restart_kernel() if self.client and self.init_code: self.client.execute_interactive(self.init_code) def execute(self, code: str, output_hook=None) -> List: client = self.client or self.start() outputs = [] def _output_hook(msg): if output_hook: output_hook(msg) output = output_from_msg(msg) if output: outputs.append(output) msg = client.execute_interactive(code, output_hook=_output_hook) update_report(self.report, msg) return list(stream_joiner(outputs)) def inspect(self, code: str, func: str = "getsource", output_hook=None) -> List: self.execute("import inspect") self.execute(code, output_hook=output_hook) outputs = self.execute(code_for_inspect(func)) if len(outputs) == 1 and outputs[0]["type"] == "execute_result": source = ast.literal_eval(outputs[0]["data"]["text/plain"]) return [dict(type="stream", name="source", text=source)] else: return outputs
import pathlib from jupyter_client.manager import KernelManager from jupyter_client.connect import find_connection_file # forkする? m = KernelManager() m.connection_file = "kernel-me.json" m.write_connection_file() info = m.get_connection_info() print(info) print(m.connection_file) print(find_connection_file()) print(find_connection_file(pathlib.Path(m.connection_file).name)) # m.load_connection_file() m.blocking_client()