Plugins service¶
consortium.server.services.plugins_service
¶
PluginsService(release_service, paths_service)
¶
get_plugin_from_directory(directory, ignore_enabled_flag=False)
¶
Instantiates a plugin from a root directory without registering it.
Disabled plugins (as indicated by enabled: false in their manifest.json)
are not instantiated unless ignore_enabled_flag is True.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
directory
|
Path
|
Path to the directory containing the plugin
project files and |
required |
ignore_enabled_flag
|
bool
|
When |
False
|
Returns:
| Type | Description |
|---|---|
BasePlugin | None
|
The instantiated plugin, or |
BasePlugin | None
|
enabled check is not overridden. |
Raises:
| Type | Description |
|---|---|
PluginManifestFileNotFoundError
|
If |
InvalidPluginManifestFileJSONError
|
If |
InvalidPluginManifestFileSchemaError
|
If |
InvalidPluginPyProjectFileTOMLError
|
If |
InvalidPluginPyProjectFileDependencyError
|
If |
ThirdPartyDependencyNotFoundError
|
If a third-party dependency
declared in |
IncompatibleThirdPartyDependencyVersionError
|
If a third-party
dependency declared in |
PluginEntryPointModuleNotFoundError
|
If the entry-point module cannot be found. |
PluginSymbolNotFoundError
|
If the symbol specified in the manifest is not found. |
PluginInterfaceError
|
If the class does not inherit from the expected base class. |
IncompatiblePluginFrameworkVersionError
|
If the plugin is incompatible with the current framework version. |
InternalPluginError
|
If an unhandled exception occurs while loading the plugin. |
get_all_plugins_from_directory(directory, ignore_enabled_flag=False)
¶
Recursively scans a directory for plugin root directories and instantiates them.
Disabled plugins (as indicated by enabled: false in their manifest.json)
are skipped unless ignore_enabled_flag is True. Plugins that fail to
load are collected in the returned error list rather than aborting the scan.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
directory
|
Path
|
The directory to scan for plugin root directories. |
required |
ignore_enabled_flag
|
bool
|
When |
False
|
Returns:
| Type | Description |
|---|---|
list[BasePlugin]
|
A three-element tuple: (1) a list of successfully instantiated plugins, (2) |
list[Path]
|
a list of paths skipped because the plugin was disabled, and (3) a list of |
list[tuple[Path, PluginLoadingError]]
|
|
Raises:
| Type | Description |
|---|---|
PluginDiscoveryFileSystemError
|
If the recursive filesystem scan of
|
register_plugin(plugin)
¶
Registers an already-instantiated plugin with the service.
Each plugin is uniquely identified by its plugin_id. Registration validates
that the plugin's ID and label are unique and that all of its declared component
dependencies are satisfied. Registering a plugin does not start it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plugin
|
BasePlugin
|
The plugin instance to register. |
required |
Raises:
| Type | Description |
|---|---|
PluginAlreadyRegisteredError
|
If a plugin with the same ID is already registered. |
DuplicatePluginLabelError
|
If a plugin with the same label is already registered. |
ComponentDependencyNotFoundError
|
If the plugin declares a dependency on another component that is not registered. |
IncompatibleComponentDependencyVersionError
|
If the plugin declares a dependency on a registered component whose version does not satisfy the required specifier. |
register_plugin_from_directory(directory, ignore_enabled_flag=False)
¶
Instantiates and registers a plugin from a root directory.
Disabled plugins are skipped unless ignore_enabled_flag is True.
This method registers the plugin but does not start it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
directory
|
Path
|
Path to the directory containing the plugin project
files and |
required |
ignore_enabled_flag
|
bool
|
When |
False
|
Returns:
| Type | Description |
|---|---|
BasePlugin | None
|
The registered plugin, or |
BasePlugin | None
|
check is not overridden. |
Raises:
| Type | Description |
|---|---|
PluginManifestFileNotFoundError
|
If |
InvalidPluginManifestFileJSONError
|
If |
InvalidPluginManifestFileSchemaError
|
If |
InvalidPluginPyProjectFileTOMLError
|
If |
InvalidPluginPyProjectFileDependencyError
|
If |
ThirdPartyDependencyNotFoundError
|
If a third-party dependency
declared in |
IncompatibleThirdPartyDependencyVersionError
|
If a third-party
dependency declared in |
PluginEntryPointModuleNotFoundError
|
If the entry-point module cannot be found. |
PluginSymbolNotFoundError
|
If the symbol specified in the manifest is not found. |
PluginInterfaceError
|
If the class does not inherit from the expected base class. |
IncompatiblePluginFrameworkVersionError
|
If the plugin is incompatible with the current framework version. |
InternalPluginError
|
If an unhandled exception occurs while loading the plugin. |
PluginAlreadyRegisteredError
|
If a plugin with the same ID is already registered. |
DuplicatePluginLabelError
|
If a plugin with the same label is already registered. |
ComponentDependencyNotFoundError
|
If the plugin declares a dependency on another component that is not registered. |
IncompatibleComponentDependencyVersionError
|
If the plugin declares a dependency on a registered component whose version does not satisfy the required specifier. |
load_plugin_from_directory(directory, ignore_enabled_flag=False, timeout=5)
async
¶
Loads a plugin from a root directory, registering it and starting it if it autostarts.
Disabled plugins are skipped unless ignore_enabled_flag is True.
After registration, the plugin is started when its autostart attribute is
True.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
directory
|
Path
|
Path to the directory containing the plugin project
files and |
required |
ignore_enabled_flag
|
bool
|
When |
False
|
timeout
|
int | None
|
The maximum number of seconds to wait for the plugin to start when
it autostarts. When |
5
|
Returns:
| Type | Description |
|---|---|
BasePlugin | None
|
The loaded plugin, or |
BasePlugin | None
|
check is not overridden. |
Raises:
| Type | Description |
|---|---|
PluginManifestFileNotFoundError
|
If |
InvalidPluginManifestFileJSONError
|
If |
InvalidPluginManifestFileSchemaError
|
If |
InvalidPluginPyProjectFileTOMLError
|
If |
InvalidPluginPyProjectFileDependencyError
|
If |
ThirdPartyDependencyNotFoundError
|
If a third-party dependency
declared in |
IncompatibleThirdPartyDependencyVersionError
|
If a third-party
dependency declared in |
PluginEntryPointModuleNotFoundError
|
If the entry-point module cannot be found. |
PluginSymbolNotFoundError
|
If the symbol specified in the manifest is not found. |
PluginInterfaceError
|
If the class does not inherit from the expected base class. |
IncompatiblePluginFrameworkVersionError
|
If the plugin is incompatible with the current framework version. |
InternalPluginError
|
If an unhandled exception occurs while loading the plugin. |
PluginAlreadyRegisteredError
|
If a plugin with the same ID is already registered. |
PluginStartError
|
If the plugin autostarts but fails to start. |
PluginFatalError
|
If the plugin autostarts and an unhandled exception escapes
its |
unload_plugin_by_plugin_id(plugin_id, timeout=5, force_unload=False)
async
¶
Stops (if running) and deregisters a loaded plugin by its ID.
A running plugin is stopped before it is removed from the registry. A plugin
that does not stop within timeout is either forcibly cancelled (when
force_unload is True) or causes the unload to fail (when force_unload is
False).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plugin_id
|
str | UUID
|
The ID of the plugin to unload. |
required |
timeout
|
int | None
|
The maximum number of seconds to wait for the plugin to stop. When
|
5
|
force_unload
|
bool
|
When |
False
|
Raises:
| Type | Description |
|---|---|
PluginNotFoundError
|
If no plugin with the given ID is registered. |
PluginStopError
|
If the plugin fails to stop and |
PluginStopTimeoutError
|
If the plugin does not stop within |
PluginFatalError
|
If an unhandled exception escapes the plugin's |
reload_plugin_by_plugin_id(plugin_id, ignore_enabled_flag=False, load_timeout=5, unload_timeout=5, force_unload=False)
async
¶
Unloads a plugin then reloads it from its original root directory.
The plugin is stopped and deregistered, then loaded again from the root
directory it was originally loaded from, starting it again if it autostarts. If the
plugin is disabled after reload and ignore_enabled_flag is False, the
plugin will only be unloaded, not reloaded.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plugin_id
|
str | UUID
|
The ID of the plugin to reload. |
required |
ignore_enabled_flag
|
bool
|
When |
False
|
load_timeout
|
int | None
|
The maximum number of seconds to wait for the plugin to start
when it autostarts on reload. When |
5
|
unload_timeout
|
int | None
|
The maximum number of seconds to wait for the plugin to stop
during unload. When |
5
|
force_unload
|
bool
|
When |
False
|
Returns:
| Type | Description |
|---|---|
BasePlugin | None
|
The reloaded plugin, or |
BasePlugin | None
|
check is not overridden. |
Raises:
| Type | Description |
|---|---|
PluginNotFoundError
|
If no plugin with the given ID is registered. |
PluginStopError
|
If the plugin fails to stop during unload and
|
PluginStopTimeoutError
|
If the plugin does not stop within |
PluginManifestFileNotFoundError
|
If |
InvalidPluginManifestFileJSONError
|
If |
InvalidPluginManifestFileSchemaError
|
If |
InvalidPluginPyProjectFileTOMLError
|
If |
InvalidPluginPyProjectFileDependencyError
|
If |
ThirdPartyDependencyNotFoundError
|
If a third-party dependency
declared in |
IncompatibleThirdPartyDependencyVersionError
|
If a third-party
dependency declared in |
PluginEntryPointModuleNotFoundError
|
If the entry-point module cannot be found. |
PluginSymbolNotFoundError
|
If the symbol specified in the manifest is not found. |
PluginInterfaceError
|
If the class does not inherit from the expected base class. |
IncompatiblePluginFrameworkVersionError
|
If the plugin is incompatible with the current framework version. |
InternalPluginError
|
If an unhandled exception occurs while loading the plugin. |
PluginAlreadyRegisteredError
|
If a plugin with the same ID is already registered when it is reloaded. |
PluginStartError
|
If the reloaded plugin autostarts but fails to start. |
PluginFatalError
|
If an unhandled exception escapes the plugin's |
load_framework_plugins(ignore_enabled_flag=False)
async
¶
Discovers and loads all plugins from the framework's plugins directory.
Every plugin root directory under the framework plugins directory is discovered,
resolved into a dependency-respecting load order, then registered and (when the
plugin has autostart set) started. Disabled plugins are skipped unless
ignore_enabled_flag is set. Discovery errors, unresolved dependencies,
circular dependencies, and per-plugin load failures are logged rather than
raised so that a single bad plugin does not abort loading the rest.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ignore_enabled_flag
|
bool
|
When |
False
|
Raises:
| Type | Description |
|---|---|
PluginDiscoveryFileSystemError
|
If the initial recursive scan of the framework plugins directory fails at the filesystem level. This happens before any individual plugin is loaded, so unlike per-plugin load failures it is not logged and swallowed, it propagates to the caller. |
unload_framework_plugins(force_unload=False, timeout=5)
async
¶
Unloads every loaded plugin that lives under the framework plugins directory.
Each matching plugin is unloaded concurrently. Failures to unload individual plugins are logged rather than raised so that one failing plugin does not prevent the others from being unloaded.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
force_unload
|
bool
|
When |
False
|
timeout
|
None | int
|
The number of seconds to wait for each plugin to stop before its
unload is considered to have timed out. When |
5
|
reload_framework_plugins(force_reload=False, timeout=5, ignore_enabled_flag=False)
async
¶
Unloads all currently loaded plugins and reloads them from disk.
Every currently loaded plugin is unloaded concurrently, then the framework plugins directory is rescanned and any plugin that is not already loaded (for example one that failed to unload) is loaded again. Per-plugin unload and load failures are logged rather than raised so that one failing plugin does not prevent the others from being reloaded.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
force_reload
|
bool
|
When |
False
|
timeout
|
None | int
|
The number of seconds to wait for each plugin to stop before its
unload is considered to have timed out. When |
5
|
ignore_enabled_flag
|
bool
|
When |
False
|
Raises:
| Type | Description |
|---|---|
PluginDiscoveryFileSystemError
|
If the recursive scan of the framework plugins directory (used to find plugins that are not already loaded, for example one that failed to unload) fails at the filesystem level. This happens after plugins are unloaded but before any are loaded again, so unlike per-plugin unload and load failures it is not logged and swallowed, it propagates to the caller. |
start_plugin_by_plugin_id(plugin_id, blocking=False)
async
¶
Starts a loaded plugin by its ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plugin_id
|
str | UUID
|
The ID of the plugin to start. |
required |
blocking
|
bool
|
When |
False
|
Raises:
| Type | Description |
|---|---|
PluginNotFoundError
|
If no plugin with the given ID is registered. |
PluginAlreadyRunningError
|
If the plugin is already running. |
PluginStartError
|
If the plugin fails to start. |
PluginFatalError
|
If an unhandled exception escapes the plugin's |
stop_plugin_by_plugin_id(plugin_id, blocking=False)
async
¶
Stops a loaded plugin by its ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plugin_id
|
str | UUID
|
The ID of the plugin to stop. |
required |
blocking
|
bool
|
When |
False
|
Raises:
| Type | Description |
|---|---|
PluginNotFoundError
|
If no plugin with the given ID is registered. |
PluginNotRunningError
|
If the plugin is not running. |
PluginStopError
|
If the plugin fails to stop. |
PluginFatalError
|
If an unhandled exception escapes the plugin's |
restart_plugin_by_plugin_id(plugin_id, blocking=False)
async
¶
Restarts a loaded plugin by its ID, stopping it and then starting it again.
When blocking is False, the stop-then-start sequence runs in a background
task, so any error raised while stopping or starting the plugin is not
propagated to the caller.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plugin_id
|
str | UUID
|
The ID of the plugin to restart. |
required |
blocking
|
bool
|
When |
False
|
Raises:
| Type | Description |
|---|---|
PluginNotFoundError
|
If no plugin with the given ID is registered. |
PluginNotRunningError
|
If |
PluginStopError
|
If |
PluginAlreadyRunningError
|
If |
PluginStartError
|
If |
PluginFatalError
|
If |
cancel_plugin_by_plugin_id(plugin_id, blocking=False)
async
¶
Cancels a loaded plugin by its ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plugin_id
|
str | UUID
|
The ID of the plugin to cancel. |
required |
blocking
|
bool
|
When |
False
|
Raises:
| Type | Description |
|---|---|
PluginNotFoundError
|
If no plugin with the given ID is registered. |
PluginNotRunningError
|
If the plugin is not running. |
PluginFatalError
|
If an unhandled exception escapes the plugin's
|
get_plugin_by_plugin_id(plugin_id)
¶
Returns a loaded plugin by its ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plugin_id
|
str | UUID
|
The ID of the plugin to retrieve. |
required |
Returns:
| Type | Description |
|---|---|
BasePlugin
|
The requested plugin. |
Raises:
| Type | Description |
|---|---|
PluginNotFoundError
|
If no plugin with the given ID is registered. |
get_plugins_by_label(label)
¶
Returns all loaded plugins with the given label.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label to filter by. |
required |
Returns:
| Type | Description |
|---|---|
list[BasePlugin]
|
All loaded plugins whose label matches. Empty if none match. |
get_all_plugins()
¶
Returns a list of all plugins loaded in the service.
Returns:
| Type | Description |
|---|---|
list[BasePlugin]
|
A list of all plugins loaded in the service. |