Draft: Resolve "Load plugins from installed bec_plugins automatically"
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)