Library Packaging¶
Decision¶
Ship the orchestrator as an installable library (testo-core on PyPI, import testo_core) so the CLI, CI wrappers, the API and custom scripts share one engine instead of each needing an app checkout.
Implementation¶
| Item | Location |
|---|---|
| Package metadata | pyproject.toml: name = "testo-core" |
| Public API | testo_core/__init__.py |
| CLI entry | testo console script (testo_core.cli.app:main) |
| API entry | testo-api console script (testo_api) |
| Dev install | pip install -e '.[dev]' |
Run history is always saved (SQLite by default), so sqlmodel is a core dependency; the [db] extra only adds the Postgres driver and tomli-w. The package CI job installs the built wheel with no extras and runs a cycle to keep it that way.
An installed package writes nothing next to its own code: run data goes to <cwd>/.testo/ or $TESTO_HOME, and a source checkout keeps using the repository root (Architecture Overview § Artifact layout). Up to 1.1.1 it was always relative to the package directory, so a pip install wrote static/ into site-packages.
FastAPI (testo_api) and the React frontend are optional consumers: testo run must not need them. See Architecture Overview § Adjacent packages (same repo).
Publishing: Publishing to PyPI. Commands: Command Reference.