From 15a9d1080d7ce9e1779a57f5519db099c7d864a6 Mon Sep 17 00:00:00 2001 From: Aliaksandr Yakutovich Date: Fri, 21 Jun 2024 14:01:21 +0000 Subject: [PATCH] Move widgets to control module. --- control.ipynb | 184 +++--------------------------------------------- home/control.py | 118 +++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 174 deletions(-) create mode 100644 home/control.py diff --git a/control.ipynb b/control.ipynb index 798ffa8..ce07a3e 100644 --- a/control.ipynb +++ b/control.ipynb @@ -16,165 +16,10 @@ "outputs": [], "source": [ "import ipywidgets as ipw\n", - "from IPython.display import clear_output, display" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6771e870", - "metadata": {}, - "outputs": [], - "source": [ - "import subprocess\n", - "from aiida import engine\n", - "\n", - "class DaemonControlPage(ipw.VBox):\n", - " def __init__(self, *args, **kwargs):\n", - " self._daemon = engine.daemon.get_daemon_client()\n", - " self._status = ipw.Output()\n", - "\n", - " # Start daemon.\n", - " start_button = ipw.Button(description=\"Start daemon\", button_style=\"info\")\n", - " start_button.on_click(self._start_daemon)\n", - "\n", - " # Stop daemon.\n", - " stop_button = ipw.Button(description=\"Stop daemon\", button_style=\"danger\")\n", - " stop_button.on_click(self._stop_daemon)\n", - "\n", - " # Restart daemon.\n", - " restart_button = ipw.Button(description=\"Restart daemon\", button_style=\"warning\")\n", - " restart_button.on_click(self._restart_daemon)\n", - "\n", - " self.info=ipw.HTML()\n", - " self._update_status()\n", - " super().__init__(children=[self.info, self._status, ipw.HBox([start_button, stop_button, restart_button])])\n", - "\n", - " def _restart_daemon(self, _=None):\n", - " self._clear_status()\n", - " self.info.value = \"Restarting the daemon...\"\n", - " response = self._daemon.restart_daemon()\n", - " self.info.value = \"\"\n", - " self._update_status()\n", - " return response\n", - "\n", - " def _start_daemon(self, _=None):\n", - " self._clear_status()\n", - " self.info.value = \"Starting the daemon...\"\n", - " response = self._daemon.start_daemon()\n", - " self.info.value = \"\"\n", - " self._update_status()\n", - " return response\n", - "\n", - " def _stop_daemon(self, _=None):\n", - " self._clear_status()\n", - " self.info.value = \"Stopping the daemon...\"\n", - " response = self._daemon.stop_daemon()\n", - " self.info.value = \"\"\n", - " self._update_status()\n", - " return response\n", - "\n", - " def _update_status(self, _=None):\n", - " self._clear_status()\n", - " with self._status:\n", - " result = subprocess.run([\"verdi\", \"daemon\", \"status\"], capture_output=True, text=True)\n", - " print(result.stdout, result.stderr)\n", - " \n", - " def _clear_status(self):\n", - " with self._status:\n", - " clear_output()\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f9bf1735", - "metadata": {}, - "outputs": [], - "source": [ - "import aiidalab_widgets_base as awb\n", - "from aiida import orm\n", - "\n", - "class ProcessControlPage(ipw.HBox):\n", - " def __init__(self, *args, **kwargs):\n", - " child_calcs = orm.QueryBuilder().append(orm.WorkflowNode, tag=\"node\").append(orm.ProcessNode, with_incoming=\"node\", filters={'attributes': {'!has_key': 'sealed'}}, project='id').all(flat=True)\n", - " query = orm.QueryBuilder().append(orm.ProcessNode, filters={'id': {'!in': child_calcs}, 'attributes':{'!has_key': 'sealed'}}, project='uuid')\n", - " self.process_list = [awb.ProcessNodesTreeWidget(value=p) for p in query.all(flat=True)]\n", - " for process in self.process_list:\n", - " process.observe(self._on_select, names=\"selected_nodes\")\n", - " self._selected = ipw.HTML()\n", - "\n", - " # Pause process.\n", - " pause_button = ipw.Button(description=\"Pause process\", button_style=\"warning\")\n", - " #pause_button.on_click(self._pause_process)\n", - " \n", - " # Play process.\n", - " play_button = ipw.Button(description=\"Play process\", button_style=\"success\")\n", - " #play_button.on_click(self._play_process)\n", - "\n", - " # Kill process.\n", - " kill_button = ipw.Button(description=\"Kill process\", button_style=\"danger\")\n", - " #play_button.on_click(self._kill_process)\n", - "\n", - " super().__init__(children=[ipw.VBox(self.process_list + [self._selected]), ipw.VBox([pause_button, play_button, kill_button])])\n", - " \n", - " def _on_select(self, change=None):\n", - " self._selected_uuid = change['new'][0].uuid\n", - " self._selected.value = self._selected_uuid\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f0701df6", - "metadata": {}, - "outputs": [], - "source": [ - "class GroupControlPage(ipw.VBox):\n", - " def __init__(self):\n", - " text = ipw.HTML(\"I am a Group Control Page\")\n", - " super().__init__(children=[text])\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e53249ac", - "metadata": {}, - "outputs": [], - "source": [ - "import subprocess\n", - "class StatusControlPage(ipw.HTML):\n", - " def __init__(self):\n", - " print(\"AiiDA status\")\n", - " print(subprocess.run([\"verdi\", \"status\"], capture_output=True, text=True).stdout)\n", - " super().__init__()\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4f6d2bdf", - "metadata": {}, - "outputs": [], - "source": [ - "from aiida import manage\n", - "\n", - "class Profile(ipw.HBox):\n", - " def __init__(self, profile):\n", - " self.profile = profile\n", - " self.name = ipw.HTML(f\"\"\" * {self.profile.name}\"\"\")\n", - " self.make_default = ipw.Button(description=\"Make default\", button_style=\"info\")\n", - " self.delete = ipw.Button(description=\"Delele\", button_style=\"danger\")\n", - " super().__init__(children=[self.name, self.make_default, self.delete])\n", - "\n", - "\n", - "class ProfileControlPage(ipw.VBox):\n", - " def __init__(self):\n", - " text = ipw.HTML(value=\"

List of profiles

\")\n", - " children = [Profile(p) for p in manage.get_config().profiles]\n", - " super().__init__(children=children)\n" + "from IPython.display import clear_output, display\n", + "from aiida import load_profile\n", + "load_profile();\n", + "from home.control import DaemonControlWidget, ProcessControlWidget, GroupControlWidget, StatusControlWidget, ProfileControlWidget" ] }, { @@ -185,11 +30,11 @@ "outputs": [], "source": [ "correspondance = {\n", - " \"Daemon\": DaemonControlPage,\n", - " \"Group\": GroupControlPage,\n", - " \"Process\": ProcessControlPage,\n", - " \"Status\": StatusControlPage,\n", - " \"Profile\": ProfileControlPage,\n", + " \"Daemon\": DaemonControlWidget,\n", + " \"Group\": GroupControlWidget,\n", + " \"Process\": ProcessControlWidget,\n", + " \"Status\": StatusControlWidget,\n", + " \"Profile\": ProfileControlWidget,\n", "}\n", "\n", "toc = ipw.ToggleButtons(\n", @@ -212,16 +57,7 @@ "\n", "toc.observe(update_output, names=\"value\")\n", "\n", - "toc.value = \"Daemon\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e5e71656", - "metadata": {}, - "outputs": [], - "source": [ + "toc.value = \"Daemon\"\n", "display(ipw.HBox([toc, output]))" ] } diff --git a/home/control.py b/home/control.py new file mode 100644 index 0000000..71702b5 --- /dev/null +++ b/home/control.py @@ -0,0 +1,118 @@ +import subprocess +from aiida import engine +import ipywidgets as ipw +import aiidalab_widgets_base as awb +from aiida import orm, manage +import plumpy +import traitlets as tr +from IPython.display import clear_output +import subprocess + +class DaemonControlWidget(ipw.VBox): + def __init__(self, *args, **kwargs): + self._daemon = engine.daemon.get_daemon_client() + self._status = ipw.Output() + + # Start daemon. + start_button = ipw.Button(description="Start daemon", button_style="info") + start_button.on_click(self._start_daemon) + + # Stop daemon. + stop_button = ipw.Button(description="Stop daemon", button_style="danger") + stop_button.on_click(self._stop_daemon) + + # Restart daemon. + restart_button = ipw.Button(description="Restart daemon", button_style="warning") + restart_button.on_click(self._restart_daemon) + + self.info=ipw.HTML() + self._update_status() + super().__init__(children=[self.info, self._status, ipw.HBox([start_button, stop_button, restart_button])]) + + def _restart_daemon(self, _=None): + self._clear_status() + self.info.value = "Restarting the daemon..." + response = self._daemon.restart_daemon() + self.info.value = "" + self._update_status() + return response + + def _start_daemon(self, _=None): + self._clear_status() + self.info.value = "Starting the daemon..." + response = self._daemon.start_daemon() + self.info.value = "" + self._update_status() + return response + + def _stop_daemon(self, _=None): + self._clear_status() + self.info.value = "Stopping the daemon..." + response = self._daemon.stop_daemon() + self.info.value = "" + self._update_status() + return response + + def _update_status(self, _=None): + self._clear_status() + with self._status: + result = subprocess.run(["verdi", "daemon", "status"], capture_output=True, text=True) + print(result.stdout, result.stderr) + + def _clear_status(self): + with self._status: + clear_output() + + + +class ProcessControlWidget(ipw.VBox): + def __init__(self): + process_list = awb.ProcessListWidget(path_to_root="../../") + past_days_widget = ipw.IntText(value=7, description='Past days:') + tr.link((past_days_widget, 'value'), (process_list, 'past_days')) + + all_days_checkbox = ipw.Checkbox(description="All days", value=True) + tr.dlink((all_days_checkbox, 'value'), (past_days_widget, 'disabled')) + tr.dlink((all_days_checkbox, 'value'), (process_list, 'past_days'), transform=lambda v: -1 if v else past_days_widget.value) + + available_states = [state.value for state in plumpy.ProcessState] + process_state_widget = ipw.SelectMultiple(options=available_states, + value=["running", "waiting"], + description='Process State:', + style={'description_width': 'initial'}, + disabled=False) + tr.dlink((process_state_widget, 'value'), (process_list, 'process_states')) + process_list.update() + + + super().__init__(children=[ipw.HBox([past_days_widget, all_days_checkbox]), process_state_widget, process_list]) + + + +class GroupControlWidget(ipw.VBox): + def __init__(self): + text = ipw.HTML("I am a Group Control Page") + super().__init__(children=[text]) + + +class StatusControlWidget(ipw.HTML): + def __init__(self): + print("AiiDA status") + print(subprocess.run(["verdi", "status"], capture_output=True, text=True).stdout) + super().__init__() + + +class Profile(ipw.HBox): + def __init__(self, profile): + self.profile = profile + self.name = ipw.HTML(f""" * {self.profile.name}""") + self.make_default = ipw.Button(description="Make default", button_style="info") + self.delete = ipw.Button(description="Delele", button_style="danger") + super().__init__(children=[self.name, self.make_default, self.delete]) + + +class ProfileControlWidget(ipw.VBox): + def __init__(self): + text = ipw.HTML(value="

List of profiles

") + children = [Profile(p) for p in manage.get_config().profiles] + super().__init__(children=children)