exlab_wizard.template.copier_driver#

Copier template-engine wrapper. Backend Spec §4.4.2 / §5.

This module wraps Copier’s run_copy Python API behind the TemplateEngine contract documented in Backend Spec §4.4.2 so that the rest of the app does not depend on Copier-specific types.

Two operations:

  • TemplateEngine.resolve() – read and validate a template’s copier.yml. Returns a ResolvedTemplate. Raises TemplateLoadError on missing / malformed manifests, missing _exlab_version, type mismatch against the caller-supplied scope, or invalid _exlab_run_scope. Raises TemplateCoreFieldRedeclaredError when _exlab_readme.fields declares one of the backend-managed core fields (label / operator / objective) – see §10.3.

  • TemplateEngine.render() – render the template into dst by calling Copier under asyncio.to_thread() (Copier is sync). Always passes unsafe=False per §5.5: any _tasks in the template are silently ignored. Returns a RenderResult carrying dst and the list of files Copier created (computed by walking dst before and after the call).

YAML reads use yaml.safe_load (Backend §4.3 docstring: PyYAML is reserved for read-only YAML files like copier.yml where round-trip preservation is not required).

Classes

RenderResult(dst_path[, files_written])

Outcome of a render call.

ResolvedTemplate(name, path, exlab_type, ...)

A loaded template's metadata.

TemplateEngine()

Wraps the Copier Python API behind the §4.4.2 contract.

class exlab_wizard.template.copier_driver.RenderResult(dst_path, files_written=<factory>)[source]#

Bases: object

Outcome of a render call.

dst_path#

The absolute destination path Copier wrote into.

files_written#

Files Copier created during the render, computed by snapshotting dst before and after the call (so we capture the exact set Copier produced).

Parameters:
dst_path: Path#
files_written: list[Path]#
class exlab_wizard.template.copier_driver.ResolvedTemplate(name, path, exlab_type, exlab_version, run_scope=None, description='', plugin_order=<factory>, extra_readme_fields=<factory>, raw_manifest=<factory>)[source]#

Bases: object

A loaded template’s metadata. Backend Spec §5.2.

name#

Template directory name (the Path.name of the template root). Used for display in the wizard.

path#

Absolute path to the template root (the directory containing copier.yml).

exlab_type#

One of "project", "equipment", or "run". Mirrors _exlab_type from copier.yml.

exlab_version#

Required non-empty string per §5.7.

run_scope#

One of "experimental", "test", "both"; populated only for run templates (None otherwise).

description#

Free-form description from _exlab_description; defaults to empty string.

plugin_order#

Plugin slug list from _exlab_plugins.

extra_readme_fields#

Field-extension list declared under _exlab_readme.fields (free-form per §10.3).

raw_manifest#

The raw, fully-parsed copier.yml body. Useful for callers that need access to question definitions that this dataclass does not normalize.

Parameters:
description: str = ''#
exlab_type: TemplateType#
exlab_version: str#
extra_readme_fields: list[dict[str, Any]]#
name: str#
path: Path#
plugin_order: list[str]#
raw_manifest: dict[str, Any]#
run_scope: RunScope | None = None#
class exlab_wizard.template.copier_driver.TemplateEngine[source]#

Bases: object

Wraps the Copier Python API behind the §4.4.2 contract.

async render(tpl, dst, variables)[source]#

Render the template into dst via Copier.

Parameters:
  • tpl (ResolvedTemplate) – A previously-resolved template.

  • dst (Path) – Destination directory. Copier creates it if it does not exist; it will not silently overwrite existing files (overwrite=False).

  • variables (dict[str, Any]) – The fully-resolved answer map. Bypasses Copier’s interactive prompts (§5.3).

Return type:

RenderResult

Returns:

A RenderResult naming dst and listing the files Copier wrote.

Raises:
  • Whatever Copier raises -- e.g. copier.errors.UserMessageError

  • when overwrite=False and a generated file already

  • exists. The caller is expected to surface these via the

  • §4.6.3 error envelope.

resolve(template_path, scope)[source]#

Load + validate a template’s copier.yml.

Parameters:
  • template_path (Path) – Path to the template directory (containing copier.yml).

  • scope (TemplateType) – The caller-asserted template scope. The loaded _exlab_type must match.

Return type:

ResolvedTemplate

Returns:

A ResolvedTemplate describing the manifest.

Raises:
  • TemplateLoadErrorcopier.yml is missing, unreadable, or malformed; _exlab_version is missing or empty; _exlab_type is missing, invalid, or does not match scope; or scope is run and _exlab_run_scope is missing or not one of {"experimental", "test", "both"}.

  • TemplateCoreFieldRedeclaredError_exlab_readme.fields declares any of label / operator / objective.