Files
docs/hexa/wiki/01_overview/index.html

1163 lines
30 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="prev" href="..">
<link rel="next" href="../02_components/">
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.23">
<title>Overview - Hexa Documentation</title>
<link rel="stylesheet" href="../assets/stylesheets/main.84d31ad4.min.css">
<link rel="stylesheet" href="../assets/stylesheets/palette.06af60db.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"JetBrains Mono"}</style>
<link rel="stylesheet" href="https://unpkg.com/dracula-prism/dist/css/dracula-prism.css">
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="slate" data-md-color-primary="blue-grey" data-md-color-accent="teal">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#library-overview" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href=".." title="Hexa Documentation" class="md-header__button md-logo" aria-label="Hexa Documentation" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10.25 2c.19 0 .36.11.44.26l2.22 3.96.09.28-.09.28-2.22 3.96c-.08.15-.25.26-.44.26h-4.5c-.19 0-.36-.11-.44-.26L3.09 6.78 3 6.5l.09-.28 2.22-3.96c.08-.15.25-.26.44-.26zm0 11c.19 0 .36.11.44.26l2.22 3.96.09.28-.09.28-2.22 3.96c-.08.15-.25.26-.44.26h-4.5c-.19 0-.36-.11-.44-.26l-2.22-3.96L3 17.5l.09-.28 2.22-3.96c.08-.15.25-.26.44-.26zm9.25-5.5c.19 0 .36.11.44.26l2.22 3.96.09.28-.09.28-2.22 3.96c-.08.15-.25.26-.44.26H15c-.19 0-.36-.11-.44-.26l-2.22-3.96-.09-.28.09-.28 2.22-3.96c.08-.15.25-.26.44-.26z"/></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Hexa Documentation
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Overview
</span>
</div>
</div>
</div>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg>
</a>
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
<div class="md-search__suggest" data-md-component="search-suggest"></div>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
<div class="md-grid">
<ul class="md-tabs__list">
<li class="md-tabs__item">
<a href=".." class="md-tabs__link">
Home
</a>
</li>
<li class="md-tabs__item md-tabs__item--active">
<a href="./" class="md-tabs__link">
Overview
</a>
</li>
<li class="md-tabs__item">
<a href="../02_components/" class="md-tabs__link">
Core Components
</a>
</li>
<li class="md-tabs__item">
<a href="../03_use_cases/01_yaml_first/" class="md-tabs__link">
Use Cases
</a>
</li>
<li class="md-tabs__item">
<a href="../04_design/" class="md-tabs__link">
Design
</a>
</li>
<li class="md-tabs__item">
<a href="../05_philosophy/" class="md-tabs__link">
Philosophy
</a>
</li>
<li class="md-tabs__item">
<a href="../06_best_practices/" class="md-tabs__link">
Best Practices
</a>
</li>
<li class="md-tabs__item">
<a href="../07_error_handling/" class="md-tabs__link">
Error Handling
</a>
</li>
<li class="md-tabs__item">
<a href="../08_testing_example/" class="md-tabs__link">
Testing
</a>
</li>
</ul>
</div>
</nav>
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary md-nav--lifted md-nav--integrated" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href=".." title="Hexa Documentation" class="md-nav__button md-logo" aria-label="Hexa Documentation" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10.25 2c.19 0 .36.11.44.26l2.22 3.96.09.28-.09.28-2.22 3.96c-.08.15-.25.26-.44.26h-4.5c-.19 0-.36-.11-.44-.26L3.09 6.78 3 6.5l.09-.28 2.22-3.96c.08-.15.25-.26.44-.26zm0 11c.19 0 .36.11.44.26l2.22 3.96.09.28-.09.28-2.22 3.96c-.08.15-.25.26-.44.26h-4.5c-.19 0-.36-.11-.44-.26l-2.22-3.96L3 17.5l.09-.28 2.22-3.96c.08-.15.25-.26.44-.26zm9.25-5.5c.19 0 .36.11.44.26l2.22 3.96.09.28-.09.28-2.22 3.96c-.08.15-.25.26-.44.26H15c-.19 0-.36-.11-.44-.26l-2.22-3.96-.09-.28.09-.28 2.22-3.96c.08-.15.25-.26.44-.26z"/></svg>
</a>
Hexa Documentation
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Overview
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Overview
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#architecture" class="md-nav__link">
<span class="md-ellipsis">
🏗️ Architecture
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#the-three-layers-the-mental-model" class="md-nav__link">
<span class="md-ellipsis">
🔄 The Three Layers (the mental model)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#lifecycle-rules" class="md-nav__link">
<span class="md-ellipsis">
🔄 Lifecycle Rules
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#which-entry-point-should-you-use" class="md-nav__link">
<span class="md-ellipsis">
🧭 Which Entry Point Should You Use?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#read-next" class="md-nav__link">
<span class="md-ellipsis">
➡️ Read Next
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../02_components/" class="md-nav__link">
<span class="md-ellipsis">
Core Components
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_4" >
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0">
<span class="md-ellipsis">
Use Cases
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
Use Cases
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_4_1" >
<label class="md-nav__link" for="__nav_4_1" id="__nav_4_1_label" tabindex="0">
<span class="md-ellipsis">
Contract Authoring
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_4_1_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4_1">
<span class="md-nav__icon md-icon"></span>
Contract Authoring
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../03_use_cases/01_yaml_first/" class="md-nav__link">
<span class="md-ellipsis">
YAML First
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../03_use_cases/02_abc_first/" class="md-nav__link">
<span class="md-ellipsis">
ABC First
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_4_2" >
<label class="md-nav__link" for="__nav_4_2" id="__nav_4_2_label" tabindex="0">
<span class="md-ellipsis">
Wiring
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_4_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4_2">
<span class="md-nav__icon md-icon"></span>
Wiring
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../03_use_cases/03_wiring_runtime/" class="md-nav__link">
<span class="md-ellipsis">
Wiring & Runtime
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../04_design/" class="md-nav__link">
<span class="md-ellipsis">
Design
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../05_philosophy/" class="md-nav__link">
<span class="md-ellipsis">
Philosophy
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../06_best_practices/" class="md-nav__link">
<span class="md-ellipsis">
Best Practices
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../07_error_handling/" class="md-nav__link">
<span class="md-ellipsis">
Error Handling
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../08_testing_example/" class="md-nav__link">
<span class="md-ellipsis">
Testing
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="library-overview">Library Overview<a class="headerlink" href="#library-overview" title="Permanent link">&para;</a></h1>
<p><code>hexa</code> lets you describe a hierarchical pipeline as a tree of typed contracts, then get a fully wired instance back from plain class annotations. This page builds the mental model: the three layers, the two interchangeable representations, and the container that reads annotations at runtime.</p>
<hr />
<h2 id="architecture">🏗️ Architecture<a class="headerlink" href="#architecture" title="Permanent link">&para;</a></h2>
<div class="language-text highlight"><span class="filename">Text Only</span><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a>┌───────────────────────────────────────────────────────────────┐
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a>│ Representation layer (optional, interchangeable) │
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a>│ │
<a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a>│ YAML spec (.yaml) ◄── parse_yaml ──┐ │
<a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a>│ │ │ PortNode tree │
<a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a>│ │ generate_abc │ (the single model) │
<a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a>│ ▼ ▼ │
<a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a>│ ABC module (_abc.py) ◄─ generate_yaml ─┐ │
<a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a>│ (contracts only: ABC + annotations) │ │
<a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a>└──────────────────────────────────────────┼────────────────────┘
<a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a>
<a id="__codelineno-0-12" name="__codelineno-0-12" href="#__codelineno-0-12"></a>┌──────────────────────────────────────────┼────────────────────┐
<a id="__codelineno-0-13" name="__codelineno-0-13" href="#__codelineno-0-13"></a>│ Runtime layer (annotations are decision)▼ │
<a id="__codelineno-0-14" name="__codelineno-0-14" href="#__codelineno-0-14"></a>│ │
<a id="__codelineno-0-15" name="__codelineno-0-15" href="#__codelineno-0-15"></a>│ root class ── build(cls, instances=, config=) ──► wired │
<a id="__codelineno-0-16" name="__codelineno-0-16" href="#__codelineno-0-16"></a>│ (e.g. ImplParentClass) instance │
<a id="__codelineno-0-17" name="__codelineno-0-17" href="#__codelineno-0-17"></a>│ │ __annotations__ merged across MRO │
<a id="__codelineno-0-18" name="__codelineno-0-18" href="#__codelineno-0-18"></a>│ ▼ │
<a id="__codelineno-0-19" name="__codelineno-0-19" href="#__codelineno-0-19"></a>│ recursively: instantiate pinned concrete port, setattr on │
<a id="__codelineno-0-20" name="__codelineno-0-20" href="#__codelineno-0-20"></a>│ parent, inject runtime instances / config values by name │
<a id="__codelineno-0-21" name="__codelineno-0-21" href="#__codelineno-0-21"></a>└───────────────────────────────────────────────────────────────┘
</code></pre></div>
<p>Two layers, deliberately decoupled:</p>
<ol>
<li><strong>Representation</strong> — the <em>same contract</em> can be written as a YAML spec or as a Python ABC module. hexa's converters translate between them through one neutral <code>PortNode</code> tree. This layer is <strong>optional</strong>: you may hand-write only the ABC file, only the YAML, or both.</li>
<li><strong>Runtime</strong><code>build(cls)</code> reads the merged annotations of a root class. Every port slot annotated with a concrete type <em>is</em> the decision; the container instantiates the tree recursively and <code>setattr</code>s each child onto its parent.</li>
</ol>
<hr />
<h2 id="the-three-layers-the-mental-model">🔄 The Three Layers (the mental model)<a class="headerlink" href="#the-three-layers-the-mental-model" title="Permanent link">&para;</a></h2>
<p>Whatever you author, the pattern is built from three fixed layers:</p>
<table>
<thead>
<tr>
<th>Layer</th>
<th>Example file</th>
<th>Role</th>
</tr>
</thead>
<tbody>
<tr>
<td>1. <strong>ABC contracts</strong></td>
<td><code>samples/minimal/abc.py</code></td>
<td><em>Declaration of need</em> — attributes, port slots, <code>@abstractmethod</code> bodies. Never runs.</td>
</tr>
<tr>
<td>2. <strong>Generic <code>Impl*</code> / concrete defaults</strong></td>
<td><code>samples/minimal/impl.py</code></td>
<td><em>Shared behavior</em> — subclasses the ABC, implements every <code>@abstractmethod</code>, <strong>re-pins</strong> slots to concrete types.</td>
</tr>
<tr>
<td>3. <strong>Specialization (optional)</strong></td>
<td><code>samples/extraction_pipeline/banks/{axis,icici}/pdf.py</code></td>
<td><em>Variation</em> — overrides only the members that differ from <code>Impl*</code>.</td>
</tr>
</tbody>
</table>
<blockquote>
<p>The root class you hand to <code>build</code> is always a concrete type (layer 2 or 3). The ABC (layer 1) is only a contract — it is never instantiated.</p>
</blockquote>
<hr />
<h2 id="lifecycle-rules">🔄 Lifecycle Rules<a class="headerlink" href="#lifecycle-rules" title="Permanent link">&para;</a></h2>
<table>
<thead>
<tr>
<th>Step</th>
<th>Call</th>
<th>Why</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Author the contract</td>
<td>As YAML (<code>.yaml</code>) or ABC (<code>_abc.py</code>) — or both, and let <code>check_matches</code> prove they agree.</td>
</tr>
<tr>
<td>2</td>
<td>Generate one from the other (optional)</td>
<td><code>generate_abc(spec.yaml)</code> when you want ABCs from YAML; <code>generate_yaml(abc.py)</code> for the reverse.</td>
</tr>
<tr>
<td>3</td>
<td>Write concrete implementations (<code>Impl*</code>)</td>
<td>Subclass the ABC, implement abstracts, pin each slot to a concrete port type.</td>
</tr>
<tr>
<td>4</td>
<td>Wire</td>
<td><code>build(ImplRoot, instances={"repo": repo}, config={"retries": 3})</code>.</td>
</tr>
<tr>
<td>5</td>
<td>Verify (optional)</td>
<td><code>check_matches(spec.yaml, abc.py)</code> returns <code>True</code> or a list of difference strings.</td>
</tr>
</tbody>
</table>
<p>Steps 13 choose <em>what</em> the pipeline needs; step 4 is automatic. Variation between pipelines happens purely by which root class you build.</p>
<hr />
<h2 id="which-entry-point-should-you-use">🧭 Which Entry Point Should You Use?<a class="headerlink" href="#which-entry-point-should-you-use" title="Permanent link">&para;</a></h2>
<table>
<thead>
<tr>
<th>Entry point</th>
<th>Use when</th>
<th>Adds</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>parse_yaml(path)</code></td>
<td>You author specs in YAML</td>
<td>YAML → <code>PortNode</code> tree (structural validation only)</td>
</tr>
<tr>
<td><code>generate_abc(node)</code></td>
<td>You want ABC source from a spec</td>
<td>YAML model → Python ABC module source</td>
</tr>
<tr>
<td><code>parse_abc(mod)</code></td>
<td>You author contracts in Python</td>
<td>ABC module → <code>PortNode</code> tree (reflection)</td>
</tr>
<tr>
<td><code>generate_yaml(node)</code></td>
<td>You want a spec for your ABCs</td>
<td>Python ABC module → YAML source</td>
</tr>
<tr>
<td><code>check_matches(a, b)</code></td>
<td>You keep both representations</td>
<td>Verifies the two trees agree; prints diffs</td>
</tr>
<tr>
<td><code>build(cls, ...)</code></td>
<td>You want a wired runtime instance</td>
<td>Recursively instantiates the port tree from annotations</td>
</tr>
</tbody>
</table>
<hr />
<h2 id="read-next">➡️ Read Next<a class="headerlink" href="#read-next" title="Permanent link">&para;</a></h2>
<ul>
<li><a href="../02_components/">Core Components</a> — the public API surface in detail.</li>
<li><a href="../03_use_cases/01_yaml_first/">Use case 01 YAML first</a> — the minimal spec-to-ABC workflow.</li>
<li><a href="../05_philosophy/">Philosophy</a> — the <em>why</em> behind type-declared dependencies.</li>
</ul>
</article>
</div>
<script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
Back to top
</button>
</main>
<footer class="md-footer">
<nav class="md-footer__inner md-grid" aria-label="Footer" >
<a href=".." class="md-footer__link md-footer__link--prev" aria-label="Previous: Home">
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</div>
<div class="md-footer__title">
<span class="md-footer__direction">
Previous
</span>
<div class="md-ellipsis">
Home
</div>
</div>
</a>
<a href="../02_components/" class="md-footer__link md-footer__link--next" aria-label="Next: Core Components">
<div class="md-footer__title">
<span class="md-footer__direction">
Next
</span>
<div class="md-ellipsis">
Core Components
</div>
</div>
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg>
</div>
</a>
</nav>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "..", "features": ["navigation.tabs", "navigation.expand", "navigation.sections", "navigation.footer", "navigation.top", "navigation.instant", "toc.integrate", "content.code.annotate", "content.code.copy", "content.code.select", "content.code.line_numbers", "content.tabs.link", "content.tooltips", "content.action.edit", "search.suggest", "search.highlight", "search.share", "header.autohide", "announce.dismiss", "footer.social"], "search": "../assets/javascripts/workers/search.973d3a69.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.f55a23d4.min.js"></script>
</body>
</html>