From 14e89e9a5761967e27ac0356881fd00b16009a13 Mon Sep 17 00:00:00 2001 From: Aliaksandr Yakutovich Date: Thu, 21 Nov 2024 16:07:53 +0000 Subject: [PATCH 1/5] Update setup.cfg --- setup.cfg | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup.cfg b/setup.cfg index 80b2ec9db..873e5e4b3 100644 --- a/setup.cfg +++ b/setup.cfg @@ -28,8 +28,7 @@ install_requires = humanfriendly~=10.0 ipytree~=0.2 traitlets~=5.4 - ipywidgets~=7.7 - widgetsnbextension<3.6.3 + ipywidgets>=7,<9 pymysql~=0.9 nglview~=3.0 spglib>=1.14,<3 From 76fbd22c466d11051fed7f3963c7aa0dbf50bec5 Mon Sep 17 00:00:00 2001 From: Aliaksandr Yakutovich Date: Fri, 22 Nov 2024 09:55:40 +0000 Subject: [PATCH 2/5] Migrate `FileUpload` widgets. --- .../computational_resources.py | 30 +++++++++++++------ aiidalab_widgets_base/structures.py | 18 ++++++++--- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/aiidalab_widgets_base/computational_resources.py b/aiidalab_widgets_base/computational_resources.py index 7adde22dd..44ef30861 100644 --- a/aiidalab_widgets_base/computational_resources.py +++ b/aiidalab_widgets_base/computational_resources.py @@ -483,12 +483,16 @@ def _on_setup_ssh_button_pressed(self, _=None): self.message = wrap_message(message, MessageLevel.ERROR) return - filename = Path(private_key_fname).name - - # if the private key filename is exist, generate random string and append to filename subfix + # if the private key filename exists, generate random string and append to filename subfix # then override current name. - if filename in [str(p.name) for p in Path(self._ssh_folder).iterdir()]: - private_key_fpath = self._ssh_folder / f"{filename}-{shortuuid.uuid()}" + if private_key_fname in [ + str(p.name) for p in Path(self._ssh_folder).iterdir() + ]: + private_key_fpath = ( + self._ssh_folder / f"{private_key_fname}-{shortuuid.uuid()}" + ) + else: + private_key_fpath = self._ssh_folder / private_key_fname self._add_private_key(private_key_fpath, private_key_content) @@ -615,10 +619,18 @@ def _on_verification_mode_change(self, change): def _private_key(self) -> tuple[str | None, bytes | None]: """Unwrap private key file and setting filename and file content.""" if self._inp_private_key.value: - (fname, _value), *_ = self._inp_private_key.value.items() - content = copy.copy(_value["content"]) - self._inp_private_key.value.clear() - self._inp_private_key._counter = 0 # pylint: disable=protected-access + try: + (fname, value), *_ = ( + (fname, item["content"]) + for fname, item in self._inp_private_key.value.items() + ) # ipywidgets 7.x + value = value["content"] + except AttributeError: + (fname, value), *_ = ( + (f["name"], f.content.tobytes()) + for f in self._inp_private_key.value + ) # ipywidgets 8.x + content = copy.copy(value) return fname, content return None, None diff --git a/aiidalab_widgets_base/structures.py b/aiidalab_widgets_base/structures.py index 3a3cbf925..a58ed71a2 100644 --- a/aiidalab_widgets_base/structures.py +++ b/aiidalab_widgets_base/structures.py @@ -412,10 +412,20 @@ def _validate_and_fix_ase_cell(self, ase_structure, vacuum_ang=10.0): def _on_file_upload(self, change=None): """When file upload button is pressed.""" - for fname, item in change["new"].items(): - self.structure = self._read_structure(fname, item["content"]) - self.file_upload.value.clear() - break + + def get_unified_representation(value): + """This function ensures backwards compatibility w.r.t. ipywidgets 7.x""" + try: + return [ + (fname, item["content"]) for fname, item in value.items() + ] # ipywidgets 7.x + except AttributeError: + return [ + (f["name"], f.content.tobytes()) for f in value + ] # ipywidgets 8.x + + fname, item = get_unified_representation(change["new"])[0] + self.structure = self._read_structure(fname, item) def _read_structure(self, fname, content): suffix = "".join(pathlib.Path(fname).suffixes) From c6b254765f9cfe4faec0a31750d05ec4d1acbc74 Mon Sep 17 00:00:00 2001 From: Aliaksandr Yakutovich Date: Fri, 22 Nov 2024 10:18:25 +0000 Subject: [PATCH 3/5] Bump ipyoptimade to ~1.1 --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 873e5e4b3..c6eb49a84 100644 --- a/setup.cfg +++ b/setup.cfg @@ -50,7 +50,7 @@ dev = pytest-timeout~=2.3.0 selenium~=4.23.0 optimade = - ipyoptimade~=0.1 + ipyoptimade~=1.1 eln = aiidalab-eln>=0.1.2,~=0.1 requests-cache~=1.0 From 6ec7d496bfafb8248abaff3b3ad7fb605a42d009 Mon Sep 17 00:00:00 2001 From: Aliaksandr Yakutovich Date: Fri, 22 Nov 2024 13:24:37 +0000 Subject: [PATCH 4/5] Fix WizardAppWidget --- aiidalab_widgets_base/wizard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aiidalab_widgets_base/wizard.py b/aiidalab_widgets_base/wizard.py index 0c633683d..cd4e68e6a 100644 --- a/aiidalab_widgets_base/wizard.py +++ b/aiidalab_widgets_base/wizard.py @@ -102,7 +102,6 @@ def __init__(self, steps, show_header=True, **kwargs): # Initialize the accordion with the widgets ... self.accordion = ipw.Accordion(children=widgets) self._update_titles() - ipw.link((self.accordion, "selected_index"), (self, "selected_index")) # Watch for changes to each step's state for widget in widgets: @@ -148,6 +147,7 @@ def __init__(self, steps, show_header=True, **kwargs): self.show_header = show_header super().__init__(children=[self.header, self.accordion], **kwargs) + ipw.link((self.accordion, "selected_index"), (self, "selected_index")) @property def show_header(self): From 4a708f0f8783e0fdaaf75a67a60ff67a8232a62a Mon Sep 17 00:00:00 2001 From: Aliaksandr Yakutovich Date: Fri, 22 Nov 2024 13:39:03 +0000 Subject: [PATCH 5/5] Test: fix ipyoptimade==1.0.0 --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index c6eb49a84..deb61bc8f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -50,7 +50,7 @@ dev = pytest-timeout~=2.3.0 selenium~=4.23.0 optimade = - ipyoptimade~=1.1 + ipyoptimade==1.0.0 eln = aiidalab-eln>=0.1.2,~=0.1 requests-cache~=1.0