from myfasthtml.controls.VisNetwork import VisNetwork from myfasthtml.core.commands import CommandsManager from myfasthtml.core.instances import SingleInstance, InstancesManager from myfasthtml.core.network_utils import from_parent_child_list class CommandsDebugger(SingleInstance): """ Represents a debugger designed for visualizing and managing commands in a parent-child hierarchical structure. """ def __init__(self, parent, _id=None): super().__init__(parent, _id=_id) def render(self): nodes, edges = self._get_nodes_and_edges() vis_network = VisNetwork(self, nodes=nodes, edges=edges) return vis_network @staticmethod def get_command_parent_from_ft(command): if (ft := command.get_ft()) is None: return None if hasattr(ft, "get_id") and callable(ft.get_id): return ft.get_id() if hasattr(ft, "get_prefix") and callable(ft.get_prefix): return ft.get_prefix() if hasattr(ft, "attrs"): return ft.attrs.get("id", None) return None @staticmethod def get_command_parent_from_instance(command): if command.owner is None: return None return command.owner.get_full_id() def _get_nodes_and_edges(self): commands = self._get_commands() nodes, edges = from_parent_child_list(commands, id_getter=lambda x: str(x.id), label_getter=lambda x: x.name, parent_getter=lambda x: str(self.get_command_parent_from_instance(x)), ghost_label_getter=lambda x: InstancesManager.get(*x.split("#")).get_id() ) for edge in edges: edge["color"] = "blue" edge["arrows"] = {"to": {"enabled": False, "type": "circle"}} for node in nodes: node["shape"] = "box" return nodes, edges def _get_commands(self): return list(CommandsManager.commands.values()) def __ft__(self): return self.render()