Common Utilities API Reference¶
Timebase¶
mycorrhizal.common.timebase ¶
Blackboard Interfaces¶
mycorrhizal.common.interfaces ¶
Blackboard Interface System
This module provides Protocol-based interfaces for type-safe, constrained access to blackboard state across Mycorrhizal's three DSL systems (Hypha, Rhizomorph, Septum).
Key concepts: - Protocols: Structural subtyping for interface definitions - Wrappers: Runtime enforcement of access constraints - Composition: Combine multiple interfaces into larger ones
Readable ¶
Bases: Protocol[T]
Protocol for read-only access to a typed value.
This protocol provides structural subtyping - any class with a matching
get_value() method will satisfy this protocol.
Class Type Parameters:
| Name | Bound or Constraints | Description | Default |
|---|---|---|---|
T
|
The type of value being read |
required |
Example
class Config: ... def get_value(self) -> int: ... return 42 config: Readable[int] = Config() isinstance(config, Readable) True
Writable ¶
Bases: Protocol[T]
Protocol for write access to a typed value.
This protocol provides structural subtyping - any class with a matching
set_value() method will satisfy this protocol.
Class Type Parameters:
| Name | Bound or Constraints | Description | Default |
|---|---|---|---|
T
|
The type of value being written |
required |
Example
class Storage: ... def set_value(self, value: int) -> None: ... self._value = value storage: Writable[int] = Storage() isinstance(storage, Writable) True
FieldAccessor ¶
Bases: Readable[T], Writable[T], Protocol[T]
Protocol for read/write access to a typed value.
Combines both Readable and Writable protocols for full access.
Class Type Parameters:
| Name | Bound or Constraints | Description | Default |
|---|---|---|---|
T
|
The type of value being accessed |
required |
Example
class Counter: ... def get_value(self) -> int: ... return self._count ... def set_value(self, value: int) -> None: ... self._count = value counter: FieldAccessor[int] = Counter() isinstance(counter, FieldAccessor) True
BlackboardProtocol ¶
Bases: Protocol
Base blackboard protocol that all blackboards should implement.
This protocol provides structural subtyping for blackboard-like objects. Any class with matching methods will satisfy this protocol, no inheritance required.
Required Methods
validate(): Check if blackboard state is valid to_dict(): Convert blackboard to dictionary representation
Example
class MyBlackboard: ... def validate(self) -> bool: ... return True ... def to_dict(self) -> dict[str, Any]: ... return {"data": 42} bb: BlackboardProtocol = MyBlackboard() isinstance(bb, BlackboardProtocol) True
FieldMetadata
dataclass
¶
Metadata for blackboard interface fields.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Field name |
type |
type
|
Field type annotation |
readonly |
bool
|
Whether field is read-only |
required |
bool
|
Whether field is required (not Optional) |
InterfaceMetadata
dataclass
¶
InterfaceMetadata(name: str, fields: dict[str, FieldMetadata] = dict(), description: Optional[str] = None, bases: tuple[type, ...] = tuple())
Metadata for a blackboard interface.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Interface name |
fields |
dict[str, FieldMetadata]
|
Dictionary of field metadata by field name |
description |
Optional[str]
|
Optional description of the interface |
bases |
tuple[type, ...]
|
Base interfaces this interface extends |
_extract_interface_metadata ¶
_extract_interface_metadata(interface_class: type, readonly_fields: set[str] | None = None, readwrite_fields: set[str] | None = None) -> InterfaceMetadata
Extract metadata from an interface class.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
interface_class
|
type
|
The interface class to analyze |
required |
readonly_fields
|
set[str] | None
|
Set of field names that are read-only |
None
|
readwrite_fields
|
set[str] | None
|
Set of field names that are read-write |
None
|
Returns:
| Type | Description |
|---|---|
InterfaceMetadata
|
InterfaceMetadata with extracted information |
Source code in src/mycorrhizal/common/interfaces.py
get_interface_fields ¶
Extract field type annotations from an interface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
interface
|
type
|
The interface class to extract fields from |
required |
Returns:
| Type | Description |
|---|---|
dict[str, type]
|
Dictionary mapping field names to their types |
Example
class MyInterface(Protocol): ... counter: int ... name: str get_interface_fields(MyInterface)
Source code in src/mycorrhizal/common/interfaces.py
create_interface_from_model ¶
create_interface_from_model(model_class: type, readonly_fields: set[str] | None = None) -> type[Protocol]
Create a Protocol interface from a Pydantic model or dataclass.
This is a utility function for automatically generating interfaces from existing model classes, supporting gradual migration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_class
|
type
|
The model class to create interface from |
required |
readonly_fields
|
set[str] | None
|
Optional set of field names that should be read-only |
None
|
Returns:
| Type | Description |
|---|---|
type[Protocol]
|
A Protocol class with the same fields as the model |
Example
from pydantic import BaseModel class TaskModel(BaseModel): ... max_tasks: int ... tasks_completed: int TaskInterface = create_interface_from_model( ... TaskModel, ... readonly_fields={'max_tasks'} ... ) get_interface_fields(TaskInterface)
Source code in src/mycorrhizal/common/interfaces.py
Runtime Wrappers¶
mycorrhizal.common.wrappers ¶
Blackboard Wrapper Classes for Constrained Access
This module provides wrapper classes that enforce interface constraints at runtime, enabling type-safe, constrained access to blackboard state.
Key concepts: - ReadOnlyView: Enforces read-only access to specified fields - WriteOnlyView: Enforces write-only access to specified fields - ConstrainedView: Provides access to subset of fields with permissions - CompositeView: Combines multiple views into single interface
AccessControlError ¶
BaseWrapper ¶
Base class for all wrapper classes.
Provides common functionality for attribute access interception and error handling.
Initialize the wrapper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bb
|
Any
|
The underlying blackboard object |
required |
allowed_fields
|
Set[str]
|
Set of field names that can be accessed |
required |
private_attrs
|
Optional[Dict[str, Any]]
|
Optional dict of private attributes for the wrapper itself |
None
|
Source code in src/mycorrhizal/common/wrappers.py
__getattr__ ¶
Get attribute from underlying blackboard
Source code in src/mycorrhizal/common/wrappers.py
__setattr__ ¶
Set attribute on underlying blackboard (to be overridden by subclasses)
Source code in src/mycorrhizal/common/wrappers.py
__dir__ ¶
__repr__ ¶
Return string representation
ReadOnlyView ¶
Bases: BaseWrapper, Generic[T]
Read-only view of specific blackboard fields.
Provides read access to specified fields while preventing any modifications. Useful for creating safe, immutable views of shared state.
Class Type Parameters:
| Name | Bound or Constraints | Description | Default |
|---|---|---|---|
T
|
The type of the interface being viewed |
required |
Example
class Blackboard: ... def init(self): ... self.config_value = 42 ... self.mutable_state = 0 bb = Blackboard() view = ReadOnlyView(bb, {'config_value'}) view.config_value # Read works 42 view.config_value = 100 # Write raises AttributeError: Field 'config_value' is read-only
Source code in src/mycorrhizal/common/wrappers.py
__setattr__ ¶
Prevent all modifications
Source code in src/mycorrhizal/common/wrappers.py
WriteOnlyView ¶
Bases: BaseWrapper, Generic[T]
Write-only view of specific blackboard fields.
Provides write access to specified fields while preventing reads. Useful for output interfaces and sinks.
Class Type Parameters:
| Name | Bound or Constraints | Description | Default |
|---|---|---|---|
T
|
The type of the interface being viewed |
required |
Example
class Blackboard: ... def init(self): ... self.output_value = None bb = Blackboard() view = WriteOnlyView(bb, {'output_value'}) view.output_value = 42 # Write works value = view.output_value # Read raises AttributeError: Field 'output_value' is write-only (cannot read)
Source code in src/mycorrhizal/common/wrappers.py
__getattr__ ¶
Prevent reads
Source code in src/mycorrhizal/common/wrappers.py
__setattr__ ¶
Allow writes to specified fields
Source code in src/mycorrhizal/common/wrappers.py
ConstrainedView ¶
ConstrainedView(bb: Any, allowed_fields: Set[str], readonly_fields: Set[str] | None = None, private_attrs: Optional[Dict[str, Any]] = None)
Bases: BaseWrapper, Generic[T, P]
Constrained access view for interface-based access.
Provides access to a subset of fields with specified permissions. Read-only fields cannot be modified, read-write fields can be both read and written.
Class Type Parameters:
| Name | Bound or Constraints | Description | Default |
|---|---|---|---|
T
|
The type of the interface being viewed |
required | |
P
|
The Protocol type that defines the interface |
required |
Example
from mycorrhizal.common.wrappers import ConstrainedView class Blackboard: ... def init(self): ... self.max_tasks = 10 ... self.tasks_completed = 0 bb = Blackboard() view = ConstrainedView( ... bb, ... allowed_fields={'max_tasks', 'tasks_completed'}, ... readonly_fields={'max_tasks'} ... ) view.max_tasks # Read works 10 view.max_tasks = 20 # Write raises (read-only) AttributeError: Field 'max_tasks' is read-only view.tasks_completed = 5 # Write works (read-write) view.tasks_completed # Read works 5
Initialize the constrained view.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bb
|
Any
|
The underlying blackboard object |
required |
allowed_fields
|
Set[str]
|
Set of field names that can be accessed |
required |
readonly_fields
|
Set[str] | None
|
Set of field names that are read-only |
None
|
private_attrs
|
Optional[Dict[str, Any]]
|
Optional dict of private attributes for the wrapper itself |
None
|
Source code in src/mycorrhizal/common/wrappers.py
__getattr__ ¶
Get attribute from underlying blackboard
Source code in src/mycorrhizal/common/wrappers.py
__setattr__ ¶
Set attribute with read-only enforcement
Source code in src/mycorrhizal/common/wrappers.py
CompositeView ¶
CompositeView(bb: Any, views: list[BaseWrapper])
Bases: BaseWrapper, Generic[T]
Combines multiple views into a single interface.
Allows composing multiple constrained views into one, enabling complex access patterns by combining simpler views.
Class Type Parameters:
| Name | Bound or Constraints | Description | Default |
|---|---|---|---|
T
|
The type of the composite interface |
required |
Example
config_view = ReadOnlyView(bb, {'max_tasks'}) state_view = ConstrainedView(bb, {'tasks_completed'}, readonly_fields=set()) composite = CompositeView.combine([config_view, state_view]) composite.max_tasks # Read from config_view 10 composite.tasks_completed = 5 # Write through state_view composite.max_tasks = 20 # Raises (read-only) AttributeError: Field 'max_tasks' is read-only
Initialize composite view from multiple views.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bb
|
Any
|
The underlying blackboard object |
required |
views
|
list[BaseWrapper]
|
List of wrapper objects to compose |
required |
Source code in src/mycorrhizal/common/wrappers.py
combine
classmethod
¶
combine(views: list[BaseWrapper]) -> CompositeView[T]
Combine multiple views into a composite view.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
views
|
list[BaseWrapper]
|
List of wrapper objects to combine |
required |
Returns:
| Type | Description |
|---|---|
CompositeView[T]
|
A new CompositeView that combines all input views |
Raises:
| Type | Description |
|---|---|
ValueError
|
If views reference different blackboards |
Source code in src/mycorrhizal/common/wrappers.py
__getattr__ ¶
Delegate read to first view that has this field
Source code in src/mycorrhizal/common/wrappers.py
__setattr__ ¶
Delegate write to first view that has this field
Source code in src/mycorrhizal/common/wrappers.py
create_readonly_view ¶
create_readonly_view(bb: Any, fields: tuple[str, ...]) -> ReadOnlyView
Create a read-only view.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bb
|
Any
|
The blackboard to wrap |
required |
fields
|
tuple[str, ...]
|
Tuple of field names for read-only access |
required |
Returns:
| Type | Description |
|---|---|
ReadOnlyView
|
A ReadOnlyView instance |
Example
view = create_readonly_view(bb, ('config', 'max_tasks'))
Source code in src/mycorrhizal/common/wrappers.py
create_constrained_view ¶
create_constrained_view(bb: Any, allowed_fields: tuple[str, ...], readonly_fields: tuple[str, ...] = ()) -> ConstrainedView
Create a constrained view.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bb
|
Any
|
The blackboard to wrap |
required |
allowed_fields
|
tuple[str, ...]
|
Tuple of field names that can be accessed |
required |
readonly_fields
|
tuple[str, ...]
|
Tuple of field names that are read-only |
()
|
Returns:
| Type | Description |
|---|---|
ConstrainedView
|
A ConstrainedView instance |
Example
view = create_constrained_view( ... bb, ... ('max_tasks', 'tasks_completed'), ... ('max_tasks',) ... )
Source code in src/mycorrhizal/common/wrappers.py
create_view_from_protocol ¶
create_view_from_protocol(bb: Any, protocol: Type[P], readonly_fields: Set[str] | None = None) -> ConstrainedView
Create a constrained view from a Protocol interface.
Extracts field information from the Protocol and creates a view that enforces the interface constraints.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bb
|
Any
|
The blackboard to wrap |
required |
protocol
|
Type[P]
|
The Protocol class defining the interface |
required |
readonly_fields
|
Set[str] | None
|
Optional set of field names that should be read-only. If not provided, will try to extract from protocol metadata. |
None
|
Returns:
| Type | Description |
|---|---|
ConstrainedView
|
A ConstrainedView instance |
Example
class TaskInterface(Protocol): ... max_tasks: int ... tasks_completed: int view = create_view_from_protocol(bb, TaskInterface, {'max_tasks'})
Source code in src/mycorrhizal/common/wrappers.py
View ¶
Factory function for creating typed views from protocols.
This provides a clean, type-safe API for creating constrained views with full type hint support.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bb
|
Any
|
The blackboard to wrap |
required |
protocol
|
Type[P]
|
The Protocol class defining the interface |
required |
Returns:
| Type | Description |
|---|---|
Any
|
A wrapper that implements the protocol |
Example
class ConfigInterface(Protocol): ... max_tasks: int ... interval: float view: ConfigInterface = View(bb, ConfigInterface)
Type checker knows view has max_tasks and interval¶
Source code in src/mycorrhizal/common/wrappers.py
Interface Builder¶
mycorrhizal.common.interface_builder ¶
Interface Builder DSL for Blackboard Interfaces
This module provides a declarative DSL for defining blackboard interfaces using PEP 593 Annotated types and access control markers.
Key concepts: - @blackboard_interface - Decorator for defining interfaces - readonly/readwrite markers for field access control - Annotated types for clean, Pythonic field definitions
_AccessMarker ¶
Base class for access control markers
readonly ¶
Bases: _AccessMarker
Marker for readonly fields in blackboard interfaces.
Fields marked as readonly can be read but not modified through the interface.
readwrite ¶
Bases: _AccessMarker
Marker for readwrite fields in blackboard interfaces.
Fields marked as readwrite can be both read and modified through the interface.
FieldSpec
dataclass
¶
FieldSpec(name: str, type: type, readonly: bool = False, computed: bool = False, computation: Optional[callable] = None)
Specification for a field in an interface
blackboard_interface ¶
Decorator for defining blackboard interfaces using Annotated types.
Processes class annotations looking for Annotated types with readonly or readwrite markers, and generates a Protocol class with access control metadata.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cls
|
Type[T] | None
|
The class being decorated |
None
|
name
|
str | None
|
Optional name for the generated interface |
None
|
Returns:
| Type | Description |
|---|---|
Any
|
A Protocol class with type hints and metadata |
Example
Fields without Annotated markers are treated as readwrite by default.
Source code in src/mycorrhizal/common/interface_builder.py
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | |