warehouse-fullSpxContainer – the “smart loader” that wires your sub-components

If SpxComponent is a node, SpxContainer is a factory that fills the node with the right children the moment it is born.

1 · Why do we need a Container?

Most SPX objects are themselves collections:

  • an attributes block is a set of SpxAttributes,

  • an actions block is a set of Actions,

  • a conditions block is a set of Conditions or IfChains,

  • even a high-level device model is “just” a bag of attributes, actions, hooks and nested models.

Manually instantiating every child would be tedious and error-prone.

SpxContainer automates that work:

  • reads a YAML / dict definition,

  • looks up each key in the registry,

  • instantiates the matching class (or a filtered base type),

  • connects the new instance to the parent tree.

You write concise YAML/JSON/Python Dict; SPX builds a full object graph ready for simulation.

Constructor & API

from spx_sdk.components import SpxComponent, SpxContainer, SpxItem

cont = SpxContainer(
    name: str,             # a label for this container node
    definition: Any,       # dict-or-list-based structure
    parent: SpxComponent,  # optional parent in your component tree
    type: Optional[type]   # optionally filter to only instantiate subclasses of this base
)

Generic Mode Examples

Filtered Mode Examples

Edge Cases & Fallbacks

  1. Unknown key in generic dict → ValueError

  2. Multi-key dict in list → wrapped in SpxItemnever raises)

  3. Filtered mode but base class not registered → ValueError immediately

  4. Filtered list: the first matching subclass is used; if none matches, fallback once to the base itself

Tips & Best Practices

  • Always register your custom SpxItem subclasses with a unique @register_class(name="…").

  • Use filtered mode to pull out a certain category of items (e.g. only Action classes under a “logic” block).

  • Keep nested logic in your child definitions – SpxContainer never recurses beyond the top level of definition.

Last updated