Auto-Registry
The Horus Runtime SDK supports automatic registration and plugin discovery through Python entry points.
Features
- Automatic discovery of
Artifact,Task,Runtime,Executor,Target,Workflow,Transfer,Interaction,InteractionTransport, andInteractionRenderertypes - Pydantic-backed discriminator lookup using
kind - Composite discriminator keys via
AutoRegistryProductfor registries keyed on multiple dimensions - Extensible architecture for third-party integrations
How Auto-Registry Works
AutoRegistry discovers implementations by:
- scanning Python entry points under a Horus namespace
- importing the referenced modules
- registering concrete subclasses under their discriminator value
This lets Horus load plugins dynamically without a central import list.
The kind Field
Every registrable base class declares:
registry_key: ClassVar[str] = "kind"
kind: str
Concrete implementations then assign a concrete string value:
class HorusTask(BaseTask):
kind: str = "horus_task"
That same kind field is used to choose the concrete class during model
validation and deserialization.
Generic Subclasses
Horus supports registrable generic base classes such as BaseRuntime[T].
Concrete subclasses of parameterized generics are registered normally. The
registry now skips only synthetic class names that contain [ rather than
skipping all subclasses of parameterized generics. This allows classes like
CommandRuntime(BaseRuntime[str]) and PythonFunctionRuntime(BaseRuntime[Callable[..., Any]])
to be discovered correctly.
Supported Entry Points
Plugins are exposed through Python entry points in pyproject.toml.
| Entry Point Group | Plugin Type | Example Key | Example Module |
|---|---|---|---|
horus.artifact | Artifact plugins | file | horus_builtin.artifact.file |
horus.task | Task plugins | horus_task | horus_builtin.task.horus_task |
horus.runtime | Runtime plugins | command | horus_builtin.runtime.command |
horus.executor | Executor plugins | shell | horus_builtin.executor.shell |
horus.target | Target plugins | local | horus_builtin.target.local |
horus.transfer | Transfer strategy plugins | local_noop | horus_builtin.transfer.local_noop |
horus.workflow | Workflow plugins | horus_workflow | horus_builtin.workflow.horus_workflow |
horus.interaction | Interaction plugins | common | horus_builtin.interaction.common |
horus.interaction_transport | Interaction transport plugins | cli | horus_builtin.interaction.cli |
horus.interaction_renderer | Interaction renderer plugins | cli | horus_builtin.interaction.cli |
Example built-in configuration:
[project.entry-points."horus.artifact"]
file = "horus_builtin.artifact.file"
folder = "horus_builtin.artifact.folder"
[project.entry-points."horus.executor"]
shell = "horus_builtin.executor.shell"
python_exec = "horus_builtin.executor.python_exec"
python_fn = "horus_builtin.executor.python_fn"
[project.entry-points."horus.runtime"]
command = "horus_builtin.runtime.command"
python_string = "horus_builtin.runtime.python_string"
python = "horus_builtin.runtime.python"
[project.entry-points."horus.task"]
horus_task = "horus_builtin.task.horus_task"
[project.entry-points."horus.target"]
local = "horus_builtin.target.local"
[project.entry-points."horus.transfer"]
local_noop = "horus_builtin.transfer.local_noop"
[project.entry-points."horus.workflow"]
horus_workflow = "horus_builtin.workflow.horus_workflow"
[project.entry-points."horus.interaction"]
common = "horus_builtin.interaction.common"
[project.entry-points."horus.interaction_transport"]
cli = "horus_builtin.interaction.cli"
[project.entry-points."horus.interaction_renderer"]
cli = "horus_builtin.interaction.cli"
Setting Up Plugins
1. Define Entry Points
For example:
[project.entry-points."horus.executor"]
my_executor = "my_package.executor.my_executor"
2. Install the Package
Install the package in the same environment as Horus Runtime. The registry will discover it automatically.
Composite Discriminator Keys
Some registries need a key that combines the discriminators of multiple other
AutoRegistry types. AutoRegistryProduct is a mixin that handles this
automatically.
See Auto-Registry Product for the full explanation and usage guide.
Custom Registries
If you inherit directly from AutoRegistry, you must supply entry_point:
class MyRuntime(AutoRegistry, entry_point="runtime"):
registry_key: ClassVar[str] = "kind"
kind: str
AutoRegistry prefixes the group internally, so:
- Class definition:
entry_point="runtime" pyproject.toml:"horus.runtime"
References
- Python entry points specification: packaging.python.org