Skip to content

Commit

Permalink
Merge pull request #73 from aiidalab/release_1.0.0b4
Browse files Browse the repository at this point in the history
Release 1.0.0b4
  • Loading branch information
yakutovicha authored Apr 17, 2020
2 parents e9b11c5 + 1c85da9 commit c4b78e3
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 33 deletions.
2 changes: 1 addition & 1 deletion aiidalab_widgets_base/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
from .structures_multi import MultiStructureUploadWidget # noqa
from .viewers import viewer # noqa

__version__ = "1.0.0b3"
__version__ = "1.0.0b4"
40 changes: 26 additions & 14 deletions aiidalab_widgets_base/computers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import pexpect
import ipywidgets as ipw
from IPython.display import clear_output
from traitlets import Dict, Instance, Int, Unicode, Union, validate, link
from traitlets import Bool, Dict, Instance, Int, Unicode, Union, link, observe, validate

from aiida.common import NotExistent
from aiida.orm import Computer, QueryBuilder, User
Expand Down Expand Up @@ -667,14 +667,21 @@ class ComputerDropdown(ipw.VBox):

selected_computer = Union([Unicode(), Instance(Computer)], allow_none=True)
computers = Dict(allow_none=True)
allow_select_disabled = Bool(False)

def __init__(self, text='Select computer:', path_to_root='../', **kwargs):
"""Dropdown for configured AiiDA Computers.
:param text: Text to display before dropdown
:type text: str"""
text (str): Text to display before dropdown.
path_to_root (str): Path to the app's root folder.
"""

self.output = ipw.Output()

if 'allow_select_disabled' in kwargs:
self.allow_select_disabled = kwargs['allow_select_disabled']

self._dropdown = ipw.Dropdown(options={},
value=None,
description=text,
Expand All @@ -683,26 +690,31 @@ def __init__(self, text='Select computer:', path_to_root='../', **kwargs):
link((self, 'computers'), (self._dropdown, 'options'))
link((self._dropdown, 'value'), (self, 'selected_computer'))

self._btn_refresh = ipw.Button(description="Refresh", layout=ipw.Layout(width="70px"))
btn_refresh = ipw.Button(description="Refresh", layout=ipw.Layout(width="70px"))
btn_refresh.on_click(self.refresh)

self._setup_another = ipw.HTML(
value="""<a href={path_to_root}aiidalab-widgets-base/setup_computer.ipynb target="_blank">
Setup new computer</a>""".format(path_to_root=path_to_root))
self._btn_refresh.on_click(self._refresh)

children = [ipw.HBox([self._dropdown, self._btn_refresh, self._setup_another]), self.output]
self._refresh()
children = [ipw.HBox([self._dropdown, btn_refresh, self._setup_another]), self.output]
self.refresh()
super().__init__(children=children, **kwargs)

@staticmethod
def _get_computers():
def _get_computers(self):
"""Get the list of available computers."""
query_b = QueryBuilder()
query_b.append(Computer, tag='computer')

# Only computers configured for the current user.
return {c[0].name: c[0] for c in query_b.all() if c[0].is_user_configured(User.objects.get_default())}
# Getting the current user.
user = User.objects.get_default()

return {
c[0].name: c[0]
for c in QueryBuilder().append(Computer).all()
if c[0].is_user_configured(user) and (self.allow_select_disabled or c[0].is_user_enabled(user))
}

def _refresh(self, _=None):
@observe('allow_select_disabled')
def refresh(self, _=None):
"""Refresh the list of configured computers."""

with self.output:
Expand Down
74 changes: 58 additions & 16 deletions aiidalab_widgets_base/process.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
"""Widgets to work with processes."""

import os
from inspect import isclass
from ipywidgets import Button, HTML, IntProgress, Layout, Textarea, VBox
from traitlets import Instance

# AiiDA imports
from aiida.engine import submit
from aiida.engine import submit, Process
from aiida.orm import CalcJobNode, ProcessNode, WorkChainNode


Expand All @@ -29,45 +31,83 @@ def get_running_calcs(process):

class SubmitButtonWidget(VBox):
"""Submit button class that creates submit button jupyter widget."""
process = Instance(ProcessNode, allow_none=True)

def __init__(self, process, input_dictionary_function, description="Submit"):
"""Submit Button
:process: work chain to run
:param_funtion: the function that generates input parameters dictionary
def __init__(self,
process_class,
input_dictionary_function,
description="Submit",
disable_after_submit=True,
append_output=False):
"""Submit Button widget.
process_class (Process): Process class to submit.
input_dictionary_function (func): Function that generates input parameters dictionary.
description (str): Description written on the submission button.
disable_after_submit (bool): Whether to disable the button after the process was submitted.
append_output (bool): Whether to clear widget output for each subsequent submission.
"""

self.process = None
self._process_class = process
self._run_after_submitted = []
if isclass(process_class) and issubclass(process_class, Process):
self._process_class = process_class
else:
raise ValueError("process_class argument must be a sublcass of {}, got {}".format(Process, process_class))

if callable(input_dictionary_function):
self.input_dictionary_function = input_dictionary_function
else:
raise ValueError(
"input_dictionary_function argument must be a function that returns input dictionary, got {}".format(
input_dictionary_function))

self.disable_after_submit = disable_after_submit
self.append_output = append_output

self.input_dictionary_function = input_dictionary_function
self.btn_submit = Button(description=description, disabled=False)
self.btn_submit.on_click(self.on_btn_submit_press)
self.submit_out = HTML('')
children = [
self.btn_submit,
self.submit_out,
]

self._run_after_submitted = []

super(SubmitButtonWidget, self).__init__(children=children)

def on_click(self, function):
self.btn_submit.on_click(function)

def on_btn_submit_press(self, _=None):
"""When submit button is pressed."""
self.submit_out.value = ''

if not self.append_output:
self.submit_out.value = ''

input_dict = self.input_dictionary_function()
if input_dict is None:
self.submit_out.value = "SubmitButtonWidget: did not recieve input dictionary."
if self.append_output:
self.submit_out.value += "SubmitButtonWidget: did not recieve input dictionary.<br>"
else:
self.submit_out.value = "SubmitButtonWidget: did not recieve input dictionary."
else:
self.btn_submit.disabled = True
self.btn_submit.disabled = self.disable_after_submit
self.process = submit(self._process_class, **input_dict)
self.submit_out.value = "Submitted process {}".format(self.process)

if self.append_output:
self.submit_out.value += "Submitted process {}<br>".format(self.process)
else:
self.submit_out.value = "Submitted process {}".format(self.process)

for func in self._run_after_submitted:
func(self.process)

def on_submitted(self, function):
"""Run functions after a process has been submitted sucesfully."""
"""Run functions after a process has been submitted successfully."""
self._run_after_submitted.append(function)


Expand Down Expand Up @@ -100,6 +140,10 @@ def _follow(self):
sleep(self.update_interval)
self.update() # update the state for the last time to be 100% sure

# Call functions to be run after the process is completed.
for func in self._run_after_completed:
func(self.process)

def follow(self, detach=False):
"""Follow the process in blocking or non-blocking manner."""
if detach:
Expand All @@ -108,8 +152,6 @@ def follow(self, detach=False):
update_state.start()
else:
self._follow()
for func in self._run_after_completed:
func(self.process)

def on_completed(self, function):
"""Run functions after a process has been completed."""
Expand Down
2 changes: 1 addition & 1 deletion codes_computers.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"outputs": [],
"source": [
"# Select from existing computers.\n",
"computer_dropdown = ComputerDropdown()\n",
"computer_dropdown = ComputerDropdown(allow_select_disabled=False)\n",
"display(computer_dropdown)"
]
}
Expand Down
2 changes: 1 addition & 1 deletion setup.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "1.0.0b3",
"version": "1.0.0b4",
"name": "aiidalab-widgets-base",
"author_email": "aiidalab@materialscloud.org",
"url": "https://github.com/aiidalab/aiidalab-widgets-base",
Expand Down

0 comments on commit c4b78e3

Please sign in to comment.