Plugins¶
Plugins extend a runner with custom steps, expression filters, and lifecycle event subscribers.
Only plugins explicitly passed to WorkflowRunner or listed in workflow YAML are activated.
Plugin contract¶
from pydantic import BaseModel, ConfigDict
from crawlerflow.engine.context import WorkflowContext
from crawlerflow.plugins import PluginRegistrationContext
class ExampleSettings(BaseModel):
model_config = ConfigDict(extra="forbid")
endpoint: str
timeout: float = 10
class ExamplePlugin:
name = "example"
settings_model = ExampleSettings
def register(self, context: PluginRegistrationContext) -> None:
context.registry.register("custom_step", CustomStep)
context.expression_engine.register_filter("reverse", lambda value: str(value)[::-1])
context.event_bus.subscribe(EventName.STEP_FINISHED, handle_step)
async def startup(self, context: WorkflowContext) -> None:
settings = context.plugin_settings[self.name]
context.storage["client"] = await create_client(settings.endpoint, settings.timeout)
async def shutdown(self, context: WorkflowContext) -> None:
await context.storage["client"].close()
Applications may inject plugin instances directly:
Each runner gets an isolated step registry, so plugin registrations do not leak into other runner instances.
YAML settings¶
Plugins without settings keep the short form:
Use the object form to pass workflow-specific settings:
A plugin opts into settings by exposing a Pydantic settings_model. Crawlerflow validates settings
while loading the workflow and stores the resulting model instance in
context.plugin_settings[plugin_name]. Non-empty settings are rejected when a plugin does not
declare a model. Plugin names must remain unique within one workflow.
Runtime lifecycle¶
startup and shutdown are optional and may be synchronous or asynchronous. Both receive the
current WorkflowContext, including variables, outputs, plugin settings, storage, browser adapter,
and base path.
The runner applies this order for every execution:
- Load, register, and validate configured plugins.
- Call
startupin plugin registration order. - Execute the workflow and publish its lifecycle events.
- Call
shutdownin reverse registration order. - Detach the event logger and close the browser adapter.
If startup fails, plugins that already started are shut down before the error is returned. Every shutdown hook is attempted even if another shutdown hook fails. A shutdown failure after a workflow failure is attached to the original error rather than replacing it.
Package entry points¶
External packages expose plugin classes or instances through the crawlerflow.plugins entry-point
group:
The workflow opts in by entry-point name:
Crawlerflow rejects missing plugins, duplicate plugin names, and entry points whose loaded plugin name differs from the configured entry-point name.
Discover installed entry points without importing or activating plugin code:
The command displays each plugin name, import target, and owning Python distribution.
Example package¶
examples/plugins/example is a separately installable reference package. It registers a custom
set_output step and surround expression filter: