1. Your First Component
A component is a plain Python class with one decorator.
The Goal
By the end of this page you’ll have a class that the kernel manages — it instantiates it, activates it, and shuts it down. You write zero lifecycle plumbing.
One Decorator
from signalpy.kernel import component
@component("greeter")
class Greeter:
passThat’s a component. The @component("greeter") decorator tells the kernel: “this class is a component factory named greeter.” The kernel can instantiate it, track its state, and manage its lifecycle.
The class is still a normal Python class. No base class, no metaclass, no framework inheritance.
Lifecycle
Components have a lifecycle: the kernel creates them, activates them (your setup code runs), and later deactivates them (your cleanup code runs):
from signalpy.kernel import component, lifecycle
@component("greeter")
class Greeter:
@lifecycle.activate
def activate(self):
print("Greeter is ready")
@lifecycle.deactivate
def deactivate(self):
print("Greeter shutting down")The method names don’t matter — call them activate, start, setup, whatever. The @lifecycle.activate decorator marks them.
Boot It
import asyncio
from signalpy.kernel import Kernel, component, lifecycle
@component("greeter")
class Greeter:
@lifecycle.activate
def activate(self):
print("Greeter is ready")
@lifecycle.deactivate
def deactivate(self):
print("Greeter shutting down")
async def main():
kernel = Kernel()
kernel.discover([Greeter]) # tell the kernel about your class
await kernel.boot() # instantiate + activate
await kernel.shutdown() # deactivate
asyncio.run(main())Greeter is ready
Greeter shutting down
What Happened
Three lines of kernel code did this:
discover([Greeter])— the kernel read the@componentmetadata, registered the factoryboot()— the kernel instantiatedGreeter(), called youractivate()shutdown()— the kernel called yourdeactivate()
You declare (with decorators), the kernel executes (lifecycle, dependencies, wiring). Your class never calls the kernel. The kernel calls you.
This seems trivial with one class. It gets powerful when you have 10 components with dependencies between them — the kernel resolves the dependency graph, activates them in the right order, and shuts them down in reverse.
Run It
PYTHONPATH=src python src/signalpy/examples/01_hello.py