Skip to main content
Both runtimes support registering sync and async handlers together. Supported handler shapes:
  • bare functions (sync or async)
  • static methods (sync or async)
  • class-level methods (Python @classmethod; in TypeScript, class-level handlers are static methods)
  • instance methods (sync or async)
import asyncio
from bubus import EventBus, BaseEvent

class WorkEvent(BaseEvent[str]):
    task_id: str

def bare_sync(event: WorkEvent) -> str:
    return f'bare-sync:{event.task_id}'

async def bare_async(event: WorkEvent) -> str:
    await asyncio.sleep(0.01)
    return f'bare-async:{event.task_id}'

class HandlerSet:
    def __init__(self, prefix: str) -> None:
        self.prefix = prefix

    @staticmethod
    def static_sync(event: WorkEvent) -> str:
        return f'static-sync:{event.task_id}'

    @staticmethod
    async def static_async(event: WorkEvent) -> str:
        await asyncio.sleep(0.01)
        return f'static-async:{event.task_id}'

    @classmethod
    def class_sync(cls, event: WorkEvent) -> str:
        return f'{cls.__name__}-class-sync:{event.task_id}'

    @classmethod
    async def class_async(cls, event: WorkEvent) -> str:
        await asyncio.sleep(0.01)
        return f'{cls.__name__}-class-async:{event.task_id}'

    def instance_sync(self, event: WorkEvent) -> str:
        return f'{self.prefix}-instance-sync:{event.task_id}'

    async def instance_async(self, event: WorkEvent) -> str:
        await asyncio.sleep(0.01)
        return f'{self.prefix}-instance-async:{event.task_id}'

bus = EventBus('AppBus')
handlers = HandlerSet(prefix='svc')

bus.on(WorkEvent, bare_sync)
bus.on(WorkEvent, bare_async)
bus.on(WorkEvent, HandlerSet.static_sync)
bus.on(WorkEvent, HandlerSet.static_async)
bus.on(WorkEvent, HandlerSet.class_sync)
bus.on(WorkEvent, HandlerSet.class_async)
bus.on(WorkEvent, handlers.instance_sync)
bus.on(WorkEvent, handlers.instance_async)