hexa
hexa
Summary
Type-declared dependency injection for Python.
Hexa is a pattern and utility library for structuring complex hierarchical
pipelines. It rests on one core idea: a concrete class's annotated slot type
is the dependency decision. Variation is expressed entirely as class
annotations — never as imperative wiring, never as __init__ parameters,
never as a composition root that assembles objects by hand.
All utilities serialize through a single shared model (PortNode):
parse_yaml/generate_yaml— between YAML specs and the modelparse_abc/generate_abc— between ABC Python modules and the modelcheck_matches— verify two representations describe the same treebuild— recursively instantiate a wired pipeline from annotations
Installation
Install using pip:
Quick start
Define contracts, pin concrete types on the slots, and let build wire the
tree from annotations:
CLI usage
Convert between YAML and ABC representations:
Core concepts
Shared model
PortNode — the neutral tree every parser and generator serializes through.
Converters
Parsers and generators that translate between YAML specs and ABC Python modules via the shared model.
Verification
check_matches — machine-check that two representations agree.
Container
build — recursively instantiate a full pipeline from class annotations.
Notes
- All utilities share a single model; any port tree fits.
- Generators emit source text only; hexa performs no runtime code generation.
Classes
MethodSpec
dataclass
Specification of a single abstract method.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Name of the method. |
args |
list[str]
|
Positional parameter names. |
kwargs |
dict[str, str]
|
Keyword-only parameter names mapped to their type expressions. |
PortNode
dataclass
A node in the hexa port tree.
Each node is a leaf (no children), a port (has nested port slots), or the parent root of the tree. Every node carries a concrete typed shape derived from an ABC class name.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Slot name, e.g. |
port_cls |
str
|
ABC class name that gives this port its shape, e.g.
|
kind |
str
|
One of |
attributes |
dict[str, ConfigValue]
|
Annotated attributes: |
children |
list[PortNode]
|
Nested port slots. |
methods |
dict[str, MethodSpec]
|
Abstract methods keyed by method name. |
Functions
diff
Return a list of human-readable difference strings.
An empty list means the trees are equal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other |
PortNode
|
Tree to compare against. |
required |
path |
str
|
Path prefix used when recursing into nested nodes; defaults to the root path. |
''
|
Returns:
| Type | Description |
|---|---|
list[str]
|
list[str]: Human-readable difference strings, one per discrepancy. |
find
Find a direct child by slot name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name |
str
|
Slot name of the child to look up. |
required |
Returns:
| Type | Description |
|---|---|
PortNode | None
|
PortNode | None:
The matching child node, or |
Functions
build
Recursively instantiate the port tree from annotations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cls |
type[T]
|
The root class to build (e.g. |
required |
instances |
dict[str, Any] | None
|
|
None
|
config |
dict[str, Any] | None
|
|
None
|
Returns:
| Name | Type | Description |
|---|---|---|
T |
T
|
A fully wired instance of |