Skip to content

Commit

Permalink
Adapt with new metadata format
Browse files Browse the repository at this point in the history
  • Loading branch information
unkcpz committed Sep 22, 2023
1 parent 58ac7cd commit 3b5e21b
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 38 deletions.
54 changes: 22 additions & 32 deletions aiidalab_widgets_base/computational_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
from humanfriendly import InvalidSize, parse_size
from IPython.display import clear_output, display
from jinja2 import Environment, meta
from jinja2.nodes import Filter

from .databases import NewComputationalResourcesDatabaseWidget
from .utils import StatusHTML
Expand Down Expand Up @@ -594,9 +593,6 @@ def _handle_ssh_password(self):
if self._ssh_password.value == "":
self.ssh_connection_state = SshConnectionState.waiting_for_input
else:
# XXX: After I(unkcpz) move disable the hidden of the password box, user can
# input the password directly and start the password send session immediately.
# It will by-pass the waiting_for_input state and cause the error of "_ssh_connection_process" is not attribute of SshComputerSetup object.
self._send_password()

def _on_verification_mode_change(self, change):
Expand Down Expand Up @@ -1220,6 +1216,7 @@ def _observe_code_setup(self, _=None):
try:
getattr(self, key).label = value
except traitlets.TraitError:
# XXX: need to conform with template variable
self.message = f"Input plugin {value} is not installed."
elif key == "computer":
# check if the computer is set by load the label.
Expand Down Expand Up @@ -1351,7 +1348,7 @@ def __init__(self):
# the key is the variable name, and the value is a tuple of (template value and widget).
self._template_variables = {}
self._help_text = ipw.HTML(
"""<div>Please fill in the template variables below.</div>"""
"""<div>Please fill the template variables below.</div>"""
)
self._help_text.layout.display = "none"

Expand Down Expand Up @@ -1390,22 +1387,17 @@ def _templates_changed(self, _=None):
def _render(self):
"""Render the template variables widget."""
metadata = self.templates.get("metadata", {})
tooptip = metadata.get("tooltip", None)

if tooptip:
self._help_text.value = f"""<div>{tooptip}</div>"""

for line_key, line_str in self.templates.items():
env = Environment()
parsed_content = env.parse(line_str)

# vars is a set of variables in the template, while filters is a list of all filters in the template
# For example, {{ label | default('daint-mc') }} will have vars = {'label'} and filters = [<Filter: default('daint-mc')>]
# not all variables have filter.
# vars is a set of variables in the template
line_vars = meta.find_undeclared_variables(parsed_content)
filters = list(parsed_content.find_all(Filter))

default_value = {
fltr.node.name: fltr.args[0].value
for fltr in filters
if fltr.name == "default"
}

# Create a widget for each variable.
# The var is the name in a template string
Expand All @@ -1428,7 +1420,7 @@ def _render(self):
if widget_type == "text":
w = ipw.Text(
description=description,
value=default_value.get(var, ""),
value=var_meta.get("default", ""),
# delay notifying the observers until the user stops typing
continuous_update=False,
layout=LAYOUT,
Expand All @@ -1438,7 +1430,7 @@ def _render(self):
w = ipw.Dropdown(
description=description,
options=var_meta.get("options", ()),
value=default_value.get(var, None),
value=var_meta.get("default", None),
layout=LAYOUT,
style=STYLE,
)
Expand Down Expand Up @@ -1651,34 +1643,32 @@ def _on_quick_setup(self, _=None):
"""Go through all the setup steps automatically."""
# Use default values for the template variables if not set.
# and the same time check if all templates are filled.
# Becareful there are same key in both template_variables_computer and template_variables_code, e.g. label.
# Be careful there are same key in both template_variables_computer and template_variables_code, e.g. label.
# So can not combine them by {**a, **b}
for w_tmp in [self.template_variables_computer, self.template_variables_code]:
metadata = w_tmp.templates.get("metadata", {})
filled_templates = deepcopy(w_tmp.filled_templates)

for k, v in w_tmp.filled_templates.items():
env = Environment()
parsed_content = env.parse(v)
vs = meta.find_undeclared_variables(parsed_content)
filters = list(parsed_content.find_all(Filter))

# No variables in the template, all filled.
if len(vs) == 0:
continue

# We only has default filter for now, so when filter number is less than variable number, it means some variables are not filled.
if len(filters) < len(vs):
self.message = f"Please fill all the variables. Missing: {vs}"
return
else:
# Update filled template with default value.

default_value = {
fltr.node.name: fltr.args[0].value
for fltr in filters
if fltr.name == "default"
}
filled_templates[k] = env.from_string(v).render(**default_value)
default_values = {}
for var in vs:
# check if the default value is exist for this variable.
default = metadata.get(var, {}).get("default", None)
if default is None:
self.message = f"Please fill missing variable: {var}"
return
else:
default_values[var] = default

filled_templates[k] = env.from_string(v).render(**default_values)

# Update the filled template to trigger the trait change.
w_tmp.filled_templates = filled_templates
Expand Down
4 changes: 3 additions & 1 deletion aiidalab_widgets_base/databases.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,9 @@ class NewComputationalResourcesDatabaseWidget(ipw.VBox):
"""Extract the setup of a known computer from the AiiDA code registry."""

_default_database_source = (
"https://aiidateam.github.io/aiida-resource-registry/database.json"
# because of issue https://github.com/orgs/community/discussions/67961
"https://raw.githubusercontent.com/aiidateam/aiida-resource-registry/gh-pages/database.json"
# "https://aiidateam.github.io/aiida-resource-registry/database.json"
)

database_source = tl.Unicode(allow_none=True)
Expand Down
12 changes: 7 additions & 5 deletions tests/test_computational_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ def test_template_variables_widget():
w = computational_resources.TemplateVariablesWidget()

w.templates = {
"label": "{{ label | default('daint-mc') }}",
"label": "{{ label }}",
"hostname": "daint.cscs.ch",
"description": "Piz Daint supercomputer at CSCS Lugano, Switzerland, multicore partition.",
"transport": "core.ssh",
Expand All @@ -230,9 +230,10 @@ def test_template_variables_widget():
"shebang": "#!/bin/bash",
"mpirun_command": "srun -n {tot_num_mpiprocs}",
"mpiprocs_per_machine": 36,
"prepend_text": "#SBATCH --partition={{ slurm_partition | default('normal') }}\n#SBATCH --account={{ slurm_account }}\n#SBATCH --constraint=mc\n#SBATCH --cpus-per-task=1\n\nexport OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK\nsource $MODULESHOME/init/bash\nulimit -s unlimited",
"prepend_text": "#SBATCH --partition={{ slurm_partition }}\n#SBATCH --account={{ slurm_account }}\n#SBATCH --constraint=mc\n#SBATCH --cpus-per-task=1\n\nexport OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK\nsource $MODULESHOME/init/bash\nulimit -s unlimited",
"metadata": {
"slurm_partition": {
"type": "text",
"key_display": "Slurm partition",
},
},
Expand All @@ -253,7 +254,7 @@ def test_template_variables_widget():
sub_widget = value.widget
sub_widget.value = "normal-test"

# check the value can be re-input
# check the value can be changed after filled
# this test somehow has unexpected behavior, disable it for the moment.
# sub_widget.value = "another-test"

Expand All @@ -273,10 +274,11 @@ def test_template_variables_widget_metadata():
w = computational_resources.TemplateVariablesWidget()

w.templates = {
"prepend_text": "#SBATCH --partition={{ slurm_partition | default('normal') }}\n#SBATCH --account={{ slurm_account }}\n#SBATCH --constraint=mc\n#SBATCH --cpus-per-task=1\n\nexport OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK\nsource $MODULESHOME/init/bash\nulimit -s unlimited",
"prepend_text": "#SBATCH --partition={{ slurm_partition }}\n#SBATCH --account={{ slurm_account }}\n#SBATCH --constraint=mc\n#SBATCH --cpus-per-task=1\n\nexport OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK\nsource $MODULESHOME/init/bash\nulimit -s unlimited",
"metadata": {
"slurm_partition": {
"type": "list",
"default": "normal",
"options": ["normal", "normal-test", "debug"],
"key_display": "Slurm partition",
},
Expand Down Expand Up @@ -403,7 +405,7 @@ def test_quick_setup_widget():
# the message should be updated.
w._on_quick_setup()

assert "Please fill all the variables" in w.message
assert "Please fill missing variable" in w.message

# Fill in the computer name and trigger the setup button again, the message should be updated.
for (
Expand Down

0 comments on commit 3b5e21b

Please sign in to comment.