pyqt_reactive.protocols

Widget protocol definitions and adapters.

ABC-based widget contracts that eliminate duck typing in favor of explicit, fail-loud inheritance-based architecture.

class pyqt_reactive.protocols.ValueGettable[source]

ABC for widgets that can return a value.

All input widgets must implement this to participate in form value extraction.

abstractmethod get_value() Any[source]

Get the current value from the widget.

Returns:

The widget’s current value. None if no value set.

class pyqt_reactive.protocols.ValueSettable[source]

ABC for widgets that can accept a value.

All input widgets must implement this to participate in form value updates.

abstractmethod set_value(value: Any) None[source]

Set the widget’s value.

Parameters:

value – The value to set. None clears the widget.

class pyqt_reactive.protocols.ResolvedValuePreviewSettable[source]

ABC for widgets that render inherited/resolved values separately from raw edits.

Lazy dataclass container widgets may keep raw None child fields while previewing the resolved inherited dataclass. This contract lets form chrome refresh that preview without replacing the raw editable value.

abstractmethod set_resolved_value_preview(value: Any) None[source]

Set the resolved value used for display/preview only.

Parameters:

value – Resolved value for the same logical field.

class pyqt_reactive.protocols.RawResolvedValueSettable[source]

ABC for widgets that can atomically apply a raw value and resolved preview.

Lazy dataclass widgets can avoid rendering a raw intermediate state when a form refresh already has both ObjectState values available.

abstractmethod set_raw_value_with_resolved_preview(raw_value: Any, resolved_value: Any) None[source]

Set the editable raw value and resolved display preview in one pass.

Parameters:
  • raw_value – Raw ObjectState value for editing.

  • resolved_value – Resolved ObjectState value for inherited preview.

class pyqt_reactive.protocols.ChildFieldChromeRefreshable[source]

ABC for compound widgets that render chrome for their own child fields.

Inline dataclass widgets can own section labels/reset controls internally while still being edited as one form value. This contract lets the form manager refresh those child markers after ObjectState dirty/signature state changes without knowing widget-specific field names.

abstractmethod refresh_child_field_chrome(owner_field_paths: tuple['DottedFieldPath', ...] | None = None) None[source]

Refresh dirty/signature/reset chrome for child fields.

class pyqt_reactive.protocols.ChildFieldSemanticChromeRefreshable[source]

ABC for compound widgets that render semantic chrome for child leaves.

abstractmethod child_field_semantic_owner_paths() tuple['DottedFieldPath', ...][source]

Return ObjectState owner paths for structural child semantics.

abstractmethod refresh_child_field_semantics(owner_field_path: DottedFieldPath, semantic_index: ObjectStateSubfieldSemanticIndex) None[source]

Refresh dirty/default/inherited chrome for an ObjectState owner field.

class pyqt_reactive.protocols.ChildFieldIdentityProvider[source]

ABC for compound widgets that expose nominal child ObjectState identity.

abstractmethod child_field_identity(field_name: str) InlineDataclassChildFieldIdentity[source]

Return the nominal identity for one direct child field.

class pyqt_reactive.protocols.ChildFieldNavigationTargetProvider[source]

ABC for compound widgets that expose concrete widgets for child fields.

Inline dataclass widgets may render their own child sections internally instead of creating nested ParameterFormManager instances. This contract lets generic form navigation scroll to the concrete child section while keeping the widget-specific layout private to the inline editor.

abstractmethod child_field_navigation_target(field_name: str) QWidget | None[source]

Return the widget that visually represents a child field, if present.

Parameters:

field_name – Direct child field name inside the compound widget.

class pyqt_reactive.protocols.ChildSubfieldNavigationTargetProvider[source]

ABC for compound widgets that expose structural descendant targets.

abstractmethod child_subfield_navigation_target(child_identity: InlineDataclassChildFieldIdentity, relative_path: StructuralValuePath) StructuralFlashTarget | None[source]

Return a concrete visual target for a child structural path.

An empty relative_path represents the child structural owner itself.

class pyqt_reactive.protocols.InlineDataclassGroupBoxChromeProvider[source]

ABC for inline dataclass value widgets that contribute container title chrome.

Regular nested dataclasses can move child widgets such as enableable checkboxes into the groupbox title row. Inline dataclass widgets do not have a nested ParameterFormManager, so they expose the same chrome through this contract while the container remains generic.

abstractmethod configure_inline_dataclass_groupbox(groupbox: Any) None[source]

Attach any inline title chrome to the owning groupbox.

Parameters:

groupbox – The InlineDataclassGroupBox hosting this value widget.

class pyqt_reactive.protocols.InlineDataclassRootResettable[source]

ABC for inline dataclass widgets that can reset their child fields.

abstractmethod reset_inline_dataclass_fields() None[source]

Reset the inline dataclass child fields to their signature defaults.

class pyqt_reactive.protocols.PlaceholderCapable[source]

ABC for widgets that can display placeholder text.

Placeholders show inherited/default values without setting actual values.

abstractmethod set_placeholder(text: str) None[source]

Set placeholder text for the widget.

Parameters:

text – Placeholder text to display (e.g., “Pipeline default: 42”)

class pyqt_reactive.protocols.PlaceholderStateTrackable[source]

ABC for widgets that own placeholder chrome/cache state.

widget_capabilities: ClassVar[frozenset[WidgetCapability]] = frozenset({WidgetCapability.PLACEHOLDER_STATE})
abstractmethod has_placeholder_state() bool[source]

Return whether placeholder chrome or cached placeholder data is present.

abstractmethod mark_placeholder_state() None[source]

Mark the widget as currently displaying placeholder chrome.

abstractmethod clear_placeholder_state() None[source]

Mark the widget as no longer displaying placeholder chrome.

abstractmethod cached_placeholder_text() str | None[source]

Return cached placeholder text, if any.

abstractmethod set_cached_placeholder_text(placeholder_text: str) None[source]

Cache placeholder text after a successful render.

abstractmethod cached_placeholder_resolved_value() Any[source]

Return cached placeholder resolved value, if any.

abstractmethod set_cached_placeholder_resolved_value(value: Any) None[source]

Cache the resolved value after a successful preview render.

abstractmethod clear_placeholder_cache() None[source]

Clear cached placeholder text and resolved value.

class pyqt_reactive.protocols.WidgetCapability(*values)[source]

Nominal widget capability tags for generic service-level queries.

PLACEHOLDER_STATE = 'placeholder_state'
class pyqt_reactive.protocols.WidgetCapabilityTagged[source]

Base for widget contracts that advertise generic capability tags.

widget_capabilities: ClassVar[frozenset[WidgetCapability]] = frozenset({})
pyqt_reactive.protocols.widget_capability_tags(widget_or_type: Any) frozenset[WidgetCapability][source]

Return all capability tags declared by a widget class and its bases.

pyqt_reactive.protocols.widget_supports_capability(widget_or_type: Any, capability: WidgetCapability) bool[source]

Return whether a widget class declares a nominal capability tag.

class pyqt_reactive.protocols.RangeConfigurable[source]

ABC for widgets that support numeric range configuration.

Typically implemented by numeric input widgets (spinboxes, sliders).

abstractmethod configure_range(minimum: float, maximum: float) None[source]

Configure the valid range for numeric input.

Parameters:
  • minimum – Minimum allowed value

  • maximum – Maximum allowed value

class pyqt_reactive.protocols.EnumSelectable[source]

ABC for widgets that can select from enum values.

Typically implemented by dropdowns and radio button groups.

abstractmethod set_enum_options(enum_type: type) None[source]

Configure widget with enum options.

Parameters:

enum_type – The Enum class to populate options from

abstractmethod get_selected_enum() Any[source]

Get the currently selected enum value.

Returns:

The selected enum member, or None if no selection

class pyqt_reactive.protocols.ChangeSignalEmitter[source]

ABC for widgets that emit change signals.

Provides explicit contract for signal connection, eliminating duck typing of signal names (textChanged vs valueChanged vs currentIndexChanged).

abstractmethod connect_change_signal(callback: Callable[[Any], None]) None[source]

Connect callback to widget’s change signal.

The callback will be invoked whenever the widget’s value changes, receiving the new value as its argument.

Parameters:

callback – Function to call when widget value changes. Signature: callback(new_value: Any) -> None

abstractmethod disconnect_change_signal(callback: Callable[[Any], None]) None[source]

Disconnect callback from widget’s change signal.

Parameters:

callback – The callback function to disconnect

class pyqt_reactive.protocols.LineEditAdapter(*args, **kwargs)[source]

Adapter for QLineEdit implementing OpenHCS ABCs.

Normalizes Qt API to OpenHCS contracts: - .text() → .get_value() - .setText() → .set_value() - .setPlaceholderText() → .set_placeholder() - .textChanged → .connect_change_signal()

get_value() Any[source]

Implement ValueGettable ABC.

set_value(value: Any) None[source]

Implement ValueSettable ABC.

set_placeholder(text: str) None[source]

Implement PlaceholderCapable ABC.

connect_change_signal(callback: Callable[[Any], None]) None[source]

Implement ChangeSignalEmitter ABC.

disconnect_change_signal(callback: Callable[[Any], None]) None[source]

Implement ChangeSignalEmitter ABC.

class pyqt_reactive.protocols.SpinBoxAdapter(parent=None)[source]

Adapter for QSpinBox implementing OpenHCS ABCs.

Handles None values using special value text mechanism. When value is None, displays placeholder text at minimum value.

__init__(parent=None)[source]
get_value() Any[source]

Implement ValueGettable ABC.

set_value(value: Any) None[source]

Implement ValueSettable ABC.

set_placeholder(text: str) None[source]

Implement PlaceholderCapable ABC.

configure_range(minimum: float, maximum: float) None[source]

Implement RangeConfigurable ABC.

connect_change_signal(callback: Callable[[Any], None]) None[source]

Implement ChangeSignalEmitter ABC.

disconnect_change_signal(callback: Callable[[Any], None]) None[source]

Implement ChangeSignalEmitter ABC.

class pyqt_reactive.protocols.DoubleSpinBoxAdapter(parent=None)[source]

Adapter for QDoubleSpinBox implementing OpenHCS ABCs.

Handles None values and floating-point ranges.

__init__(parent=None)[source]
get_value() Any[source]

Implement ValueGettable ABC.

set_value(value: Any) None[source]

Implement ValueSettable ABC.

set_placeholder(text: str) None[source]

Implement PlaceholderCapable ABC.

configure_range(minimum: float, maximum: float) None[source]

Implement RangeConfigurable ABC.

connect_change_signal(callback: Callable[[Any], None]) None[source]

Implement ChangeSignalEmitter ABC.

disconnect_change_signal(callback: Callable[[Any], None]) None[source]

Implement ChangeSignalEmitter ABC.

class pyqt_reactive.protocols.ComboBoxAdapter(*args, **kwargs)[source]

Adapter for QComboBox implementing OpenHCS ABCs.

Stores actual values in itemData, not just display text. Supports enum population and selection.

get_value() Any[source]

Implement ValueGettable ABC.

set_value(value: Any) None[source]

Implement ValueSettable ABC.

set_placeholder(text: str) None[source]

Implement PlaceholderCapable ABC.

populate_enum(enum_type: type) None[source]

Populate combobox with enum values.

Parameters:

enum_type – The Enum class to populate from

connect_change_signal(callback: Callable[[Any], None]) None[source]

Implement ChangeSignalEmitter ABC.

disconnect_change_signal(callback: Callable[[Any], None]) None[source]

Implement ChangeSignalEmitter ABC.

class pyqt_reactive.protocols.CheckBoxAdapter(*args, **kwargs)[source]

Adapter for QCheckBox implementing OpenHCS ABCs.

Returns bool values, treats None as False.

get_value() Any[source]

Implement ValueGettable ABC.

set_value(value: Any) None[source]

Implement ValueSettable ABC.

connect_change_signal(callback: Callable[[Any], None]) None[source]

Implement ChangeSignalEmitter ABC.

disconnect_change_signal(callback: Callable[[Any], None]) None[source]

Implement ChangeSignalEmitter ABC.

class pyqt_reactive.protocols.PlaceholderStateMixin(*args, **kwargs)[source]

Nominal placeholder-state storage for Qt widget adapters.

widget_capabilities: ClassVar[frozenset[WidgetCapability]] = frozenset({WidgetCapability.PLACEHOLDER_STATE})
__init__(*args, **kwargs)[source]
has_placeholder_state() bool[source]

Return whether placeholder chrome or cached placeholder data is present.

mark_placeholder_state() None[source]

Mark the widget as currently displaying placeholder chrome.

clear_placeholder_state() None[source]

Mark the widget as no longer displaying placeholder chrome.

cached_placeholder_text() str | None[source]

Return cached placeholder text, if any.

set_cached_placeholder_text(placeholder_text: str) None[source]

Cache placeholder text after a successful render.

cached_placeholder_resolved_value() Any[source]

Return cached placeholder resolved value, if any.

set_cached_placeholder_resolved_value(value: Any) None[source]

Cache the resolved value after a successful preview render.

clear_placeholder_cache() None[source]

Clear cached placeholder text and resolved value.

class pyqt_reactive.protocols.PyQtWidgetMeta(name, bases, namespace, /, **kwargs)[source]

Metaclass for PyQt widgets that need ABC support.

class pyqt_reactive.protocols.FunctionRegistryProtocol(*args, **kwargs)[source]

Protocol for function registries that provide function lookup and metadata.

Applications can implement this protocol to provide their own function registry.

Example

from pyqt_reactive.protocols import register_function_registry from myapp.registry import MyFunctionRegistry

register_function_registry(MyFunctionRegistry())

get_function_by_name(name: str) Callable | None[source]

Get function by name.

Parameters:

name – Function name to lookup

Returns:

Function callable if found, None otherwise

get_all_functions() Dict[str, Callable][source]

Get all registered functions.

Returns:

Dictionary mapping function names to callables

get_function_metadata(name: str) Dict[str, Any] | None[source]

Get metadata for a function.

Parameters:

name – Function name

Returns:

Metadata dict if available, None otherwise

__init__(*args, **kwargs)
pyqt_reactive.protocols.register_function_registry(registry: FunctionRegistryProtocol) None[source]

Register a function registry implementation.

Parameters:

registry – Object implementing FunctionRegistryProtocol

pyqt_reactive.protocols.get_function_registry() FunctionRegistryProtocol | None[source]

Get the registered function registry.

Returns:

Registered registry or None if not registered

class pyqt_reactive.protocols.PreviewFormatterRegistry[source]

Registry for preview formatters by config type.

Applications can register formatters for specific config types to customize how fields are displayed in list item previews.

Example

from pyqt_reactive.protocols import PreviewFormatterRegistry

def format_zarr_config(config, field_name):
if field_name == ‘compression’:

return f”comp={config.compression[:3]}” # Abbreviate

return str(getattr(config, field_name))

PreviewFormatterRegistry.register(ZarrConfig, format_zarr_config)

classmethod register(config_type: Type, formatter: Callable[[Any, str], str]) None[source]

Register a formatter for a config type.

Parameters:
  • config_type – Config class to format

  • formatter – Formatter function taking (config, field_name) -> str

classmethod get_formatter(config_type: Type) Callable[[Any, str], str] | None[source]

Get formatter for a config type.

Parameters:

config_type – Config class

Returns:

Formatter function if registered, None otherwise

classmethod format_field(config: Any, field_name: str) str | None[source]

Format a field using registered formatter if available.

Parameters:
  • config – Config instance

  • field_name – Field name to format

Returns:

Formatted string if formatter available, None otherwise

pyqt_reactive.protocols.register_preview_formatter(config_type: Type, formatter: Callable[[Any, str], str]) None[source]

Register a preview formatter for a config type.

Parameters:
  • config_type – Config class

  • formatter – Formatter function

class pyqt_reactive.protocols.FormGenConfig(enable_placeholder_styling: bool = True, enable_help_buttons: bool = True, enable_inheritance_tracking: bool = True, custom_widget_factories: Type, ~typing.Any]=<factory>, jedi_project_paths: List[str] = <factory>, log_dir: str | None = None, log_prefixes: List[str] = <factory>, log_root_logger_name: str | None = None, performance_logger_name: str = 'pyqt_reactive.performance', performance_log_filename: str = 'performance.log', path_cache_file: str | None = None)[source]

Base configuration for form generation behavior.

Applications can subclass this to provide custom configuration.

enable_placeholder_styling

Whether to apply special styling to placeholder values

Type:

bool

enable_help_buttons

Whether to show help buttons for fields with docstrings

Type:

bool

enable_inheritance_tracking

Whether to show inheritance source indicators

Type:

bool

custom_widget_factories

Custom widget factories by type

Type:

Dict[Type, Any]

enable_placeholder_styling: bool = True
enable_help_buttons: bool = True
enable_inheritance_tracking: bool = True
custom_widget_factories: Dict[Type, Any]
jedi_project_paths: List[str]
log_dir: str | None = None
log_prefixes: List[str]
log_root_logger_name: str | None = None
performance_logger_name: str = 'pyqt_reactive.performance'
performance_log_filename: str = 'performance.log'
path_cache_file: str | None = None
__init__(enable_placeholder_styling: bool = True, enable_help_buttons: bool = True, enable_inheritance_tracking: bool = True, custom_widget_factories: Type, ~typing.Any]=<factory>, jedi_project_paths: List[str] = <factory>, log_dir: str | None = None, log_prefixes: List[str] = <factory>, log_root_logger_name: str | None = None, performance_logger_name: str = 'pyqt_reactive.performance', performance_log_filename: str = 'performance.log', path_cache_file: str | None = None) None
pyqt_reactive.protocols.set_form_config(config: FormGenConfig) None[source]

Set the global form generation configuration.

Parameters:

config – FormGenConfig instance

pyqt_reactive.protocols.get_form_config() FormGenConfig[source]

Get the current form generation configuration.

Returns:

Current FormGenConfig or default if not set

class pyqt_reactive.protocols.LLMServiceProtocol(*args, **kwargs)[source]

Protocol for LLM services used by LLMChatPanel.

api_endpoint: str
model: str | None
test_connection() Tuple[bool, str][source]

Return (is_connected, status_message).

generate_code(request: str, code_type: str | None = None) str[source]

Generate code for a request and optional code type.

__init__(*args, **kwargs)
pyqt_reactive.protocols.register_llm_service(service: LLMServiceProtocol) None[source]

Register a global LLM service implementation.

pyqt_reactive.protocols.get_llm_service() LLMServiceProtocol | None[source]

Get the registered LLM service implementation.

class pyqt_reactive.protocols.CodegenProvider(*args, **kwargs)[source]

Protocol for code generators used by the simple code editor.

generate_complete_orchestrator_code(plate_paths: list[str], pipeline_data: dict, global_config: Any | None = None, per_plate_configs: dict | None = None, pipeline_config: Any | None = None, clean_mode: bool = True) str[source]
generate_complete_pipeline_steps_code(pipeline_steps: list[Any], clean_mode: bool = True) str[source]
generate_complete_function_pattern_code(func_obj: Any, clean_mode: bool = False) str[source]
generate_config_code(config_obj: Any, clean_mode: bool = True, config_class: type | None = None) str[source]
generate_step_code(step_obj: Any, clean_mode: bool = True) str[source]
__init__(*args, **kwargs)
pyqt_reactive.protocols.register_codegen_provider(provider: CodegenProvider) None[source]

Register a global code generation provider.

pyqt_reactive.protocols.get_codegen_provider() CodegenProvider | None[source]

Get the registered code generation provider.

class pyqt_reactive.protocols.LogDiscoveryProvider(*args, **kwargs)[source]

Protocol for discovering log files and current log path.

get_current_log_path() Path[source]

Return current log file path.

discover_logs(base_log_path: str | None = None, include_main_log: bool = True, log_directory: Path | None = None) List[LogFileInfo][source]

Return discovered logs.

__init__(*args, **kwargs)
class pyqt_reactive.protocols.ServerScanProvider(*args, **kwargs)[source]

Protocol for discovering server logs (e.g., via port scans).

scan_for_server_logs() List[LogFileInfo][source]

Return logs discovered from live servers.

__init__(*args, **kwargs)
pyqt_reactive.protocols.register_log_discovery_provider(provider: LogDiscoveryProvider) None[source]

Register a global log discovery provider.

pyqt_reactive.protocols.get_log_discovery_provider() LogDiscoveryProvider | None[source]

Get the registered log discovery provider.

pyqt_reactive.protocols.register_server_scan_provider(provider: ServerScanProvider) None[source]

Register a global server scan provider.

pyqt_reactive.protocols.get_server_scan_provider() ServerScanProvider | None[source]

Get the registered server scan provider.

class pyqt_reactive.protocols.WindowFactoryProtocol(*args, **kwargs)[source]

Protocol for creating windows for a given scope.

Use this for duck-typed checking. For implementation, prefer WindowFactoryABC.

create_window_for_scope(scope_id: str, object_state: ObjectState | None = None) QWidget | None[source]

Create and show a window for the given scope id.

__init__(*args, **kwargs)
class pyqt_reactive.protocols.WindowFactoryABC[source]

Abstract base class for window factories.

Subclass this to implement application-specific window creation logic. The factory is responsible for: - Parsing scope_id format to determine window type - Creating the appropriate window class - Showing and activating the window

abstractmethod create_window_for_scope(scope_id: str, object_state: ObjectState | None = None) QWidget | None[source]

Create and show a window for the given scope_id.

Parameters:
  • scope_id – Scope identifier. Format is application-specific, e.g.: - “” (empty string): Global config - “/path/to/item”: Item-level config - “/path/to/item::sub”: Nested scope

  • object_state – Optional ObjectState for time-travel restore

Returns:

The created window, or None if creation failed/skipped

pyqt_reactive.protocols.register_window_factory(factory: WindowFactoryProtocol) None[source]

Register a global window factory.

Parameters:

factory – Factory instance implementing WindowFactoryProtocol or WindowFactoryABC

pyqt_reactive.protocols.get_window_factory() WindowFactoryProtocol | None[source]

Get the registered window factory.

class pyqt_reactive.protocols.ComponentSelectionProvider(*args, **kwargs)[source]

Protocol for component selection and display metadata.

get_groupby_enum() Any[source]

Return the GroupBy enum (or compatible enum) used by the host app.

get_component_keys(group_by: Any) List[str][source]

Return available component keys for a given group_by.

has_components_available(group_by: Any) bool[source]

Check if components are available for the given group_by without fetching them all.

Used to determine if UI elements (like component selection buttons) should be enabled. Should return False if the underlying data source (e.g., orchestrator) is not ready.

get_component_display_name(group_by: Any, component_key: str) str | None[source]

Return a human-readable name for a component key.

select_components(available_components: Iterable[str], selected_components: Iterable[str], group_by: Any, parent: Any | None = None, **context: Any) List[str] | None[source]

Show selection UI and return chosen components (or None if canceled).

__init__(*args, **kwargs)
class pyqt_reactive.protocols.FunctionSelectionProvider(*args, **kwargs)[source]

Protocol for selecting a function in UI.

select_function(parent: Any | None = None, **context: Any) Callable | None[source]

Return a selected function or None.

__init__(*args, **kwargs)
pyqt_reactive.protocols.register_component_selection_provider(provider: ComponentSelectionProvider) None[source]

Register a global component selection provider.

pyqt_reactive.protocols.get_component_selection_provider() ComponentSelectionProvider | None[source]

Get the registered component selection provider.

pyqt_reactive.protocols.register_function_selection_provider(provider: FunctionSelectionProvider) None[source]

Register a global function selection provider.

pyqt_reactive.protocols.get_function_selection_provider() FunctionSelectionProvider | None[source]

Get the registered function selection provider.

Modules

codegen_provider

Code generation provider protocol for app-specific code emitters.

component_selection

Component and function selection provider protocols.

form_config

Base configuration class for form generation.

function_registry

Function registry protocol for pluggable function lookup.

llm_service

LLM service protocol for pluggable code generation backends.

log_providers

Protocols for log discovery and server scanning.

preview_formatter

Preview formatter registry for customizable list item previews.

widget_adapters

Widget adapters that wrap Qt widgets to implement OpenHCS ABCs.

widget_protocols

window_factory

Window factory protocol and ABC for creating scope-aware windows.

zmq_server_protocol

ZMQ server protocol abstractions for generic server browser widgets.