Skip to content

symfonic.cli.components

components

Component catalog for the symfonic init scaffolder.

Each component maps to a set of path prefixes (relative to the generated project root). When a component is not selected, every file whose path starts with one of those prefixes is skipped during generation.

The "fastapi" component is the kernel -- it cannot be removed in isolation because every other backend component depends on it. The CLI treats it as implicitly included whenever at least one server-side component is requested.

Domain examples are self-describing, not hardcoded here. The scaffolder ships one default domain (app/domains/starter/) plus zero or more selectable example domains. A selectable domain declares itself with a _scaffold.json manifest in its own template folder (app/domains/<name>/_scaffold.json); this module discovers those manifests at import and turns each into a component. Adding a new example domain is therefore a matter of dropping a folder + manifest into the templates tree -- no edit to this file (or the CLI) is required, and no specific example name lives in the CLI code.

domain_components

domain_components() -> dict[str, dict]

Return the discovered domain-example components keyed by component name.

The scaffolder uses this to set per-domain Jinja flags, enforce mutual-exclusion with the default starter domain, and label next steps -- all without naming any specific domain in the CLI code.

Source code in src/symfonic/cli/components.py
def domain_components() -> dict[str, dict]:
    """Return the discovered domain-example components keyed by component name.

    The scaffolder uses this to set per-domain Jinja flags, enforce
    mutual-exclusion with the default starter domain, and label next steps --
    all without naming any specific domain in the CLI code.
    """
    return dict(_DOMAINS)

files_for_components

files_for_components(components: list[str]) -> set[str]

Return the set of path prefixes that are active for components.

A generated file should be written when its path starts with at least one prefix in the returned set. The "fastapi" kernel has no excluded prefixes, so it is implicitly always active.

This is used by the scaffolder to decide whether to emit a template.

Source code in src/symfonic/cli/components.py
def files_for_components(components: list[str]) -> set[str]:
    """Return the set of path *prefixes* that are active for *components*.

    A generated file should be written when its path starts with at least
    one prefix in the returned set.  The "fastapi" kernel has no excluded
    prefixes, so it is implicitly always active.

    This is used by the scaffolder to decide whether to emit a template.
    """
    active: set[str] = set()
    for component in components:
        for prefix in _COMPONENT_PREFIXES.get(component, []):
            active.add(prefix)
    return active

validate_components

validate_components(components: list[str]) -> list[str]

Return components unchanged or raise ValueError on unknown names.

Parameters:

Name Type Description Default
components list[str]

Component names provided by the caller.

required

Returns:

Type Description
list[str]

The validated list (same object).

Raises:

Type Description
ValueError

When any name is not in ALL_COMPONENTS.

Source code in src/symfonic/cli/components.py
def validate_components(components: list[str]) -> list[str]:
    """Return *components* unchanged or raise ``ValueError`` on unknown names.

    Args:
        components: Component names provided by the caller.

    Returns:
        The validated list (same object).

    Raises:
        ValueError: When any name is not in ``ALL_COMPONENTS``.
    """
    known = set(ALL_COMPONENTS)
    unknown = [c for c in components if c not in known]
    if unknown:
        raise ValueError(f"Unknown component(s): {unknown}. Valid components: {ALL_COMPONENTS}")
    return components