How FabLL (faebryk.core.node) maps Python node/trait declarations into the TypeGraph + instance graph, including field/trait invariants and instantiation patterns. Use when defining new components or traits, working with the Node API, or understanding type registration.
fabll (primarily src/faebryk/core/node.py) is the high-level Python API for defining and working with hardware components. It bridges the gap between Python classes and the underlying TypeGraph and instance graph.
import faebryk.core.faebrykpy as fbrk
import faebryk.core.graph as graph
import faebryk.core.node as fabll
g = graph.GraphView.create()
tg = fbrk.TypeGraph.create(g=g)
class _App(fabll.Node):
pass
app = _App.bind_typegraph(tg=tg).create_instance(g=g)
src/faebryk/core/node.py (Node/Traits/fields, type registration, binding/instantiation helpers)src/faebryk/core/faebrykpy.py (edge types used by FabLL under the hood)src/faebryk/core/graph.py (GraphView wrapper used by instances)src/faebryk/library/): Every component (Resistor, Capacitor, etc.) inherits from Node.Node subclasses dynamically from ato files.Node instances to extract parameters and constraints.fabll.Node is constructed with a graph.BoundNode.SomeType.MakeChild(...)Traits.MakeEdge(SomeTrait.MakeChild().put_on_type()) (or similar)MyType.bind_typegraph(tg).create_instance(g)faebryk.library.*) intentionally have short identifiers (class name) for ato importsNode._register_type)src/faebryk/core/node.py (field system).__init_subclass__).ato dev test --llm test/core/test_node.py -q and ato dev test --llm test/library/test_traits.py -qNode subclasses if they can be a Trait. This allows them to be applied to different component families.Node.__init_subclass__).EdgeTrait.traverse(trait_type=...).MyNode() with no args: instances are created from a bound type via bind_typegraph(...).create_instance(...).import faebryk.core.graph as graph
import faebryk.core.faebrykpy as fbrk
g = graph.GraphView.create()
tg = fbrk.TypeGraph.create(g=g)
inst = MyNode.bind_typegraph(tg).create_instance(g=g)
Node.__init_subclass__ forbids “deeper than one level” inheritance for node types.Node subclasses that typically contain an ImplementsTrait edge.class MyTrait(Node):
is_trait = Traits.MakeEdge(ImplementsTrait.MakeChild().put_on_type())
node_instance.get_trait(TraitType) to retrieve a trait instance. This performs a graph traversal.EdgeComposition. add_child creates this edge. Large trees (10k+ nodes) should be constructed carefully to avoid Python loop overhead; the underlying graph is efficient, but Python interactions cost time.