Skip to content

Commit

Permalink
Merge branch 'master' into unpin-ase
Browse files Browse the repository at this point in the history
  • Loading branch information
yakutovicha authored Feb 5, 2025
2 parents 3f3ed75 + 0b1651b commit 2bab940
Show file tree
Hide file tree
Showing 24 changed files with 479 additions and 259 deletions.
16 changes: 8 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:

env:
FORCE_COLOR: "1"
UV_VERSION: "0.4.6"
UV_VERSION: "0.5.28"

# https://docs.github.com/en/actions/using-jobs/using-concurrency
concurrency:
Expand All @@ -27,10 +27,10 @@ jobs:
matrix:
browser: [Chrome, Firefox]
# test on the latest and the oldest supported version
aiida-core-version: [2.1.2, 2.6.2]
aiida-core-version: [2.1.2, 2.6.3]
fail-fast: false

runs-on: ubuntu-latest
runs-on: ubuntu-22.04
timeout-minutes: 30

steps:
Expand All @@ -44,7 +44,7 @@ jobs:
python-version: '3.10'

- name: Setup uv
uses: astral-sh/setup-uv@v1
uses: astral-sh/setup-uv@v5
with:
version: ${{ env.UV_VERSION }}

Expand Down Expand Up @@ -90,10 +90,10 @@ jobs:
matrix:
python-version: ['3.9', '3.11']
# Test on the latest and oldest supported version
aiida-core-version: [2.2.2, 2.6.2]
aiida-core-version: [2.2.2, 2.6.3]
fail-fast: false

runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 30
services:
rabbitmq:
Expand All @@ -114,7 +114,7 @@ jobs:
python-version: ${{ matrix.python-version }}

- name: Setup uv
uses: astral-sh/setup-uv@v1
uses: astral-sh/setup-uv@v5
with:
version: ${{ env.UV_VERSION }}

Expand All @@ -131,7 +131,7 @@ jobs:
run: pytest -v tests --cov=aiidalab_widgets_base

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
uses: codecov/codecov-action@v5
with:
flags: python-${{ matrix.python-version }}
token: ${{ secrets.CODECOV_TOKEN }}
6 changes: 3 additions & 3 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
build:

name: Build package
runs-on: ubuntu-latest
runs-on: ubuntu-24.04

steps:

Expand Down Expand Up @@ -52,7 +52,7 @@ jobs:
if: github.repository_owner == 'aiidalab'

needs: [build]
runs-on: ubuntu-latest
runs-on: ubuntu-24.04

environment:
name: Test PyPI
Expand All @@ -79,7 +79,7 @@ jobs:
if: startsWith(github.ref, 'refs/tags/v') && github.repository_owner == 'aiidalab'

needs: [build, publish-test]
runs-on: ubuntu-latest
runs-on: ubuntu-24.04

environment:
name: PyPI
Expand Down
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ ci:

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
rev: v5.0.0
hooks:
- id: check-json
- id: check-yaml
Expand All @@ -13,7 +13,7 @@ repos:
exclude: miscellaneous/structures

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.5.0
rev: v0.9.1
hooks:
- id: ruff-format
exclude: ^docs/.*
Expand All @@ -27,11 +27,11 @@ repos:
args: [--preserve-quotes]

- repo: https://github.com/sirosen/check-jsonschema
rev: 0.28.6
rev: 0.31.0
hooks:
- id: check-github-workflows

- repo: https://github.com/kynan/nbstripout
rev: 0.7.1
rev: 0.8.1
hooks:
- id: nbstripout
21 changes: 14 additions & 7 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,17 @@ build:
os: ubuntu-22.04
tools:
python: '3.11'
commands:
- asdf plugin add uv
- asdf install uv 0.1.44
- asdf global uv 0.1.44
- uv venv
- uv pip install .[docs]
- .venv/bin/python -m sphinx -W --keep-going -d _build/doctrees -D language=en -b html docs/source $READTHEDOCS_OUTPUT/html
jobs:
pre_create_environment:
- asdf plugin add uv
- asdf install uv 0.5.17
- asdf global uv 0.5.17
create_environment:
- uv venv $READTHEDOCS_VIRTUALENV_PATH
install:
- uv pip install .[docs] --no-cache --prefix $READTHEDOCS_VIRTUALENV_PATH

sphinx:
builder: html
fail_on_warning: true
configuration: docs/source/conf.py
8 changes: 4 additions & 4 deletions aiidalab_widgets_base/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,13 @@ def is_running_in_jupyter():

__all__ = [
"AiidaNodeViewWidget",
"BasicStructureEditor",
"BasicCellEditor",
"BasicStructureEditor",
"CodQueryWidget",
"CodeDatabaseWidget",
"CodeDropdown",
"CodQueryWidget",
"ComputerDatabaseWidget",
"ComputationalResourcesWidget",
"ComputerDatabaseWidget",
"ComputerDropdownWidget",
"ElnConfigureWidget",
"ElnExportWidget",
Expand Down Expand Up @@ -129,4 +129,4 @@ def is_running_in_jupyter():
"viewer",
]

__version__ = "2.3.0a2"
__version__ = "2.3.0a3"
88 changes: 61 additions & 27 deletions aiidalab_widgets_base/computational_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ def __init__(
enable_detailed_setup=True,
clear_after=None,
default_calc_job_plugin=None,
include_setup_widget=True,
fetch_codes=True,
**kwargs,
):
"""Dropdown for Codes for one input plugin.
Expand All @@ -73,7 +75,7 @@ def __init__(
self.setup_message = StatusHTML(clear_after=clear_after)
self.code_select_dropdown = ipw.Dropdown(
description=description,
disabled=True,
disabled=fetch_codes, # disable if handled internally, enable otherwise
value=None,
style={"description_width": "initial"},
)
Expand All @@ -95,33 +97,45 @@ def __init__(
self.refresh, names=["allow_disabled_computers", "allow_hidden_codes"]
)

self.btn_setup_new_code = ipw.ToggleButton(description="Setup new code")
self.btn_setup_new_code.observe(self._setup_new_code, "value")
self._default_user_email = orm.User.collection.get_default().email

self._setup_new_code_output = ipw.Output(layout={"width": self._output_width})
selection_row = ipw.HBox(
children=[
self.code_select_dropdown,
]
)

self._default_user_email = orm.User.collection.get_default().email
children = [selection_row]

children = [
ipw.HBox([self.code_select_dropdown, self.btn_setup_new_code]),
self._setup_new_code_output,
self.output,
]
super().__init__(children=children, **kwargs)
if include_setup_widget:
self.btn_setup_new_code = ipw.ToggleButton(description="Setup new code")
self.btn_setup_new_code.observe(self._setup_new_code, "value")

# Computer/code setup
self.resource_setup = _ResourceSetupBaseWidget(
default_calc_job_plugin=self.default_calc_job_plugin,
enable_quick_setup=enable_quick_setup,
enable_detailed_setup=enable_detailed_setup,
)
self.resource_setup.observe(self.refresh, "success")
tl.dlink(
(self.resource_setup, "message"),
(self.setup_message, "message"),
)
selection_row.children += (self.btn_setup_new_code,)

self.refresh()
self._setup_new_code_output = ipw.Output(
layout={"width": self._output_width}
)
children.append(self._setup_new_code_output)

# Computer/code setup
self.resource_setup = ResourceSetupBaseWidget(
default_calc_job_plugin=self.default_calc_job_plugin,
enable_quick_setup=enable_quick_setup,
enable_detailed_setup=enable_detailed_setup,
)
self.resource_setup.observe(self.refresh, "success")
tl.dlink(
(self.resource_setup, "message"),
(self.setup_message, "message"),
)

children.append(self.output)

super().__init__(children=children, **kwargs)

if fetch_codes:
self.refresh()

def _get_codes(self):
"""Query the list of available codes."""
Expand Down Expand Up @@ -1179,6 +1193,13 @@ def on_setup_code(self, _=None):
with self.setup_code_out:
clear_output()

if not self.label.value:
self.message = wrap_message(
"Please provide a code label.",
MessageLevel.WARNING,
)
return False

if not self.computer.value:
self.message = wrap_message(
"Please select an existing computer.",
Expand Down Expand Up @@ -1215,7 +1236,7 @@ def on_setup_code(self, _=None):
qb = orm.QueryBuilder()
qb.append(orm.Computer, filters={"uuid": computer.uuid}, tag="computer")
qb.append(
orm.AbstractCode,
orm.Code,
with_computer="computer",
filters={"label": kwargs["label"]},
)
Expand Down Expand Up @@ -1576,7 +1597,7 @@ def fill(self):
# if the widget is not filled, use the original template var string e.g. {{ var }}
inp_dict = {}
for _var in line.vars:
if self._template_variables[_var].widget.value == "":
if self._template_variables[_var].widget.value in ("", None):
variable_key = self._template_variables[_var].widget.description
self.unfilled_variables.append(variable_key.strip(":"))
inp_dict[_var] = "{{ " + _var + " }}"
Expand All @@ -1598,7 +1619,7 @@ def _on_template_variable_filled(self, _):
self.fill()


class _ResourceSetupBaseWidget(ipw.VBox):
class ResourceSetupBaseWidget(ipw.VBox):
"""The widget that allows to setup a computer and code.
This is the building block of the `ComputationalResourcesDatabaseWidget` which
will be directly used by the user.
Expand Down Expand Up @@ -1645,6 +1666,11 @@ def __init__(
default_calc_job_plugin=default_calc_job_plugin,
show_reset_button=False,
)
ipw.dlink(
(self.comp_resources_database, "configured"),
(self.quick_setup_button, "disabled"),
lambda configured: not configured,
)

# All templates
self.template_computer_setup = TemplateVariablesWidget()
Expand Down Expand Up @@ -1863,14 +1889,22 @@ def _on_quick_setup(self, _=None):
)
return

# Raise error if the code is not selected.
if not self.comp_resources_database.code_selector.value:
self.message = wrap_message(
"Please select a code from the database.",
MessageLevel.ERROR,
)
return

# Check if all the template variables are filled.
# If not raise a warning and return (skip the setup).
if (
unfilled_variables := self.template_computer_setup.unfilled_variables
+ self.template_computer_configure.unfilled_variables
+ self.template_code.unfilled_variables
):
var_warn_message = ", ".join([f"<b>{v}</b>" for v in unfilled_variables])
var_warn_message = ", ".join({f"<b>{v}</b>" for v in unfilled_variables})
self.message = wrap_message(
f"Please fill the template variables: {var_warn_message}",
MessageLevel.WARNING,
Expand Down
10 changes: 10 additions & 0 deletions aiidalab_widgets_base/databases.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ class ComputationalResourcesDatabaseWidget(ipw.VBox):
computer_configure = tl.Dict()
code_setup = tl.Dict()

configured = tl.Bool(False)

STYLE = {"description_width": "180px"}
LAYOUT = {"width": "400px"}

Expand Down Expand Up @@ -413,6 +415,8 @@ def _computer_changed(self, change=None):
self.computer_setup = computer_setup
self.computer_configure = computer_configure

self._set_configured()

def _code_changed(self, change=None):
"""Update code settings."""
if change["new"] is None:
Expand All @@ -430,3 +434,9 @@ def _code_changed(self, change=None):
.get("codes", {})
.get(selected_code, {})
)

self._set_configured()

def _set_configured(self):
"""Update state of the widget."""
self.configured = all((self.computer_setup, self.code_setup))
2 changes: 2 additions & 0 deletions aiidalab_widgets_base/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,8 @@ def _walk_tree(cls, root):
def _update_tree_node(self, tree_node):
if isinstance(tree_node, AiidaProcessNodeTreeNode):
process_node = orm.load_node(tree_node.pk)
if process_node.process_state is None:
return
tree_node.name = calc_info(process_node)
# Override the process state in case that the process node has failed:
# (This could be refactored with structural pattern matching with py>=3.10.)
Expand Down
6 changes: 6 additions & 0 deletions aiidalab_widgets_base/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import inspect
import os
import sys
import threading
import time
import traceback
Expand Down Expand Up @@ -731,6 +732,8 @@ def __init__(self, callbacks=None, on_sealed=None, timeout=None, **kwargs):
self._monitor_thread_stop = threading.Event()
self._monitor_thread_lock = threading.Lock()

self.log_widget: ipw.Output | None = kwargs.pop("log_widget", None)

super().__init__(**kwargs)

@tl.observe("value")
Expand Down Expand Up @@ -773,6 +776,9 @@ def _run(funcs):
else:
func()
except Exception:
if self.log_widget:
with self.log_widget:
traceback.print_exc(file=sys.stdout)
warnings.warn(
f"WARNING: The callback function {func.__name__!r} was disabled due to an error:\n{traceback.format_exc()}",
stacklevel=2,
Expand Down
Loading

0 comments on commit 2bab940

Please sign in to comment.