{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"hexa","text":""},{"location":"#hexa","title":"hexa","text":""},{"location":"#hexa--summary","title":"Summary","text":"

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 \u2014 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):

"},{"location":"#hexa--installation","title":"Installation","text":"

Install using pip:

pip install hexa\n
"},{"location":"#hexa--quick-start","title":"Quick start","text":"

Define contracts, pin concrete types on the slots, and let build wire the tree from annotations:

from hexa import build\n\nclass NumberPort(ABC):\n    @abstractmethod\n    def extract(self, line: str) -> float: ...\n\nclass ParserPort(ABC):\n    number: NumberPort\n\n    @abstractmethod\n    def parse(self, text: str) -> dict: ...\n\nclass RegexNumberPort(NumberPort):\n    def extract(self, line: str) -> float:\n        ...\n\nclass StandardParserPort(ParserPort):\n    number: RegexNumberPort  # <-- the dependency decision\n\n    def parse(self, text: str) -> dict:\n        return {\"value\": self.number.extract(text)}\n\npipeline = build(StandardParserPort)\nprint(pipeline.parse(\"Value: 42\"))\n
"},{"location":"#hexa--cli-usage","title":"CLI usage","text":"

Convert between YAML and ABC representations:

hexa parse-yaml spec.yaml\nhexa generate-abc spec.yaml --out spec_abc.py\nhexa parse-abc spec_abc.py\nhexa generate-yaml spec_abc.py --out spec.yaml\nhexa check spec.yaml spec_abc.py\n
"},{"location":"#hexa--core-concepts","title":"Core concepts","text":""},{"location":"#hexa--shared-model","title":"Shared model","text":"

PortNode \u2014 the neutral tree every parser and generator serializes through.

"},{"location":"#hexa--converters","title":"Converters","text":"

Parsers and generators that translate between YAML specs and ABC Python modules via the shared model.

"},{"location":"#hexa--verification","title":"Verification","text":"

check_matches \u2014 machine-check that two representations agree.

"},{"location":"#hexa--container","title":"Container","text":"

build \u2014 recursively instantiate a full pipeline from class annotations.

"},{"location":"#hexa--notes","title":"Notes","text":""},{"location":"#hexa-classes","title":"Classes","text":""},{"location":"#hexa.MethodSpec","title":"MethodSpec dataclass","text":"
MethodSpec(\n    name: str,\n    args: list[str] = list(),\n    kwargs: dict[str, str] = dict(),\n)\n

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.

"},{"location":"#hexa.PortNode","title":"PortNode dataclass","text":"
PortNode(\n    name: str,\n    port_cls: str,\n    kind: str = \"leaf\",\n    attributes: dict[str, ConfigValue] = dict(),\n    children: list[PortNode] = list(),\n    methods: dict[str, MethodSpec] = dict(),\n)\n

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. \"parser\", \"amount_balance\".

port_cls str

ABC class name that gives this port its shape, e.g. \"TransactionParserPort\". Every port has a concrete typed shape.

kind str

One of \"leaf\", \"port\", or \"parent\". - \"leaf\": no children (e.g. NumberPort) - \"port\": has children (e.g. TransactionParserPort) - \"parent\": the root of the tree (e.g. ExtractionPipeline)

attributes dict[str, ConfigValue]

Annotated attributes: name -> type_expr for scalars, or a nested dict of sub-attributes (a struct) for grouped values.

children list[PortNode]

Nested port slots.

methods dict[str, MethodSpec]

Abstract methods keyed by method name.

"},{"location":"#hexa.PortNode-functions","title":"Functions","text":""},{"location":"#hexa.PortNode.diff","title":"diff","text":"
diff(other: PortNode, path: str = '') -> list[str]\n

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.

"},{"location":"#hexa.PortNode.find","title":"find","text":"
find(name: str) -> PortNode | None\n

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 None if no child has that name.

"},{"location":"#hexa.PortNode.walk","title":"walk","text":"
walk() -> list[PortNode]\n

Return all nodes in depth-first order (self first).

Returns:

Type Description list[PortNode]

list[PortNode]: All nodes of the tree, self first, depth-first.

"},{"location":"#hexa-functions","title":"Functions","text":""},{"location":"#hexa.build","title":"build","text":"
build(\n    cls: type[T],\n    *,\n    instances: dict[str, Any] | None = None,\n    config: dict[str, Any] | None = None\n) -> T\n

Recursively instantiate the port tree from annotations.

Parameters:

Name Type Description Default cls type[T]

The root class to build (e.g. AxisExtractionPipeline).

required instances dict[str, Any] | None

{slot_name: object} injected verbatim into every node whose annotations contain that name (runtime values \u2014 repos, handlers, clients \u2014 that must not be re-constructed). Applied to the whole tree by name.

None config dict[str, Any] | None

{field_name: value} propagated by name to every node's annotated config fields (non-port attributes), replacing the default None.

None

Returns:

Name Type Description T T

A fully wired instance of cls and all its nested ports.

"},{"location":"check_matches/","title":"Check Matches","text":""},{"location":"check_matches/#hexa.check_matches","title":"hexa.check_matches","text":""},{"location":"check_matches/#hexa.check_matches--summary","title":"Summary","text":"

Verify that two hexa representations agree.

check_matches parses two representations \u2014 one YAML spec and/or ABC Python module each \u2014 and reports whether they describe the same port tree.

"},{"location":"check_matches/#hexa.check_matches--notes","title":"Notes","text":""},{"location":"check_matches/#hexa.check_matches-classes","title":"Classes","text":""},{"location":"check_matches/#hexa.check_matches-functions","title":"Functions","text":""},{"location":"check_matches/#hexa.check_matches.check_matches","title":"check_matches","text":"
check_matches(\n    path_a: str | Path, path_b: str | Path\n) -> bool | list[str]\n

Verify two representations agree.

Parameters:

Name Type Description Default path_a str | Path

Path to a .yaml or .py file.

required path_b str | Path

Path to a .yaml or .py file.

required

Returns:

Type Description bool | list[str]

bool | list[str]: True if they match exactly, otherwise a list of difference strings.

"},{"location":"cli/","title":"Cli","text":""},{"location":"cli/#hexa.cli","title":"hexa.cli","text":""},{"location":"cli/#hexa.cli--summary","title":"Summary","text":"

Command-line interface for hexa utilities.

"},{"location":"cli/#hexa.cli--usage","title":"Usage","text":"
hexa parse-yaml PATH\nhexa generate-abc PATH [--out FILE]\nhexa parse-abc PATH\nhexa generate-yaml PATH [--out FILE]\nhexa check PATH_A PATH_B\n
"},{"location":"cli/#hexa.cli-functions","title":"Functions","text":""},{"location":"container/","title":"Container","text":""},{"location":"container/#hexa.container","title":"hexa.container","text":""},{"location":"container/#hexa.container--summary","title":"Summary","text":"

Container to build a wired hexa pipeline from annotations.

build recursively instantiates the port tree implied by a root class's annotations, injecting provided runtime instances and config values by name.

"},{"location":"container/#hexa.container--notes","title":"Notes","text":""},{"location":"container/#hexa.container-functions","title":"Functions","text":""},{"location":"container/#hexa.container.build","title":"build","text":"
build(\n    cls: type[T],\n    *,\n    instances: dict[str, Any] | None = None,\n    config: dict[str, Any] | None = None\n) -> T\n

Recursively instantiate the port tree from annotations.

Parameters:

Name Type Description Default cls type[T]

The root class to build (e.g. AxisExtractionPipeline).

required instances dict[str, Any] | None

{slot_name: object} injected verbatim into every node whose annotations contain that name (runtime values \u2014 repos, handlers, clients \u2014 that must not be re-constructed). Applied to the whole tree by name.

None config dict[str, Any] | None

{field_name: value} propagated by name to every node's annotated config fields (non-port attributes), replacing the default None.

None

Returns:

Name Type Description T T

A fully wired instance of cls and all its nested ports.

"},{"location":"generate_abc/","title":"Generate Abc","text":""},{"location":"generate_abc/#hexa.generate_abc","title":"hexa.generate_abc","text":""},{"location":"generate_abc/#hexa.generate_abc--summary","title":"Summary","text":"

Generate _abc.py source from a hexa PortNode tree.

"},{"location":"generate_abc/#hexa.generate_abc-classes","title":"Classes","text":""},{"location":"generate_abc/#hexa.generate_abc-functions","title":"Functions","text":""},{"location":"generate_abc/#hexa.generate_abc.generate_abc","title":"generate_abc","text":"
generate_abc(\n    node: PortNode, out_path: str | Path | None = None\n) -> str\n

Generate ABC Python source from a :class:PortNode tree.

Parameters:

Name Type Description Default node PortNode

The root of the parsed YAML (or generated) tree.

required out_path str | Path | None

Optional file path to write the generated source to.

None

Returns:

Name Type Description str str

The generated Python source code.

"},{"location":"generate_yaml/","title":"Generate Yaml","text":""},{"location":"generate_yaml/#hexa.generate_yaml","title":"hexa.generate_yaml","text":""},{"location":"generate_yaml/#hexa.generate_yaml--summary","title":"Summary","text":"

Generate YAML spec (nested mapping form) from a hexa PortNode tree.

"},{"location":"generate_yaml/#hexa.generate_yaml-classes","title":"Classes","text":""},{"location":"generate_yaml/#hexa.generate_yaml-functions","title":"Functions","text":""},{"location":"generate_yaml/#hexa.generate_yaml.generate_yaml","title":"generate_yaml","text":"
generate_yaml(\n    node: PortNode, out_path: str | Path | None = None\n) -> str\n

Generate YAML source from a :class:PortNode tree.

Parameters:

Name Type Description Default node PortNode

The root of the tree.

required out_path str | Path | None

Optional file path to write the generated source to.

None

Returns:

Name Type Description str str

The generated YAML source.

"},{"location":"model/","title":"Model","text":""},{"location":"model/#hexa.model","title":"hexa.model","text":""},{"location":"model/#hexa.model--summary","title":"Summary","text":"

Shared neutral model for hexa port trees.

All utilities (parse_yaml, generate_abc, parse_abc, generate_yaml, check_matches) serialize through this single model.

"},{"location":"model/#hexa.model--notes","title":"Notes","text":""},{"location":"model/#hexa.model-classes","title":"Classes","text":""},{"location":"model/#hexa.model.MethodSpec","title":"MethodSpec dataclass","text":"
MethodSpec(\n    name: str,\n    args: list[str] = list(),\n    kwargs: dict[str, str] = dict(),\n)\n

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.

"},{"location":"model/#hexa.model.PortNode","title":"PortNode dataclass","text":"
PortNode(\n    name: str,\n    port_cls: str,\n    kind: str = \"leaf\",\n    attributes: dict[str, ConfigValue] = dict(),\n    children: list[PortNode] = list(),\n    methods: dict[str, MethodSpec] = dict(),\n)\n

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. \"parser\", \"amount_balance\".

port_cls str

ABC class name that gives this port its shape, e.g. \"TransactionParserPort\". Every port has a concrete typed shape.

kind str

One of \"leaf\", \"port\", or \"parent\". - \"leaf\": no children (e.g. NumberPort) - \"port\": has children (e.g. TransactionParserPort) - \"parent\": the root of the tree (e.g. ExtractionPipeline)

attributes dict[str, ConfigValue]

Annotated attributes: name -> type_expr for scalars, or a nested dict of sub-attributes (a struct) for grouped values.

children list[PortNode]

Nested port slots.

methods dict[str, MethodSpec]

Abstract methods keyed by method name.

"},{"location":"model/#hexa.model.PortNode-functions","title":"Functions","text":""},{"location":"model/#hexa.model.PortNode.diff","title":"diff","text":"
diff(other: PortNode, path: str = '') -> list[str]\n

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.

"},{"location":"model/#hexa.model.PortNode.find","title":"find","text":"
find(name: str) -> PortNode | None\n

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 None if no child has that name.

"},{"location":"model/#hexa.model.PortNode.walk","title":"walk","text":"
walk() -> list[PortNode]\n

Return all nodes in depth-first order (self first).

Returns:

Type Description list[PortNode]

list[PortNode]: All nodes of the tree, self first, depth-first.

"},{"location":"parse_abc/","title":"Parse Abc","text":""},{"location":"parse_abc/#hexa.parse_abc","title":"hexa.parse_abc","text":""},{"location":"parse_abc/#hexa.parse_abc--summary","title":"Summary","text":"

Parse an ABC Python module into a hexa PortNode tree.

ABC classes become port nodes. A nested-struct attribute is expressed as a @dataclass annotation on an ABC port (e.g. source: ExtractionSource where ExtractionSource is a @dataclass); the dataclass's fields are expanded into a nested attributes entry.

"},{"location":"parse_abc/#hexa.parse_abc--notes","title":"Notes","text":""},{"location":"parse_abc/#hexa.parse_abc-classes","title":"Classes","text":""},{"location":"parse_abc/#hexa.parse_abc-functions","title":"Functions","text":""},{"location":"parse_abc/#hexa.parse_abc.parse_abc","title":"parse_abc","text":"
parse_abc(module_or_path: str | Path | Any) -> PortNode\n

Parse an ABC Python module into a :class:PortNode tree.

ABC classes become port nodes. A nested-struct attribute is expressed as a @dataclass annotation on an ABC port (e.g. source: ExtractionSource where ExtractionSource is a @dataclass); the dataclass's fields are expanded into a nested attributes entry.

Parameters:

Name Type Description Default module_or_path str | Path | Any

A file path to a .py file, a module import string, or a loaded module.

required

Returns:

Name Type Description PortNode PortNode

The root node of the tree.

"},{"location":"parse_yaml/","title":"Parse Yaml","text":""},{"location":"parse_yaml/#hexa.parse_yaml","title":"hexa.parse_yaml","text":""},{"location":"parse_yaml/#hexa.parse_yaml--summary","title":"Summary","text":"

Parse a hexa YAML spec into a :class:PortNode tree.

The YAML grammar uses a nested mapping format built from three member kinds:

Disambiguation of a mapping value

A mapping with exactly one key whose value is a non-scalar body (a mapping, ..., or a list) is a port. Any other mapping (multiple keys, or all scalar-typed values) is a nested struct of attributes.

"},{"location":"parse_yaml/#hexa.parse_yaml--examples","title":"Examples","text":"

Parse a spec into a port tree:

```python\nfrom hexa import parse_yaml\n\nnode = parse_yaml(\"samples/minimal/sample.yaml\")\nprint(node)\n```\n

The YAML grammar:

```yaml\nRootClassName:\n  attr: type                 # scalar attribute\n  source:                    # nested struct (all scalar sub-attributes)\n    source_type: str\n    bank: str\n  methods:                   # reserved block of functions\n    run:\n      args: [a, b]\n  ingest:                    # port (single non-scalar class key)\n    IngestPort:\n      source_type: str\n      methods: {Method: ...}\n```\n
"},{"location":"parse_yaml/#hexa.parse_yaml--notes","title":"Notes","text":""},{"location":"parse_yaml/#hexa.parse_yaml-classes","title":"Classes","text":""},{"location":"parse_yaml/#hexa.parse_yaml-functions","title":"Functions","text":""},{"location":"parse_yaml/#hexa.parse_yaml.parse_yaml","title":"parse_yaml","text":"
parse_yaml(path: str | Path) -> PortNode\n

Parse a hexa YAML spec file into a :class:PortNode tree.

Parameters:

Name Type Description Default path str | Path

Path to the .yaml file.

required

Returns:

Name Type Description PortNode PortNode

The root node of the parsed tree.

Raises:

Type Description ValueError

On structural errors in the YAML.

"}]}