Code indexing in gitaly is broken and leads to code not being visible to the user. We work on the issue with highest priority.

Skip to content
Snippets Groups Projects

Draft: Resolve "Load plugins from installed bec_plugins automatically"

Closed guijar_m requested to merge 193-load-plugins-from-installed-bec_plugins-automatically into main

Description

DRAFT FOR DISCUSSION

This MR demonstrates a possible way to have BEC plugins following the Python plugins documentation.

It is based on !526 (merged) , because like this I could also propose --help showing the different options added by the plugin easily.

I think plugins should be independent "projects", adding the right entry point in their pyproject.toml (in fact, like pytest or other projects like flask are doing...). So, to demonstrate a project like this the "csaxs" plugin is added to bec/bec_plugins/csaxs ; of course it is just an example. In real life it can be another gitlab repository, the plugin code should have nothing to do with BEC source code.

There are 2 "mount points" for the plugin:

  • extend_command_line_args(parser): called from the application (BEC client), with the parser object -> it can be completed by the plugin user to add command line arguments
  • setup(parser): called from the application, once it is initialized -> should add things in BEC or alter prompt, whatever

Complete code of the "csaxs" plugin (file bec/bec_plugins/csaxs/bec_csaxs_plugin.py):

def extend_command_line_args(parser):
    parser.add_argument("--session", help="Session name", type=str, default="my_default_session")

def setup(parser):
    args = parser.parse_args()

    if args.session == "my_session":
        print("Loading my_session session")
    else:
        print("Loading default session")

    # SETUP PROMPTS
    bec._ip.prompts.username = args.session
    bec._ip.prompts.status = 1

And corresponding pyproject.toml:

[project]
name = "csaxs_plugin"
version = "0.1"
dependencies = [
    "bec-lib",
    "bec-client"
]

[project.entry-points.'bec.plugins']
csaxs = 'bec_csaxs_plugin'

So the plugin is called csaxs, it will be found under bec.plugins by importlib and the plugin code is bec_csaxs_plugin.py.

It is enough to do pip install . in the plugin source directory to add the plugin to BEC.

Once done, we can have BEC client loading plugins:

parser = argparse.ArgumentParser(
    prog="BEC IPython client", description="BEC command line interface"
)
parser.add_argument("--version", action="store_true", default=False)
parser.add_argument("--nogui", action="store_true", default=False)
parser.add_argument("--config", action="store", default=None)

### NEW CODE
# look for plugins, complete parser with extra args
from importlib.metadata import entry_points
discovered_plugins = entry_points(group='bec.plugins')
plugin_modules = []
for plugin in discovered_plugins:
    print(f"Loading BEC plugin: {plugin.name}")
    plugin_module = plugin.load()
    plugin_modules.append(plugin_module)
    plugin_module.extend_command_line_args(parser)
### END OF NEW CODE

args, left_args = parser.parse_known_args()

The code above extends the arguments parser:

(bec) [matias@kashyyyk bec]$ bec --help
Loading BEC plugin: csaxs
usage: BEC IPython client [-h] [--version] [--nogui] [--config CONFIG] [--session SESSION]

BEC command line interface

options:
  -h, --help         show this help message and exit
  --version
  --nogui
  --config CONFIG
  --session SESSION  Session name     <<<<<<<<<<<<<<< SEE ADDED ENTRY

And it is easy to call .setup() on the plugin(s) to have them initalized:

# go through plugins and initialize those
for plugin in plugin_modules:
    plugin.setup(parser)

try:
    app.start()
finally: 
    bec.shutdown()

Result:

(bec) [matias@kashyyyk bec]$ bec --session bla
Loading BEC plugin: csaxs  <<<<<<<<<<<<<<<<<<<< plugin is loaded
Python 3.11.7 | packaged by conda-forge | (main, Dec 23 2023, 14:43:09) [GCC 12.3.0]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.22.2 -- An enhanced Interactive Python. Type '?' for help.
2024-04-03 16:34:55 | [INFO] | Waiting for ScanServer.
2024-04-03 16:34:55 | [SUCCESS] | ScanServer is running.
2024-04-03 16:34:55 | [INFO] | Waiting for ScanBundler.
2024-04-03 16:34:55 | [SUCCESS] | ScanBundler is running.
2024-04-03 16:34:55 | [INFO] | Waiting for DeviceServer.
2024-04-03 16:34:55 | [SUCCESS] | DeviceServer is running.
2024-04-03 16:34:55 | [INFO] | Waiting for SciHub.
2024-04-03 16:34:55 | [SUCCESS] | SciHub is running.
2024-04-03 16:34:55 | [SUCCESS] | All BEC services are running.
Loading default session

• my_default_session [1/2] ❯❯ 
^^^^^^^^^^^^^^^^^^^^^^
prompt is changed

Closes #193 (closed)

Merge request reports

Loading
Loading

Activity

Filter activity
  • Approvals
  • Assignees & reviewers
  • Comments (from bots)
  • Comments (from users)
  • Commits & branches
  • Edits
  • Labels
  • Lock status
  • Mentions
  • Merge request status
  • Tracking
Please register or sign in to reply
Loading