Plugin Registry¶
The plugin registry manages all registered plugins and their state.
Registering Plugins¶
Registering Classes or Instances¶
Register plugins using register() method:
# Register class (auto-instantiated if no __init__ params)
simplug.register(MyPlugin)
# Register instance (use when __init__ needs params)
instance = MyPlugin(config={})
simplug.register(instance)
Registering Multiple Plugins¶
Register multiple plugins at once:
Registering by Module Name¶
Register a plugin by module string:
The module will be imported automatically.
Querying Plugins¶
Get Plugin by Name¶
Get a specific plugin:
plugin = simplug.get_plugin('myplugin')
# Get raw plugin object
plugin_obj = simplug.get_plugin('myplugin', raw=True)
Raises NoSuchPlugin if plugin not found.
Get All Plugins¶
Get all registered plugins:
# Get plugin wrappers
plugins = simplug.get_all_plugins()
# Get raw plugin objects
plugins = simplug.get_all_plugins(raw=True)
Returns an OrderedDiot (ordered dictionary).
Get Enabled Plugins¶
Get only enabled plugins:
# Get enabled plugin wrappers
enabled = simplug.get_enabled_plugins()
# Get enabled raw objects
enabled = simplug.get_enabled_plugins(raw=True)
Get Plugin Names¶
Get list of all plugin names:
Get enabled plugin names:
Names are in execution order (sorted by priority).
Enabling and Disabling Plugins¶
Disable Plugins¶
Temporarily disable plugins:
# Disable specific plugin
simplug.disable('plugin1')
# Disable multiple
simplug.disable('plugin1', 'plugin2')
Enable Plugins¶
Re-enable disabled plugins:
# Enable specific plugin
simplug.enable('plugin1')
# Enable multiple
simplug.enable('plugin1', 'plugin2')
Direct Plugin Access¶
You can also access plugins directly:
# Get plugin and disable
plugin = simplug.get_plugin('myplugin')
plugin.disable()
# Get plugin and enable
plugin = simplug.get_plugin('myplugin')
plugin.enable()
Plugin Context Manager¶
Temporarily enable or disable plugins using a context manager:
# Enable only specific plugins
with simplug.plugins_context(['plugin1', 'plugin2']):
# Only plugin1 and plugin2 are active
simplug.hooks.my_hook(data)
# Original state restored
Context Syntax¶
# Enable only these plugins
with simplug.plugins_context(['plugin1', 'plugin2']):
pass
# Add plugin
with simplug.plugins_context(['+plugin3']):
# plugin3 added to enabled set
pass
# Remove plugin
with simplug.plugins_context(['-plugin1']):
# plugin1 removed from enabled set
pass
# Multiple operations
with simplug.plugins_context(['-plugin1', '+plugin3']):
# plugin1 disabled, plugin3 enabled
pass
# No changes
with simplug.plugins_context(None):
# All plugins maintain current state
pass
Context Rules¶
- All plugins without prefix (
+/-): Only those are enabled, all others disabled - With prefixes: All start current state, then apply changes
- Context exit: Original state automatically restored
Plugin Names¶
Plugin names are determined in this priority:
_nameattribute (when loaded from entrypoint)nameattribute__name__attribute (lowercased)__class__.__name__attribute (lowercased)
class MyPlugin:
name = "custom_name" # Will use "custom_name"
# Or
class MyPlugin:
pass # Will use "myplugin" (lowercased)
Duplicate Plugin Names¶
Registering a plugin with existing name raises error:
simplug.register(Plugin1) # Name: "plugin1"
simplug.register(Plugin2) # Also has name: "plugin1"
# Raises PluginRegistered
Same plugin object is allowed:
Inspection Methods¶
Check if Plugin Exists¶
Get Plugin Count¶
List Disabled Plugins¶
all_plugins = set(simplug.get_all_plugin_names())
enabled_plugins = set(simplug.get_enabled_plugin_names())
disabled = all_plugins - enabled_plugins
Complete Example¶
from simplug import Simplug
simplug = Simplug('app')
# Define hook
@simplug.spec
def process(data):
pass
# Create plugins
class PluginA:
name = "plugin_a"
priority = -1 # Higher priority
@simplug.impl
def process(self, data):
return f"A: {data}"
class PluginB:
name = "plugin_b"
@simplug.impl
def process(self, data):
return f"B: {data}"
class PluginC:
name = "plugin_c"
priority = 1 # Lower priority
@simplug.impl
def process(self, data):
return f"C: {data}"
# Register all
simplug.register(PluginA, PluginB, PluginC)
# Check registry
print(f"All plugins: {simplug.get_all_plugin_names()}")
# Output: ['plugin_a', 'plugin_b', 'plugin_c']
print(f"Enabled: {simplug.get_enabled_plugin_names()}")
# Output: ['plugin_a', 'plugin_b', 'plugin_c']
# Disable one
simplug.disable('plugin_b')
print(f"Enabled: {simplug.get_enabled_plugin_names()}")
# Output: ['plugin_a', 'plugin_c']
# Use context to enable only plugin_b
with simplug.plugins_context(['plugin_b']):
print(f"In context: {simplug.get_enabled_plugin_names()}")
# Output: ['plugin_b']
result = simplug.hooks.process("test")
print(result) # ["B: test"]
# Context exit - original state restored
print(f"After context: {simplug.get_enabled_plugin_names()}")
# Output: ['plugin_a', 'plugin_c']
Next Steps¶
- Priority System - How execution order is determined
- Setuptools Entrypoints - Loading plugins from packages
- Implementing Hooks - Creating plugins