Registry / devops / stevedore

stevedore

JSON →
library5.9.1pypypi✓ verified 25d ago

Stevedore is a Python library designed to simplify the management of dynamic plugins for Python applications. It builds on top of `setuptools` entry points, providing a standardized and less repetitive way to discover and load extensions at runtime. The library abstracts away much of the boilerplate associated with `__import__` or `importlib` for plugin systems. [2, 5]

pip install stevedore
INSTALL
IMPORT
SIG · STEVEDORE
S
stevedore
devopspythonv5.9.1
Install
1.6s avg
Import
119ms
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v5.8.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.128s · 18.2MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.6s · import 0.110s · 19MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

DriverManager
from stevedore.driver import DriverManager
Used for managing a single named plugin.
ExtensionManager
from stevedore.extension import ExtensionManager
Used for managing multiple extensions within a namespace.
NamedExtensionManager
from stevedore.named import NamedExtensionManager
Manages a specific set of named extensions from a namespace.
EnabledExtensionManager
from stevedore.enabled import EnabledExtensionManager
Manages extensions based on an 'enabled' filter.

This quickstart demonstrates how to define a plugin interface and a concrete plugin, then use `stevedore.ExtensionManager` to discover and load it. It simulates `setuptools` entry point registration for a self-contained, runnable example. In a real application, plugins would be installed as separate packages declaring their entry points in `setup.py` or `pyproject.toml`. [1, 3, 5]

import os from setuptools import setup, find_packages from stevedore import extension # 1. Define a plugin interface (e.g., in myapp/plugins/base.py) # In a real scenario, this would be in a separate package. # For this quickstart, we'll simulate it. plugin_base_code = ''' import abc class FormatterBase(abc.ABC): @abc.abstractmethod def format(self, data): """Format the data and return a string.""" pass ''' # 2. Implement a concrete plugin (e.g., in myapp_simple_formatter/formatter.py) # In a real scenario, this would be in a separate package. plugin_impl_code = ''' from myapp.plugins.base import FormatterBase class SimpleFormatter(FormatterBase): def format(self, data): return f"Simple format: {data['value']}" ''' # Create dummy files for demonstration if not os.path.exists('myapp/plugins'): os.makedirs('myapp/plugins') with open('myapp/plugins/base.py', 'w') as f: f.write(plugin_base_code) if not os.path.exists('myapp_simple_formatter'): os.makedirs('myapp_simple_formatter') with open('myapp_simple_formatter/formatter.py', 'w') as f: f.write(plugin_impl_code) with open('myapp/__init__.py', 'w') as f: pass with open('myapp_simple_formatter/__init__.py', 'w') as f: pass # 3. Define entry points in setup.py (or pyproject.toml) # For a runnable quickstart, we'll use a dummy setup for the plugin # and then manually register it to simulate installation. # In a real project, myapp_simple_formatter would have its own setup.py # and be installed via pip install -e . # Simulate plugin registration by creating a pseudo-entry-point # This is for quickstart demonstration; usually setuptools handles this via installation. # This specific 'hack' for dynamic registration during runtime is not standard Stevedore usage, # but it makes the quickstart runnable without a full package installation process. # We'll use a hack to make the quickstart self-contained and runnable. # In a real scenario, 'myapp_simple_formatter' would be an installed package # with its entry point declared in its setup.py (or pyproject.toml). # To simulate: we directly add the module to sys.modules and define a mock entry_points function. import sys sys.path.insert(0, os.path.abspath('.')) # Temporarily import the base and plugin to make them available from myapp.plugins.base import FormatterBase from myapp_simple_formatter.formatter import SimpleFormatter # Mock the entry point discovery for demonstration def mock_entry_points(group=None): if group == 'myapp.formatters': class MockEntryPoint: def __init__(self, name, load_callable): self.name = name self._load_callable = load_callable def load(self): return self._load_callable return { 'simple': MockEntryPoint('simple', SimpleFormatter) } return {} # Replace the real entry_points discovery for this script's scope # This is a highly simplified mock for quickstart purposes and not how stevedore usually discovers plugins # In practice, entry points are discovered via 'importlib.metadata.entry_points()' after package installation. import stevedore.extension stevedore.extension.entry_points = mock_entry_points # 4. Use stevedore in your application to load plugins def main(): print("Loading formatters...") mgr = extension.ExtensionManager( namespace='myapp.formatters', invoke_on_load=True ) if not mgr.extensions: print("No formatters found. Ensure plugin packages are installed and define 'myapp.formatters' entry points.") return print(f"Found {len(mgr.extensions)} formatter(s).") for ext in mgr.extensions: print(f" - {ext.name}: {ext.obj.format({'value': 123})}") if __name__ == '__main__': main() # Clean up dummy files/dirs import shutil shutil.rmtree('myapp') shutil.rmtree('myapp_simple_formatter')
Debug
Known issues
gotchaBe aware that another tool also named 'Stevedore' exists for Docker image building and container orchestration. Ensure you are using the correct Python plugin management library, often identified by its OpenStack origin. [1, 7, 8, 10, 12]
fix
Always import classes from `stevedore.extension`, `stevedore.driver`, etc., and verify documentation from `docs.openstack.org/stevedore` or PyPI.
affects: All
gotchaIncorrectly defining entry points in `setup.py` or `pyproject.toml`, or referencing non-existent callables for your plugins, can lead to `ImportError` at runtime that is difficult to debug at packaging time. [15]
fix
Thoroughly test your plugin packages after installation. Ensure the entry point string ('module.path:callable_name') precisely matches the module and the callable object within it. Use `entry_point_inspector` for debugging.
affects: All
gotchaWhile powerful, using a large number of `setuptools` entry points (and thus `stevedore` plugins) can potentially contribute to slower application startup times due to the discovery and loading process. [9]
fix
For performance-critical applications with many plugins, consider lazy loading mechanisms or optimizing plugin discovery if startup time becomes an issue. Profile your application to identify bottlenecks.
affects: All
gotchaStevedore's namespaces, while resembling Python package paths (e.g., `a.b.c`), do not directly correspond to Python package structures. They are logical identifiers for groups of plugins. [8]
fix
Choose descriptive and unique namespaces for your plugin groups. Understand that a plugin in namespace `foo.bar` can reside in any Python package that declares an entry point for that namespace, not necessarily a package named `foo.bar`.
affects: All
deprecatedSupport for older Python versions (e.g., Python 3.8 and earlier) has been dropped in recent Stevedore releases. [6]
fix
Ensure your project is running on a supported Python version (>= 3.10 as of 5.7.0). Consult the `stevedore` changelog for specific version compatibility details. [2]
affects: < 5.4.0
breakingThe Stevedore library, especially when defining plugins via entry points, fundamentally relies on `setuptools`. If `setuptools` is not installed in the environment, the library (or tools expecting its entry points) may fail with a `ModuleNotFoundError` for `setuptools` itself.
fix
Ensure `setuptools` is installed in your Python environment. For example, include it in your `requirements.txt` or `pyproject.toml` dependencies, or install it directly via `pip install setuptools`.
affects: All
Errors
Common errors & fixes
No entry points found for group 'my_plugin_group'
The `entry_points` in the plugin's `setup.py` or `pyproject.toml` do not define any entry points under the specified group name, or the plugin package is not installed in the environment.
fix
Ensure the plugin package's `setup.py` (or `pyproject.toml`) correctly defines `entry_points` under the specified group and that the plugin package is installed (e.g., `pip install -e .` for development or `pip install my-plugin-package`).
ModuleNotFoundError: No module named 'my_plugin_package.plugins'
The `entry_points` definition in the plugin's `setup.py` or `pyproject.toml` refers to a module path or class name that does not exist or is misspelled within the plugin package.
fix
Verify that the module path and class name specified in the `entry_points` definition (e.g., in `setup.py` or `pyproject.toml`) are correct and that the corresponding Python file and class exist within the plugin package.
TypeError: __init__() missing 1 required positional argument: 'config_object'
When `ExtensionManager` is initialized with `invoke_on_load=True`, it attempts to instantiate plugin classes, but the provided `invoke_args` or `invoke_kwargs` do not match the plugin's `__init__` method signature.
fix
Pass the required arguments to the plugin's constructor via `invoke_args` or `invoke_kwargs` when initializing `ExtensionManager` (e.g., `manager = ExtensionManager('group', invoke_on_load=True, invoke_kwargs={'config_object': my_config})`).
Upgrade
Version history
5.9.1latest on PyPI · released Aug 20, 2026
Audit
Dependencies
setuptoolsrequiredStevedore relies on setuptools entry points for plugin discovery and loading.
Agent activity
12 hits · last 30 days
node
10
Resources