Skip to main content

Events

The event system lets you react to workflow execution in real-time.

EventBus

Import from orca.sdk.events:

from orca.sdk.events import EventBus

event_bus = EventBus()

Methods

MethodDescription
subscribe(event_name, handler)Register a handler for an event
unsubscribe(event_name, handler)Remove a handler
emit(event_name, context)Emit an event (internal use)

Subscribing to Events

Function Handlers

Simple callable handlers receive event name and context:

def on_thread_completed(event_name, context):
print(f"Thread {context.thread_name} completed")

event_bus.subscribe("THREAD.COMPLETED", on_thread_completed)

Workflow Event Handlers

Subscribe directly on the workflow:

workflow.add_event_handler("METHOD.COMPLETED", on_method_complete)

Event Names

Events follow the pattern ENTITY.ID.STATUS or ENTITY.STATUS:

Thread Events

EventWhen
THREAD.CREATEDThread instance created
THREAD.MOVINGThread labware is being transported
THREAD.EXECUTING_ACTIONAction is executing
THREAD.COMPLETEDThread finished all methods

Method Events

EventWhen
METHOD.CREATEDMethod instance created
METHOD.IN_PROGRESSMethod is executing
METHOD.COMPLETEDAll actions in method done

Action Events

EventWhen
ACTION.CREATEDAction created
ACTION.EXECUTING_ACTIONAction is running
ACTION.COMPLETEDAction finished
ACTION.ERROREDAction failed

Workflow Events

EventWhen
WORKFLOW.CREATEDWorkflow created
WORKFLOW.IN_PROGRESSWorkflow running
WORKFLOW.COMPLETEDAll threads completed
WORKFLOW.ERROREDWorkflow failed

Execution Context

Handlers receive context with execution details. Import context types from orca.sdk.events:

from orca.sdk.events import ExecutionContext, WorkflowExecutionContext, ThreadExecutionContext

WorkflowExecutionContext

@dataclass
class WorkflowExecutionContext:
workflow_id: str
workflow_name: str

ThreadExecutionContext

@dataclass
class ThreadExecutionContext(WorkflowExecutionContext):
thread_id: str
thread_name: str

The ExecutionContext type is a union of all context types. Handlers receive the appropriate context type based on the event.

SystemBoundEventHandler

For handlers that need system access, extend SystemBoundEventHandler:

from orca.sdk.events import SystemBoundEventHandler

class MyHandler(SystemBoundEventHandler):
def handle(self, event_name: str, context):
# Access system via self._system
device = self._system.get_device("shaker")
print(f"Event: {event_name}, Device status: {device.is_initialized}")

The system is automatically injected when the workflow runs.

Status Enums

Import status enums for comparison:

from orca.sdk.events import ActionStatus, MethodStatus, LabwareThreadStatus

# ActionStatus values
ActionStatus.CREATED
ActionStatus.EXECUTING_ACTION
ActionStatus.COMPLETED
ActionStatus.ERRORED

# MethodStatus values
MethodStatus.CREATED
MethodStatus.IN_PROGRESS
MethodStatus.COMPLETED

# LabwareThreadStatus values
LabwareThreadStatus.CREATED
LabwareThreadStatus.MOVING
LabwareThreadStatus.EXECUTING_ACTION
LabwareThreadStatus.COMPLETED

Example: Logging Handler

from orca.sdk.events import EventBus

def log_event(event_name, context):
print(f"[{event_name}] workflow={context.workflow_name}")
if hasattr(context, 'thread_name'):
print(f" thread={context.thread_name}")
if hasattr(context, 'method_name'):
print(f" method={context.method_name}")

event_bus = EventBus()
event_bus.subscribe("THREAD.COMPLETED", log_event)
event_bus.subscribe("METHOD.COMPLETED", log_event)
event_bus.subscribe("WORKFLOW.COMPLETED", log_event)

Next Steps