Skip to content

symfonic.cli.examples

examples

symfonic examples -- copy a runnable example into the user's project.

Examples are not importable modules shipped in the wheel; they are bundled as data under symfonic/cli/example_data/ (via a build-time hatch force-include mapping the repo-root examples/ tree). This command copies a curated example out into the caller's working directory so an installed-only consumer -- someone who ran pip install symfonic-core and never cloned the repo -- can run it in seconds, without us shipping the whole codebase inside the package.

Two resolution roots are supported so the command behaves identically in a wheel install and in a source checkout / editable install:

  1. Packaged data -- symfonic/cli/example_data/ (present in built wheels).
  2. Repo checkout fallback -- the sibling examples/ tree at the repo root (present in editable installs and when running the tests).

Both roots carry the same relative layout for the curated set, so the :data:CURATED specs resolve against either without branching.

ExampleSpec dataclass

ExampleSpec(
    name: str,
    summary: str,
    run: str,
    srcdir: str | None = None,
    srcfile: str | None = None,
    requires: str | None = None,
)

A curated, copy-out example.

srcdir and srcfile are mutually exclusive and are given relative to the resolved examples root. Exactly one must be set.

requires class-attribute instance-attribute

requires: str | None = None

Human note on prerequisites (extra + credentials), or None for a base-install example that runs on MockModelProvider.

ExamplesError

Bases: RuntimeError

Raised when an example cannot be listed or copied.

add_example

add_example(
    name: str,
    dest_dir: Path,
    *,
    root: Path | None = None,
    force: bool = False,
) -> Path

Copy the curated example name into dest_dir/<name>/.

Returns the created target directory. Raises :class:ExamplesError for an unknown name, a missing source, or an existing target when force is False.

Source code in src/symfonic/cli/examples.py
def add_example(
    name: str,
    dest_dir: Path,
    *,
    root: Path | None = None,
    force: bool = False,
) -> Path:
    """Copy the curated example ``name`` into ``dest_dir/<name>/``.

    Returns the created target directory. Raises :class:`ExamplesError` for an
    unknown name, a missing source, or an existing target when ``force`` is
    False.
    """
    spec = CURATED.get(name)
    if spec is None:
        known = ", ".join(CURATED)
        raise ExamplesError(
            f"Unknown example {name!r}. Available: {known}. "
            "Run 'symfonic examples list' to see them."
        )

    src_root = root if root is not None else resolve_examples_root()
    target = dest_dir / name

    if target.exists():
        if not force:
            raise ExamplesError(
                f"{target} already exists. Pass --force to overwrite."
            )
        shutil.rmtree(target)

    if spec.srcdir is not None:
        source = src_root / spec.srcdir
        if not source.is_dir():
            raise ExamplesError(f"Example source not found: {source}")
        shutil.copytree(source, target, ignore=_IGNORE)
    else:
        assert spec.srcfile is not None  # guaranteed by __post_init__
        source = src_root / spec.srcfile
        if not source.is_file():
            raise ExamplesError(f"Example source not found: {source}")
        target.mkdir(parents=True, exist_ok=True)
        shutil.copy2(source, target / source.name)

    return target

available_examples

available_examples() -> list[ExampleSpec]

Return the curated examples in stable declaration order.

Source code in src/symfonic/cli/examples.py
def available_examples() -> list[ExampleSpec]:
    """Return the curated examples in stable declaration order."""
    return list(CURATED.values())

resolve_examples_root

resolve_examples_root() -> Path

Locate the directory that holds the curated example sources.

Prefers the packaged example_data (wheel installs); falls back to the repo-root examples/ tree (editable installs / source checkouts).

Source code in src/symfonic/cli/examples.py
def resolve_examples_root() -> Path:
    """Locate the directory that holds the curated example sources.

    Prefers the packaged ``example_data`` (wheel installs); falls back to the
    repo-root ``examples/`` tree (editable installs / source checkouts).
    """
    packaged = resources.files("symfonic.cli").joinpath("example_data")
    try:
        if packaged.is_dir():
            return Path(str(packaged))
    except (FileNotFoundError, ModuleNotFoundError):  # pragma: no cover
        pass

    cli_dir = Path(str(resources.files("symfonic.cli"))).resolve()
    # cli_dir == <repo>/src/symfonic/cli  ->  parents[2] == <repo>
    repo_examples = cli_dir.parents[2] / "examples"
    if repo_examples.is_dir():
        return repo_examples

    raise ExamplesError(
        "Bundled examples not found. Reinstall symfonic-core, or run this "
        "command from a source checkout of the repository."
    )