- 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:
fromabcimportABC, abstractmethodclassExportFormat(ABC):
"""Extension point for document export formats."""@abstractmethoddefexport(self, document: dict, output_path: str) ->str:
"""Export a document and return the output file path."""
...
@abstractmethoddefsupported_extensions(self) ->list[str]:
"""Return supported file extensions."""
...Plugins implement extension points by inheriting from both BasePlugin and the extension point:
frompluginforgeimportBasePluginclassEpubExport(BasePlugin, ExportFormat):
name="epub_export"version="1.0.0"defexport(self, document: dict, output_path: str) ->str:
# ... epub export logic ...returnf"{output_path}.epub"defsupported_extensions(self) ->list[str]:
return [".epub"]
classPdfExport(BasePlugin, ExportFormat):
name="pdf_export"version="1.0.0"defexport(self, document: dict, output_path: str) ->str:
# ... pdf export logic ...returnf"{output_path}.pdf"defsupported_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 ExportFormatexporters=pm.get_extensions(ExportFormat)
# [<EpubExport>, <PdfExport>]# Use them directlyforexporterinexporters:
path=exporter.export(document, "/tmp/output")
print(f"Exported to {path}")
# Get all supported formatsall_extensions= []
forexporterinexporters:
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:
classEpubExport(BasePlugin, ExportFormat):
name="epub_export"# Extension point implementationdefexport(self, document: dict, output_path: str) ->str:
returnself._do_export(document, output_path)
defsupported_extensions(self) ->list[str]:
return [".epub"]
# Hook implementation@hookimpldefon_document_save(self, document: dict) ->None:
# Auto-export on save if configuredifself.config.get("auto_export"):
self.export(document, self.config["output_dir"])