Skip to content

Commit

Permalink
Fix code setup. (#255)
Browse files Browse the repository at this point in the history
* Make sure to not set up code if the computer is not provided.
* Gracefully handle situations when the requested code plugin
is not installed.
* `AiiDACodeSetup`: allow input_plugin trait to be None.

Co-authored-by: Carl Simon Adorf <simon.adorf@epfl.ch>
  • Loading branch information
yakutovicha and csadorf committed Oct 14, 2021
1 parent e6a951f commit a6b3a75
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 33 deletions.
54 changes: 39 additions & 15 deletions aiidalab_widgets_base/codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from subprocess import check_output

import ipywidgets as ipw
from aiida.orm import Code, Computer, QueryBuilder, User
from aiida.orm import Code, QueryBuilder, User
from aiida.plugins.entry_point import get_entry_point_names
from IPython.display import clear_output
from traitlets import Bool, Dict, Instance, Unicode, Union, dlink, link, validate
Expand Down Expand Up @@ -157,9 +157,8 @@ class AiiDACodeSetup(ipw.VBox):
"""Class that allows to setup AiiDA code"""

label = Unicode()
computer = Union([Unicode(), Instance(Computer)], allow_none=True)

input_plugin = Unicode()
computer = Unicode(allow_none=True)
input_plugin = Unicode(allow_none=True)
description = Unicode()
remote_abs_path = Unicode()
prepend_text = Unicode()
Expand All @@ -178,20 +177,19 @@ def __init__(self, path_to_root="../", **kwargs):
link((inp_label, "value"), (self, "label"))

# Computer on which the code is installed. Two dlinks are needed to make sure we get a Computer instance.
inp_computer = ComputerDropdown(
self.inp_computer = ComputerDropdown(
path_to_root=path_to_root, layout={"margin": "0px 0px 0px 125px"}
)
dlink((inp_computer, "selected_computer"), (self, "computer"))
dlink((self, "computer"), (inp_computer, "selected_computer"))
dlink((self, "computer"), (self.inp_computer, "selected_computer"))

# Code plugin.
inp_code_plugin = ipw.Dropdown(
self.inp_code_plugin = ipw.Dropdown(
options=sorted(get_entry_point_names("aiida.calculations")),
description="Code plugin:",
layout=ipw.Layout(width="500px"),
style=style,
)
link((inp_code_plugin, "value"), (self, "input_plugin"))
link((self.inp_code_plugin, "value"), (self, "input_plugin"))

# Code description.
inp_description = ipw.Text(
Expand Down Expand Up @@ -233,8 +231,8 @@ def __init__(self, path_to_root="../", **kwargs):
ipw.VBox(
[
inp_label,
inp_computer,
inp_code_plugin,
self.inp_computer,
self.inp_code_plugin,
inp_description,
inp_abs_path,
]
Expand All @@ -247,6 +245,11 @@ def __init__(self, path_to_root="../", **kwargs):
]
super(AiiDACodeSetup, self).__init__(children, **kwargs)

@validate("input_plugin")
def _validate_input_plugin(self, proposal):
plugin = proposal["value"]
return plugin if plugin in self.inp_code_plugin.options else None

def _setup_code(self, _=None):
"""Setup an AiiDA code."""
with self._setup_code_out:
Expand All @@ -257,26 +260,47 @@ def _setup_code(self, _=None):
if not self.remote_abs_path:
print("You did not specify absolute path to the executable.")
return
if not self.inp_computer.selected_computer:
print(
"Please specify a computer that is configured in your AiiDA profile."
)
return False
if not self.input_plugin:
print(
"Please specify an input plugin that is installed in your AiiDA environment."
)
return False
if self.exists():
print(f"Code {self.label}@{self.computer.label} already exists.")
print(
f"Code {self.label}@{self.inp_computer.selected_computer.label} already exists."
)
return
code = Code(remote_computer_exec=(self.computer, self.remote_abs_path))
code = Code(
remote_computer_exec=(
self.inp_computer.selected_computer,
self.remote_abs_path,
)
)
code.label = self.label
code.description = self.description
code.set_input_plugin_name(self.input_plugin)
code.set_prepend_text(self.prepend_text)
code.set_append_text(self.append_text)
code.store()
code.reveal()
full_string = f"{self.label}@{self.computer.label}"
full_string = f"{self.label}@{self.inp_computer.selected_computer.label}"
print(check_output(["verdi", "code", "show", full_string]).decode("utf-8"))

def exists(self):
"""Returns True if the code exists, returns False otherwise."""
from aiida.common import MultipleObjectsError, NotExistent

if not self.label:
return False
try:
Code.get_from_string(f"{self.label}@{self.computer.label}")
Code.get_from_string(
f"{self.label}@{self.inp_computer.selected_computer.label}"
)
return True
except MultipleObjectsError:
return True
Expand Down
9 changes: 5 additions & 4 deletions aiidalab_widgets_base/computers.py
Original file line number Diff line number Diff line change
Expand Up @@ -908,12 +908,13 @@ def _validate_selected_computer(self, change):
if isinstance(computer, str):
if computer in self.computers:
return self.computers[computer]
self.output.value = f"""No computer named '<span style="color:red">{computer}</span>'
was found in your AiiDA database."""
self.output.value = f"""Computer instance '<span style="color:red">{computer}</span>'
is not configured in your AiiDA profile."""
return None

if isinstance(computer, Computer):
if computer.label in self.computers:
return computer
self.output.value = f"""The computer instance '<span style="color:red">{computer}</span>'
supplied was not found in your AiiDA database."""
self.output.value = f"""Computer instance '<span style="color:red">{computer.label}</span>'
is not configured in your AiiDA profile."""
return None
36 changes: 22 additions & 14 deletions notebooks/setup_code.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,27 @@
"from aiidalab_widgets_base import AiiDACodeSetup, CodeDatabaseWidget"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"parsed_url = urlparse.parse_qs(urlparse.urlsplit(jupyter_notebook_url).query)\n",
"args = {}\n",
"for key, value in parsed_url.items():\n",
" args[key] = '\\n'.join(value) if isinstance(value,(tuple,list)) else value"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"aiidacode = AiiDACodeSetup(path_to_root=\"../../\", **args)"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down Expand Up @@ -53,19 +74,6 @@
"metadata": {},
"outputs": [],
"source": [
"parsed_url = urlparse.parse_qs(urlparse.urlsplit(jupyter_notebook_url).query)\n",
"args = {}\n",
"for key, value in parsed_url.items():\n",
" args[key] = '\\n'.join(value) if isinstance(value,(tuple,list)) else value"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"aiidacode = AiiDACodeSetup(path_to_root=\"../../\", **args)\n",
"display(aiidacode)"
]
}
Expand All @@ -86,7 +94,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
"version": "3.7.9"
}
},
"nbformat": 4,
Expand Down

0 comments on commit a6b3a75

Please sign in to comment.