Skip to content

mineproductivity.plugins

Auto-generated API reference for the Plugins package, rendered from the package's own docstrings. For the narrative overview, dependency rules, and extension guide, see Packages -> Plugins.

plugins

mineproductivity.plugins -- the plugin lifecycle layer built on registry: manifests, version-gated activation, inter-plugin dependency ordering, and graceful failure isolation.

Implements docs/architecture/03_Registry_Framework_Design_Specification.md exactly. plugins depends on core and registry -- see README.md for the full set of architectural rules this package must satisfy.

Everything documented here is part of the public API and can be imported directly from mineproductivity.plugins, e.g.::

from mineproductivity.plugins import PluginManifest, PluginLifecycle

PluginActivationError

PluginActivationError(message, *, details=None)

Bases: MineProductivityError

PluginLifecycle.activate() failed for a reason other than version incompatibility (e.g. the entry-point's target module raised on import).

PluginDependencyError

PluginDependencyError(message, *, details=None)

Bases: PluginActivationError

A declared :class:~mineproductivity.plugins.manifest.PluginDependency could not be satisfied.

PluginLifecycle

Bases: ABC

Orchestrates a :class:PluginManifest through :class:PluginState, delegating the actual entry-point scanning to :class:~mineproductivity.registry.EntryPointDiscovery (via :class:~mineproductivity.plugins.loader.PluginLoader) and adding: inter-plugin dependency resolution, activation ordering, and graceful failure isolation (one bad plugin must not prevent others from loading).

activate abstractmethod

activate(manifest)

Move manifest from Discovered to Active (or Failed, in isolation from every other plugin's activation).

deactivate abstractmethod

deactivate(plugin_name)

Move an active plugin to Deactivated.

state_of abstractmethod

state_of(plugin_name)

Return the current :class:PluginState of plugin_name.

Raises:

Type Description
NotFoundError

If plugin_name has never been passed to :meth:activate.

PluginState

Bases: Enum

The five states a plugin passes through, per design spec §11.

PluginLoader

PluginLoader(*, discovery=None)

Loads every :class:~mineproductivity.registry.EntryPointSpec a :class:PluginManifest declares in provides, delegating each to :class:~mineproductivity.registry.EntryPointDiscovery -- the mechanism :class:~mineproductivity.plugins.lifecycle.PluginLifecycle implementations use to complete the Validated -> Active transition (design spec §15).

Import-time failure within any one entry-point is already isolated by :class:~mineproductivity.registry.EntryPointDiscovery itself (that entry-point is simply absent from its result); this class additionally treats a systemic failure of one provides group's scan (e.g. corrupted package metadata) as fatal to loading the whole manifest, since a manifest that cannot even be scanned has provided nothing.

load

load(manifest)

Discover every EntryPointSpec in manifest.provides.

Returns:

Type Description
Result[Mapping[str, Sequence[str]]]

Result.ok mapping each provided entry-point group to the entry-point names that loaded successfully within it, or the first Result.err encountered while scanning a group.

PluginDependency dataclass

PluginDependency(plugin_name, version_range)

Bases: BaseValueObject

One other plugin, by name, that a plugin requires to already be active before it can itself activate.

PluginManifest dataclass

PluginManifest(plugin_name, plugin_version, core_version_range, provides, *, depends_on=())

Bases: BaseValueObject

The declared identity of one installed plugin package -- richer than a single entry-point, since one plugin package can register into multiple registries (e.g. a site pack registering both KPIs and equipment types).

Examples:

>>> manifest = PluginManifest(
...     plugin_name="haulmetrics",
...     plugin_version="1.0.0",
...     core_version_range=VersionRange(min_version="0.5.0", max_version_exclusive="1.0.0"),
...     provides=(EntryPointSpec(group="mineproductivity.kpis", target_registry="kpis"),),
... )
>>> manifest.plugin_name
'haulmetrics'

resolve_activation_order

resolve_activation_order(manifests)

Order manifests so that every plugin appears after every plugin it declares a :class:~mineproductivity.plugins.manifest.PluginDependency on (a topological sort, via Kahn's algorithm).

Returns:

Type Description
Result[Sequence[PluginManifest]]

Result.ok with the dependency-respecting order, or Result.err(PluginDependencyError) if a declared dependency names a plugin not present in manifests, or if the dependency graph contains a cycle.