From 95cc9893146dfcbdf53d339e7f548347986f6d34 Mon Sep 17 00:00:00 2001 From: Aliaksandr Yakutovich Date: Thu, 20 Jul 2023 12:12:59 +0000 Subject: [PATCH 1/6] Draft implementation of the AiiDA control page. --- control.ipynb | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++ start.py | 24 ++++- 2 files changed, 269 insertions(+), 5 deletions(-) create mode 100644 control.ipynb diff --git a/control.ipynb b/control.ipynb new file mode 100644 index 0000000..798ffa8 --- /dev/null +++ b/control.ipynb @@ -0,0 +1,250 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "2f454b5b", + "metadata": {}, + "source": [ + "# AiiDA control" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "03c3d207", + "metadata": {}, + "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" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "56f4a261", + "metadata": {}, + "outputs": [], + "source": [ + "correspondance = {\n", + " \"Daemon\": DaemonControlPage,\n", + " \"Group\": GroupControlPage,\n", + " \"Process\": ProcessControlPage,\n", + " \"Status\": StatusControlPage,\n", + " \"Profile\": ProfileControlPage,\n", + "}\n", + "\n", + "toc = ipw.ToggleButtons(\n", + " options=correspondance.keys(),\n", + " value=None,\n", + " orientation=\"vertical\",\n", + " layout=ipw.Layout(width='200px')\n", + ")\n", + "\n", + "\n", + "\n", + "output = ipw.Output()\n", + "\n", + "def update_output(value={\"new\": \"Group\"}):\n", + " if value['new'] in correspondance:\n", + " with output:\n", + " clear_output()\n", + " display(correspondance[value['new']]())\n", + "\n", + "\n", + "toc.observe(update_output, names=\"value\")\n", + "\n", + "toc.value = \"Daemon\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e5e71656", + "metadata": {}, + "outputs": [], + "source": [ + "display(ipw.HBox([toc, output]))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/start.py b/start.py index 53fc027..70783da 100644 --- a/start.py +++ b/start.py @@ -3,6 +3,9 @@ def get_start_widget(appbase, jupbase): # http://fontawesome.io/icons/ + + width = "70px" + template = """
@@ -15,7 +18,7 @@ def get_start_widget(appbase, jupbase): File Manager - + - + - + - + + + + +
@@ -24,7 +27,7 @@ def get_start_widget(appbase, jupbase): Terminal @@ -33,7 +36,7 @@ def get_start_widget(appbase, jupbase): Tasks @@ -42,7 +45,16 @@ def get_start_widget(appbase, jupbase): App Store + + +
+ Control +
@@ -55,5 +67,7 @@ def get_start_widget(appbase, jupbase): """ - html = template.format(appbase=appbase, jupbase=jupbase, style="margin:20px") + html = template.format( + appbase=appbase, jupbase=jupbase, style="margin:20px", width=width + ) return ipw.HTML(html) From 15a9d1080d7ce9e1779a57f5519db099c7d864a6 Mon Sep 17 00:00:00 2001 From: Aliaksandr Yakutovich Date: Fri, 21 Jun 2024 14:01:21 +0000 Subject: [PATCH 2/6] 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) From abb5e987241773f46296d8561c7eca6ef67c790d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 21 Jun 2024 14:02:54 +0000 Subject: [PATCH 3/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- control.ipynb | 6 ++--- home/control.py | 69 ++++++++++++++++++++++++++++++++----------------- 2 files changed, 48 insertions(+), 27 deletions(-) diff --git a/control.ipynb b/control.ipynb index ce07a3e..a5a58ad 100644 --- a/control.ipynb +++ b/control.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "2f454b5b", + "id": "0", "metadata": {}, "source": [ "# AiiDA control" @@ -11,7 +11,7 @@ { "cell_type": "code", "execution_count": null, - "id": "03c3d207", + "id": "1", "metadata": {}, "outputs": [], "source": [ @@ -25,7 +25,7 @@ { "cell_type": "code", "execution_count": null, - "id": "56f4a261", + "id": "2", "metadata": {}, "outputs": [], "source": [ diff --git a/home/control.py b/home/control.py index 71702b5..081f64e 100644 --- a/home/control.py +++ b/home/control.py @@ -1,12 +1,12 @@ import subprocess -from aiida import engine -import ipywidgets as ipw + import aiidalab_widgets_base as awb -from aiida import orm, manage +import ipywidgets as ipw import plumpy import traitlets as tr +from aiida import engine, manage from IPython.display import clear_output -import subprocess + class DaemonControlWidget(ipw.VBox): def __init__(self, *args, **kwargs): @@ -22,12 +22,20 @@ def __init__(self, *args, **kwargs): stop_button.on_click(self._stop_daemon) # Restart daemon. - restart_button = ipw.Button(description="Restart daemon", button_style="warning") + restart_button = ipw.Button( + description="Restart daemon", button_style="warning" + ) restart_button.on_click(self._restart_daemon) - self.info=ipw.HTML() + self.info = ipw.HTML() self._update_status() - super().__init__(children=[self.info, self._status, ipw.HBox([start_button, stop_button, restart_button])]) + super().__init__( + children=[ + self.info, + self._status, + ipw.HBox([start_button, stop_button, restart_button]), + ] + ) def _restart_daemon(self, _=None): self._clear_status() @@ -56,37 +64,48 @@ def _stop_daemon(self, _=None): def _update_status(self, _=None): self._clear_status() with self._status: - result = subprocess.run(["verdi", "daemon", "status"], capture_output=True, text=True) + result = subprocess.run( + ["verdi", "daemon", "status"], capture_output=True, text=True, check=False + ) 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')) + 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) + 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_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]) - + super().__init__( + children=[ + ipw.HBox([past_days_widget, all_days_checkbox]), + process_state_widget, + process_list, + ] + ) class GroupControlWidget(ipw.VBox): @@ -98,7 +117,9 @@ def __init__(self): class StatusControlWidget(ipw.HTML): def __init__(self): print("AiiDA status") - print(subprocess.run(["verdi", "status"], capture_output=True, text=True).stdout) + print( + subprocess.run(["verdi", "status"], capture_output=True, text=True, check=False).stdout + ) super().__init__() From dea251eecd6be6f182208b9edf668ace33889b61 Mon Sep 17 00:00:00 2001 From: Aliaksandr Yakutovich Date: Fri, 21 Jun 2024 14:07:34 +0000 Subject: [PATCH 4/6] Fix pre-commit --- home/control.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/home/control.py b/home/control.py index 081f64e..cc4cfad 100644 --- a/home/control.py +++ b/home/control.py @@ -9,7 +9,7 @@ class DaemonControlWidget(ipw.VBox): - def __init__(self, *args, **kwargs): + def __init__(self): self._daemon = engine.daemon.get_daemon_client() self._status = ipw.Output() @@ -65,7 +65,10 @@ def _update_status(self, _=None): self._clear_status() with self._status: result = subprocess.run( - ["verdi", "daemon", "status"], capture_output=True, text=True, check=False + ["verdi", "daemon", "status"], + capture_output=True, + text=True, + check=False, ) print(result.stdout, result.stderr) @@ -118,7 +121,9 @@ class StatusControlWidget(ipw.HTML): def __init__(self): print("AiiDA status") print( - subprocess.run(["verdi", "status"], capture_output=True, text=True, check=False).stdout + subprocess.run( + ["verdi", "status"], capture_output=True, text=True, check=False + ).stdout ) super().__init__() @@ -136,4 +141,4 @@ 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) + super().__init__(children=[text, *children]) From ee45eaa649c6b6edcfc31044feb34a7579c13a6e Mon Sep 17 00:00:00 2001 From: Aliaksandr Yakutovich Date: Fri, 21 Jun 2024 14:38:10 +0000 Subject: [PATCH 5/6] Merge status page into daemon page --- control.ipynb | 3 +-- home/control.py | 22 ++++++++-------------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/control.ipynb b/control.ipynb index a5a58ad..a9d6cdc 100644 --- a/control.ipynb +++ b/control.ipynb @@ -19,7 +19,7 @@ "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" + "from home.control import DaemonControlWidget, ProcessControlWidget, GroupControlWidget, ProfileControlWidget" ] }, { @@ -33,7 +33,6 @@ " \"Daemon\": DaemonControlWidget,\n", " \"Group\": GroupControlWidget,\n", " \"Process\": ProcessControlWidget,\n", - " \"Status\": StatusControlWidget,\n", " \"Profile\": ProfileControlWidget,\n", "}\n", "\n", diff --git a/home/control.py b/home/control.py index cc4cfad..92ba663 100644 --- a/home/control.py +++ b/home/control.py @@ -64,13 +64,18 @@ def _stop_daemon(self, _=None): def _update_status(self, _=None): self._clear_status() with self._status: - result = subprocess.run( + result_status = subprocess.run( + ["verdi", "status"], capture_output=True, text=True, check=False + ) + print(result_status.stdout, result_status.stderr) + + result_daemon = subprocess.run( ["verdi", "daemon", "status"], capture_output=True, text=True, check=False, ) - print(result.stdout, result.stderr) + print(result_daemon.stdout, result_daemon.stderr) def _clear_status(self): with self._status: @@ -79,7 +84,7 @@ def _clear_status(self): class ProcessControlWidget(ipw.VBox): def __init__(self): - process_list = awb.ProcessListWidget(path_to_root="../../") + 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")) @@ -117,17 +122,6 @@ def __init__(self): super().__init__(children=[text]) -class StatusControlWidget(ipw.HTML): - def __init__(self): - print("AiiDA status") - print( - subprocess.run( - ["verdi", "status"], capture_output=True, text=True, check=False - ).stdout - ) - super().__init__() - - class Profile(ipw.HBox): def __init__(self, profile): self.profile = profile From cb5b3e917df84277f148f3ee51a36c4c62f93bfe Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 14:17:11 +0000 Subject: [PATCH 6/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- control.ipynb | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/control.ipynb b/control.ipynb index a9d6cdc..cd58cba 100644 --- a/control.ipynb +++ b/control.ipynb @@ -16,10 +16,16 @@ "outputs": [], "source": [ "import ipywidgets as ipw\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, ProfileControlWidget" + "from IPython.display import clear_output, display\n", + "\n", + "load_profile()\n", + "from home.control import (\n", + " DaemonControlWidget,\n", + " GroupControlWidget,\n", + " ProcessControlWidget,\n", + " ProfileControlWidget,\n", + ")" ] }, { @@ -40,18 +46,18 @@ " options=correspondance.keys(),\n", " value=None,\n", " orientation=\"vertical\",\n", - " layout=ipw.Layout(width='200px')\n", + " layout=ipw.Layout(width=\"200px\"),\n", ")\n", "\n", "\n", - "\n", "output = ipw.Output()\n", "\n", + "\n", "def update_output(value={\"new\": \"Group\"}):\n", - " if value['new'] in correspondance:\n", + " if value[\"new\"] in correspondance:\n", " with output:\n", " clear_output()\n", - " display(correspondance[value['new']]())\n", + " display(correspondance[value[\"new\"]]())\n", "\n", "\n", "toc.observe(update_output, names=\"value\")\n",