Skip to content

Commit

Permalink
Feature/post install plugins (#755)
Browse files Browse the repository at this point in the history
* Adding the post installation trigger when we install a plugin.
Putting also the post install information for the vibroscopy in the plugin.yaml file.

* Modification of the name of the post_install command for vibroscopy GUI.
Documentation will come in the next commit in order to help developers
to set the post installation for their plugins.

Also, updating of the plugin_list notebook, now the post installation step
title is also printed.

to test with the aiidalab-qe-vibroscopy plugin, you should modify the data dictionary
of the first block of the notebook like this:

data['aiidalab-qe-vibroscopy']['github'] = "https://github.com/mikibonacci/aiidalab-qe-vibroscopy@automatic_installation_codes"
data['aiidalab-qe-vibroscopy']['post_install'] = "setup-phonopy"

* Modifying the plugin_list notebook to take the local plugins.yaml file.
I think this is better, as the file can also contain specific plugin versions
which are compatible with the current local qeApp version (not with the remote main).

Also, due to this, I modified the plugin.yaml file to update the branch of the vibroscopy
plugin. (will change to the release version soon).

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Adding the documentation section on how to setup the post-install for a given plugin.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Updating dependencies: allowing installation of aiidalab-widgets-base[optimade]<2.4.0

* Updating the plugin_list notebook following the pre-commit suggestion.

* documentation on automatic post install plugins refined and ready.

* Changing the aiidalab-qe-vibroscopy installation from github to pip

* Removing the attempt of fetching plugins.yaml file from remote.
We should keep it local so we don't risk to load incompatible plugins (wrt the app version).

* Adding a space in post_install command in the plugin_list notebook.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
mikibonacci and pre-commit-ci[bot] authored Jul 8, 2024
1 parent e2d3d93 commit aea6022
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 22 deletions.
15 changes: 11 additions & 4 deletions docs/source/development/plugin_registry.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ To include your plugin in the registry, follow these steps:
author: "Alice Doe"
github: "https://github.com/alicedoe/aiidalab-qe-xyz"
documentation: "https://aiidalab-qe-xyz.readthedocs.io/"
pip: "aiidalab-qe-xyz"
pip: "aiidalab-qe-xyz==version-of-the-code"
post-install: "post-install-command"
3. Submit a Pull Request. Direct it to `this repository's Pull Requests section <https://github.com/aiidalab/aiidalab-qe/pulls>`_.

Expand All @@ -37,10 +38,16 @@ Plugin Entry Requirements

- **github:** If provided, this should be the URL to the plugin's GitHub homepage.

At least one of ``github`` or ``pip`` is required.
At least one of ``github`` or ``pip`` is required. ``pip`` installation will be preferred if both are provided, and "==version-of-the-code" can be omitted (but strongly suggested, to ensure compatiblity).

- **pip:** The PyPI package name for your plugin, useful for installation via pip. Example: ``aiida-quantum``.
- **documentation:** The URL to your plugin's online documentation, such as ReadTheDocs.
- **author:** The developer of the plugin.

By following these guidelines, you can ensure your plugin is correctly listed and accessible within the AiiDAlab Quantum ESPRESSO app, facilitating its discovery and use by the community.
- **post-install:** a post install Command Line Interface (CLI) command which should be defined inside your plugin if you needs it. For example in the ``aiidalab-qe-vibroscopy`` plugin, we automatically setup the phonopy code via this command. See below for more explanations.

How to define a post install command in your plugin
---------------------------------------------------------------------
If you need to run a post-install command, you can define it in the CLI of your package. The command should be designed to be run as ``package-name post-install-command``.
To define the CLI, you can use the ``__main__.py`` file in your source folder and the ``pyproject.toml`` file. You can refer to the `aiidalab-qe-vibroscopy <https://github.com/mikibonacci/aiidalab-qe-vibroscopy>`_ plugin for an example of how to do this.
In that plugin, the automatic setup for the phonopy code is implemented. It assumes that the ``phonopy`` binary is already present on the machine, as the plugin will install it as a dependency.
The post-install command will be triggered after the installation of the plugin (only) from the plugin list page of the Quantum ESPRESSO app.
42 changes: 26 additions & 16 deletions plugin_list.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,20 @@
"metadata": {},
"outputs": [],
"source": [
"import requests\n",
"import yaml\n",
"from pathlib import Path\n",
"\n",
"# URL of the YAML file\n",
"filepath = 'https://raw.githubusercontent.com/aiidalab/aiidalab-qe/main/plugins.yaml'\n",
"import yaml\n",
"\n",
"# Fetch the contents of the URL\n",
"response = requests.get(filepath)\n",
"# Get the current working directory\n",
"cwd = Path.cwd()\n",
"# Define a relative path\n",
"relative_path = 'plugins.yaml'\n",
"# Resolve the relative path to an absolute path\n",
"yaml_file = cwd / relative_path\n",
"\n",
"# Check if the request was successful\n",
"if response.status_code == 200:\n",
" # Load the YAML content\n",
" data = yaml.safe_load(response.content)\n",
" # Now 'data' contains the YAML file's contents as a Python object\n",
"else:\n",
" print(f\"Failed to fetch the YAML file: HTTP {response.status_code}\")"
"# Load the YAML content\n",
"with yaml_file.open('r') as file:\n",
" data = yaml.safe_load(file)"
]
},
{
Expand All @@ -54,7 +52,6 @@
"from IPython.display import display\n",
"\n",
"\n",
"\n",
"def is_package_installed(package_name):\n",
" import importlib\n",
" package_name = package_name.replace('-', '_')\n",
Expand Down Expand Up @@ -97,13 +94,19 @@
" return False\n",
"\n",
"\n",
"def install_package(package_name, pip, github, output_container, message_container, install_btn, remove_btn, accordion, index):\n",
"def install_package(package_name, pip, github, post_install, output_container, message_container, install_btn, remove_btn, accordion, index):\n",
" if pip:\n",
" command = [\"pip\", \"install\", pip, \"--user\"]\n",
" else:\n",
" command = [\"pip\", \"install\", \"git+\" + github, \"--user\"]\n",
" message_container.value = f\"\"\"<div style=\"color: #000000;\">Installing {package_name}...</div>\"\"\"\n",
" result = execute_command_with_output(command, output_container, install_btn, remove_btn)\n",
" # Execute post install if defined in the plugin.yaml:\n",
" if post_install: \n",
" message_container.value += \"\"\"<div style=\"color: #008000;\">Post installation step...</div>\"\"\"\n",
" command = [sys.executable, '-m', package_name.replace('-','_'), post_install]\n",
" # Execute the command\n",
" result = subprocess.run(command, capture_output=True, text=True)\n",
" # if the package was installed successfully\n",
" if result:\n",
" message_container.value += \"\"\"<div style=\"color: #008000;\">Initiating test to load the plugin...</div>\"\"\"\n",
Expand Down Expand Up @@ -183,7 +186,7 @@
" install_btn = ipw.Button(description=\"Install\", button_style='success', disabled=installed)\n",
" remove_btn = ipw.Button(description=\"Remove\", button_style='danger', disabled=not installed)\n",
"\n",
" install_btn.on_click(lambda btn, pn=plugin_name, pip=plugin_data.get('pip', None), github=plugin_data.get('github', ''), oc=output_container, mc=message_container, ib=install_btn, rb=remove_btn, ac=accordion, index=i: install_package(pn, pip, github, oc, mc, ib, rb, ac, index))\n",
" install_btn.on_click(lambda btn, pn=plugin_name, pip=plugin_data.get('pip', None), github=plugin_data.get('github', ''), post = plugin_data.get('post_install', None), oc=output_container, mc=message_container, ib=install_btn, rb=remove_btn, ac=accordion, index=i: install_package(pn, pip, github, post, oc, mc, ib, rb, ac, index))\n",
" remove_btn.on_click(lambda btn, pn=plugin_name, oc=output_container, mc=message_container, ib=install_btn, rb=remove_btn, ac=accordion, index=i: run_remove_button(pn, oc, mc, ib, rb, ac, index))\n",
"\n",
" box = ipw.VBox([\n",
Expand All @@ -200,6 +203,13 @@
"display(accordion)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
Expand Down
3 changes: 2 additions & 1 deletion plugins.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ aiida-bader:
aiidalab-qe-vibroscopy:
description: Plugin to compute vibrational properties of materials via the aiida-vibroscopy AiiDA plugin
author: Miki Bonacci, Andres Ortega Guerrero
github: https://github.com/mikibonacci/aiidalab-qe-vibroscopy
pip: aiidalab-qe-vibroscopy==1.0.1
post_install: setup-phonopy

aiidalab-qe-muon:
description: Plugin to compute muon stopping sites and related properties via the aiida-muon and aiida-musconv AiiDA plugins
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ install_requires =
aiida-core~=2.2,<3
Jinja2~=3.0
aiida-quantumespresso~=4.6
aiidalab-widgets-base[optimade]~=2.2.0
aiidalab-widgets-base[optimade]~=2.2.0,<2.4.0
aiida-pseudo~=1.4
filelock~=3.8
importlib-resources~=5.2
Expand Down

0 comments on commit aea6022

Please sign in to comment.