exlab_wizard.readme#

README generation package. Backend Spec §10.

class exlab_wizard.readme.CoreFields(label, operator, objective)[source]#

Bases: object

Mandatory core fields (User Interaction Spec §2).

All three are non-empty (after trim) when the controller hands the context to ReadmeGenerator; the generator re-validates so a misuse never lets a malformed README onto disk.

Parameters:
label: str#
objective: str#
operator: str#
class exlab_wizard.readme.CustomField(label, value)[source]#

Bases: object

An ad-hoc user-added field. Backend Spec §10.4.

Custom fields are plain string key-value pairs (no type selection) and their order in the output mirrors the order the user added them.

Parameters:
label: str#
value: str#
class exlab_wizard.readme.ReadmeContext(level, core, template_fields, config_fields, custom_fields, system, template_field_decls=<factory>, config_field_decls=<factory>)[source]#

Bases: object

Inputs to ReadmeGenerator. Composed by the controller.

The controller pre-merges the four layers into the dicts below so the generator does not need to know about the merge order; the generator’s job is to validate, render, and persist.

Parameters:
config_field_decls: list[TemplateFieldDecl]#
config_fields: dict[str, Any]#
core: CoreFields#
custom_fields: list[CustomField]#
level: CreationLevel#
system: SystemFields#
template_field_decls: list[TemplateFieldDecl]#
template_fields: dict[str, Any]#
class exlab_wizard.readme.ReadmeGenerator[source]#

Bases: object

Renders README.md + readme_fields.json. Backend Spec §10.

async generate(dst, ctx)[source]#

Validate ctx, write both files, return (readme, cache).

The destination directory dst must already exist (the controller creates it during the directory-render phase). The .exlab-wizard/ cache directory is created on demand.

Both files are written via asyncio.to_thread so the asyncio event loop is never blocked on disk syscalls. The two writes share a single timestamp (ctx.system.created) so the generated_at and created fields agree.

Parameters:
Return type:

tuple[Path, Path]

class exlab_wizard.readme.SystemFields(created, created_by, equipment, template, project, run, run_kind)[source]#

Bases: object

Auto-populated, non-editable system fields. Backend Spec §10.6.

Parameters:
created: datetime#
created_by: str#
equipment: dict[str, str]#
project: str#
run: str | None#
run_kind: str#
template: dict[str, str]#
class exlab_wizard.readme.TemplateFieldDecl(id, label, type, required=False, default='', options=None, hint=None)[source]#

Bases: object

Field declaration from a template’s _exlab_readme.fields list or from config.yaml readme.defaults. Backend Spec §10.3.

The same shape covers both layers: the controller knows which list it came from and packs the matching ReadmeContext slot.

Parameters:
default: Any = ''#
hint: str | None = None#
id: str#
label: str#
options: list[str] | None = None#
required: bool = False#
type: FieldType#

Modules

generator

README generator.