-
Notifications
You must be signed in to change notification settings - Fork 0
Extensions
Asterios Raptis edited this page Mar 27, 2026
·
1 revision
PluginForge supports an extension point pattern for querying active plugins by interface, inspired by PF4J's extension system.
While pluggy hooks use a fire-and-forget call pattern (call_hook("on_save", ...)), extension points let you query and interact with plugins directly:
Hooks: pm.call_hook("on_save", document=doc) -> list of results
Extensions: pm.get_extensions(ExportFormat) -> list of plugin instances
An extension point is any Python class or ABC:
from abc import ABC, abstractmethod
class ExportFormat(ABC):
"""Extension point for document export formats."""
@abstractmethod
def export(self, document: dict, output_path: str) -> str:
"""Export a document and return the output file path."""
...
@abstractmethod
def supported_extensions(self) -> list[str]:
"""Return supported file extensions."""
...Plugins implement extension points by inheriting from both BasePlugin and the extension point:
from pluginforge import BasePlugin
class EpubExport(BasePlugin, ExportFormat):
name = "epub_export"
version = "1.0.0"
def export(self, document: dict, output_path: str) -> str:
# ... epub export logic ...
return f"{output_path}.epub"
def supported_extensions(self) -> list[str]:
return [".epub"]
class PdfExport(BasePlugin, ExportFormat):
name = "pdf_export"
version = "1.0.0"
def export(self, document: dict, output_path: str) -> str:
# ... pdf export logic ...
return f"{output_path}.pdf"
def supported_extensions(self) -> list[str]:
return [".pdf"]Use get_extensions() to find all active plugins implementing an extension point:
pm = PluginManager("config/app.yaml")
pm.register_plugins([EpubExport, PdfExport, AnalyticsPlugin])
# Only returns plugins that implement ExportFormat
exporters = pm.get_extensions(ExportFormat)
# [<EpubExport>, <PdfExport>]
# Use them directly
for exporter in exporters:
path = exporter.export(document, "/tmp/output")
print(f"Exported to {path}")
# Get all supported formats
all_extensions = []
for exporter in exporters:
all_extensions.extend(exporter.supported_extensions())
# [".epub", ".pdf"]| Aspect | Hooks | Extensions |
|---|---|---|
| Pattern | Fire-and-forget | Query and interact |
| Returns | List of results | List of plugin instances |
| Use case | Events, notifications | Capabilities, strategies |
| Example | "Document was saved" | "Which export formats exist?" |
Use hooks when you want to notify plugins about events. Use extensions when you want to discover capabilities and interact with specific plugins.
A plugin can be both an extension and a hook implementer:
class EpubExport(BasePlugin, ExportFormat):
name = "epub_export"
# Extension point implementation
def export(self, document: dict, output_path: str) -> str:
return self._do_export(document, output_path)
def supported_extensions(self) -> list[str]:
return [".epub"]
# Hook implementation
@hookimpl
def on_document_save(self, document: dict) -> None:
# Auto-export on save if configured
if self.config.get("auto_export"):
self.export(document, self.config["output_dir"])