Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 53 additions & 2 deletions src/docgen/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,54 @@
"""docgen — reusable demo generation pipeline."""
"""docgen — reusable demo generation pipeline.

__version__ = "0.1.0"
The package root re-exports the per-function demo API (`demo_function`) so
consumers can use ``from docgen import load_manifest, render`` without reaching
into submodules. For CLI / VHS demos (no Playwright tests), build a manifest with
`manifest_from_mapping` and pass it to `render`.
"""

from docgen.demo_function import (
CACHED_ARTIFACTS,
HARD_CAP_SECONDS,
Action,
EXIT_INVALID,
EXIT_NEUTRAL_SKIP,
EXIT_OK,
EXIT_TOOLING_MISSING,
Manifest,
ManifestError,
NarrationResult,
PlaceholderManifest,
RenderResult,
SUPPORTED_ACTION_KINDS,
ToolingMissingError,
generate_capture_script,
load_manifest,
manifest_from_mapping,
render,
run_cli,
)

__version__ = "0.2.0"

__all__ = [
"__version__",
"Action",
"CACHED_ARTIFACTS",
"EXIT_INVALID",
"EXIT_NEUTRAL_SKIP",
"EXIT_OK",
"EXIT_TOOLING_MISSING",
"HARD_CAP_SECONDS",
"Manifest",
"ManifestError",
"NarrationResult",
"PlaceholderManifest",
"RenderResult",
"SUPPORTED_ACTION_KINDS",
"ToolingMissingError",
"generate_capture_script",
"load_manifest",
"manifest_from_mapping",
"render",
"run_cli",
]
24 changes: 24 additions & 0 deletions src/docgen/demo_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,29 @@ def _load_yaml_sidecar(path: Path) -> Manifest:
return _coerce(raw, source_path=path)


def manifest_from_mapping(
raw: dict[str, Any],
*,
source_path: Path | None = None,
) -> Manifest:
"""Build a validated `Manifest` from the same mapping shape as a ``*.docgen.yaml``.

For programmatic use when you are not loading YAML from disk and not using a
Playwright ``.ts`` spec or ``path.py::test_name``. Typical cases:

- **CLI / VHS** — ``demonstration.kind: cli`` and ``demonstration.tape`` pointing
at a ``.tape`` file (no Playwright involved).
- **Declarative browser** — ``demonstration.kind: playwright`` with ``url`` and
``actions`` (docgen drives Playwright from Python; no Node ``@playwright/test``).

``source_path`` resolves relative paths inside the manifest (fixtures, tape,
optional ``spec``/``cwd``) the same way as a sidecar file next to your assets.

Raises `ManifestError` if the mapping violates the schema.
"""
return _coerce(raw, source_path=source_path)


def _load_pytest_marker(path: Path, test_name: str) -> Manifest:
"""Read `@pytest.mark.docgen(...)` decorator on `test_name` via `ast`.

Expand Down Expand Up @@ -1676,6 +1699,7 @@ def run_cli(
"RenderResult",
"NarrationResult",
"load_manifest",
"manifest_from_mapping",
"render",
"run_cli",
"generate_capture_script",
Expand Down
17 changes: 17 additions & 0 deletions tests/test_demo_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
_render_action,
generate_capture_script,
load_manifest,
manifest_from_mapping,
run_cli,
)

Expand Down Expand Up @@ -172,6 +173,22 @@ def test_cli_kind_requires_tape() -> None:
_coerce(raw)


def test_manifest_from_mapping_cli(tmp_path: Path) -> None:
"""Programmatic manifest for VHS (no Playwright test files)."""
tape = tmp_path / "demo.tape"
tape.write_text("Output out.mp4\n", encoding="utf-8")
sidecar = tmp_path / "side.docgen.yaml"
raw = {
"identifier": "cli:demo",
"intent": "Shows the CLI.",
"demonstration": {"kind": "cli", "tape": "demo.tape"},
"output_budget": {"duration_seconds": 15, "resolution": "1280x720"},
}
m = manifest_from_mapping(raw, source_path=sidecar)
assert m.kind == "cli"
assert m.cli_tape == tape.resolve()


def test_playwright_spec_requires_grep(tmp_path: Path) -> None:
spec = tmp_path / "t.spec.ts"
spec.write_text("//", encoding="utf-8")
Expand Down
8 changes: 8 additions & 0 deletions tests/test_package_exports.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""Smoke tests for `docgen` package-level re-exports."""

from docgen import manifest_from_mapping, render


def test_manifest_from_mapping_exported_at_package_root() -> None:
assert callable(manifest_from_mapping)
assert callable(render)