Pluginlib
Pluginlib is a framework for creating, managing, and importing plugins within Python applications. It provides utilities for dynamically discovering and loading classes that inherit from a specified base plugin class, often found via filesystem paths or entry points. The current version is 0.10.0, with releases occurring periodically to add features, improve compatibility, and address issues.
Warnings
- breaking Pluginlib dropped support for Python 2.6 and older Python 3 versions.
- gotcha When loading plugins from namespace packages, pluginlib explicitly states that these packages are NOT searched recursively for imports. This means sub-modules within a namespace package won't be automatically discovered.
- breaking The return type of `PluginLoader.plugins_all()` at its lowest level changed from a regular dictionary to an `OrderedDict`. Code relying on `dict` iteration order or direct indexing might be affected.
- gotcha If an abstract method in a base `Plugin` class is defined as a coroutine (async), any overriding method in a child plugin class must also be defined as a coroutine.
Install
-
pip install pluginlib
Imports
- Plugin
from pluginlib import Plugin
- PluginLoader
from pluginlib import PluginLoader
Quickstart
import os
import tempfile
import shutil
from pluginlib import Plugin, PluginLoader
# --- Setup: Create a temporary directory and a dummy plugin file ---
# This simulates having a 'plugins' directory with 'my_plugin.py'
temp_dir = tempfile.TemporaryDirectory()
plugin_root_dir = temp_dir.name
plugin_dir_path = os.path.join(plugin_root_dir, "plugins")
os.makedirs(plugin_dir_path, exist_ok=True)
plugin_file_path = os.path.join(plugin_dir_path, "my_plugin.py")
with open(plugin_file_path, "w") as f:
f.write("""
from pluginlib import Plugin
class MyPlugin(Plugin):
version = "1.0.0"
def execute(self) -> str:
return "Hello from MyPlugin!"
""")
# --- End Setup ---
try:
# Initialize the PluginLoader to search in our temporary 'plugins' directory
# We specify the exact plugin module name and its base class
with PluginLoader(
[plugin_root_dir], # Search path includes the root of our plugins dir
plugin_name="my_plugin", # The name of the module (my_plugin.py)
plugin_class="Plugin" # The base class for our plugins
) as loader:
# Access the loaded plugins. 'plugins' is a nested dictionary:
# {module_name: {plugin_class_name: instance}}
loaded_plugins = loader.plugins
if "my_plugin" in loaded_plugins and "MyPlugin" in loaded_plugins["my_plugin"]:
my_plugin_instance = loaded_plugins["my_plugin"]["MyPlugin"]
result = my_plugin_instance.execute()
print(f"Successfully loaded and executed plugin: {result}")
print(f"Plugin version: {my_plugin_instance.version}")
else:
print("Error: MyPlugin could not be found or loaded.")
finally:
# --- Teardown: Clean up the temporary directory ---
temp_dir.cleanup()
# --- End Teardown ---