Event Handlers
Event handlers attach to a
ComputeStep and react to the events
it emits. ResultsHandler keeps
the best (or last) result,
HistoryHandler keeps
everything, DataFrameHandler
writes a structured table,
CallbackHandler forwards
selected events to a user callback, and
EventForwardHandler
forwards events to an
EventDispatcher for
lock-free dispatch.
The EventDispatcher fans
events out to its registered handlers from the asyncio event loop's thread, so
handlers shared across concurrent compute steps need no locking.
See Optimization Workflows and Working with Results for usage.
ropt.components.event_handlers.EventHandler
Bases: ABC
Abstract base class for event handlers.
A concrete handler reacts to the events emitted by a
ComputeStep it is attached to,
by implementing
handle_event.
Handlers may store state using dictionary-like access ([]).
Note
A handler's handle_event is not re-entrant, and not safe to call from
two threads at once: both raise WorkflowError. Register a handler
shared across concurrently running steps with an
EventDispatcher
instead, which serializes the calls. See
Optimization Workflows and
Parallel Evaluation for usage
and pitfalls.
claim
Claim this handler for exclusive use by one run at a time.
Claiming marks the handler as dedicated to a single consumer, such as
one optimization run, until it is released with
release. While a
claim is held, a second claim raises, so a handler can never be shared by
two runs at once; releasing it at the end of a run lets the same handler
be reused by a later, sequential run, for example to accumulate results.
Handlers meant to aggregate across concurrent runs are not claimed;
they are shared explicitly through an
EventDispatcher.
This claim is independent of the attachment to a dispatcher or a compute
step, and of the transient concurrency guard on handle_event.
Raises:
| Type | Description |
|---|---|
WorkflowError
|
If the handler is currently claimed. |
release
Release a claim taken with claim so the handler can be reused.
Clears the exclusive-use flag, letting a later run claim the handler again, for example to accumulate results across sequential runs. The attachment to a dispatcher or a compute step is left untouched. Releasing an unclaimed handler is a no-op.
event_types
abstractmethod
property
The event types that are handled.
Returns:
| Type | Description |
|---|---|
set[EnOptEventType]
|
A set of event types that are handled. |
handle_event
React to an emitted event.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
EnOptEvent
|
The event object. |
required |
Raises:
| Type | Description |
|---|---|
WorkflowError
|
If this handler is already running on another thread. |
__getitem__
Retrieve a stored value by key (handler[key]).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
The string key identifying the value to retrieve. |
required |
Returns:
| Type | Description |
|---|---|
Any
|
The value associated with the specified key. |
Raises:
| Type | Description |
|---|---|
AttributeError
|
If |
__setitem__
Store or update a value in the internal state (handler[key] = value).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
The string key identifying the value to store (must be an identifier). |
required |
value
|
Any
|
The value to associate with the key. |
required |
Raises:
| Type | Description |
|---|---|
AttributeError
|
If |
ropt.components.event_handlers.ResultsHandler
Bases: EventHandler
Track a single optimization result based on selection criteria.
Listens for FINISHED_EVALUATION events and retains either the best
(lowest weighted objective) or most recent valid result. Optionally
filters by constraint tolerance. The selected result is accessible via the
result property or
handler["results"].
See Result Handlers for full details on selection criteria and scaling.
__init__
__init__(
*,
what: Literal["best", "last"] = "best",
constraint_tolerance: float | None = None,
filter: Callable[[Results], bool] | None = None,
) -> None
Initialize the ResultsHandler.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
what
|
Literal['best', 'last']
|
Criterion for selecting results ('best' or 'last'). |
'best'
|
constraint_tolerance
|
float | None
|
Optional threshold for filtering constraint violations. Violations are compared in the domain the optimizer works in, so a scale applies to them as well. |
None
|
filter
|
Callable[[Results], bool] | None
|
Optional callable to filter results based on custom logic. |
None
|
result
property
The selected (best or last) result, or None if none is available.
event_types
property
The event types that are handled.
Returns:
| Type | Description |
|---|---|
set[EnOptEventType]
|
A set of event types that are handled. |
ropt.components.event_handlers.HistoryHandler
Bases: EventHandler
Collect all optimization results into a tuple.
Listens for FINISHED_EVALUATION events and appends every
Results object to a growing tuple accessible
via the results
property or handler["results"].
See Result Handlers for full details on scaling and accumulation behavior.
event_types
property
The event types that are handled.
Returns:
| Type | Description |
|---|---|
set[EnOptEventType]
|
A set of event types that are handled. |
ropt.components.event_handlers.DataFrameHandler
Bases: EventHandler
Build pandas or polars DataFrames from optimization results.
Collects FunctionResults and
GradientResults into named tables.
Tables are defined via add_table with a column specification, or
registered in bulk with set_default_tables.
The frame library is chosen with the engine argument. The "polars"
engine, the default, produces long-format tables in which batch and axis
labels are ordinary leading columns; the "pandas" engine produces tables
indexed by those instead.
Access tables via dictionary syntax: handler["functions"].
Warning
Tables are generated on the fly from internal data when accessing them in this way. When multiple accesses are needed, it is more efficient to first store them in a variable.
See Result Handlers for the column specification, default tables, and callback details.
__init__
Initialize a default table event handler.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
engine
|
DataFrameEngine
|
Frame library used to build the tables. |
'polars'
|
sep
|
str
|
Separator used in column names. |
','
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
UnsupportedError
|
If the selected frame library is not installed. |
engine
property
The frame library used to build the tables.
Returns:
| Type | Description |
|---|---|
DataFrameEngine
|
Either |
set_default_tables
Register a standard set of result tables.
Adds the default functions, evaluations, and constraints tables
for function results, and the default gradients and perturbations
tables for gradient results.
set_callback
Set a function to call whenever the tables are updated.
The callback receives the output directory configured for the run
(OptimizerConfig.output_dir, None if
it is not set), and reads the tables from this handler. If it performs
blocking operations (for example writing tables to disk), register this
handler with run_in_thread=True on the
EventDispatcher:
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
callback
|
Callable[[Path | None], None]
|
A function that is called when the tables are updated. |
required |
add_table
add_table(
name: str,
table_type: Literal["functions", "gradients"],
columns: dict[str, str],
) -> None
Register a new table to be populated from incoming results.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Key under which the table is stored and looked up. |
required |
table_type
|
Literal['functions', 'gradients']
|
Whether this table is filled from function results
( |
required |
columns
|
dict[str, str]
|
Mapping from result-field attribute names (using dotted attribute syntax) to display titles. |
required |
get_tables
Return the tables stored in the event handler.
Returns:
| Type | Description |
|---|---|
dict[str, DataFrame | DataFrame]
|
A dictionary mapping table names to their corresponding tables. |
Warning
Tables are generated on the fly from internal data. When multiple access is needed, it is more efficient to first store them in a variable.
event_types
property
The event types that are handled.
Returns:
| Type | Description |
|---|---|
set[EnOptEventType]
|
A set of event types that are handled. |
__getitem__
Retrieve a of a table from the event handler.
Warning
The table is generated on the fly from internal data hen multiple access are needed, it is more efficient to first store them in a variable.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
The string key identifying the table to retrieve. |
required |
Returns:
| Type | Description |
|---|---|
Any
|
The table associated with the specified key. |
Raises:
| Type | Description |
|---|---|
AttributeError
|
If the requested table does not exist. |
add_column
ropt.components.event_handlers.CallbackHandler
Bases: EventHandler
The default event handler for observing events.
This event handler listens for events of matching types and forwards them to a callback function.
If the callback performs blocking operations (file I/O, network calls,
etc.), register this handler with run_in_thread=True on the
EventDispatcher:
__init__
Initialize the CallbackHandler.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event_types
|
set[EnOptEventType]
|
The set of event types to respond to. |
required |
callback
|
Callable[[EnOptEvent], None]
|
The callable to invoke for matching events. |
required |
event_types
property
The event types that are handled.
Returns:
| Type | Description |
|---|---|
set[EnOptEventType]
|
A set of event types that are handled. |
ropt.components.event_handlers.EventForwardHandler
Bases: EventHandler
Forwards events from a compute step to an EventDispatcher.
See Optimization Workflows for usage.
__init__
Initialize the EventForwardHandler.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dispatcher
|
EventDispatcher
|
The EventDispatcher to forward events to. |
required |
event_types
|
set[EnOptEventType]
|
The set of event types to forward. |
required |
ropt.components.event_handlers.EventDispatcher
Dispatches events to handlers from the asyncio event loop's thread.
Handlers added with run_in_thread=True run on a thread pool the
dispatcher owns and shuts down when it stops, so handler work is isolated
from the asyncio loop's shared default pool.
See Parallel Evaluation for usage.
add_event_handler
Add an event handler.
By default the handler is called directly on the event loop's thread.
Pass run_in_thread=True for handlers that perform blocking I/O; see
Thread-based dispatch.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
handler
|
EventHandler
|
The handler to add. |
required |
run_in_thread
|
bool
|
If True, dispatch via the dispatcher's thread pool instead of the event loop. |
False
|
remove_event_handler
Remove a previously added handler.
The handler is released, so it can afterwards be added to another dispatcher or registered with a compute step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
handler
|
EventHandler
|
The handler to remove. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
Whether the removed handler was set to run in a thread. |
Raises:
| Type | Description |
|---|---|
WorkflowError
|
If the handler was not added to this dispatcher. |
dispatch_event
Submit an event and block until every handler has processed it.
Events are handled in submission order. A handler exception is re-raised here, on the caller's own stack. See Handler failures.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
EnOptEvent
|
The event to submit. |
required |
Raises:
| Type | Description |
|---|---|
WorkflowError
|
If the dispatcher is not running, or if the call is made from the thread running its event loop, or from one of its handler threads. |
Exception
|
Whatever a handler raised while processing the event. |
start
async
Start the dispatcher.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task_group
|
TaskGroup
|
The task group to use. |
required |
Raises:
| Type | Description |
|---|---|
WorkflowError
|
If the dispatcher is already running. |