continuo-validation-runner
The slim, continuo-owned validation harness. It dispatches on VALIDATION_OP
(build_from_sql / clone_from_prod / build_from_columns / ensure_schema
/ drop_schema), fetches a node's candidate SQL or column spec from S3 when
relevant, discovers the single installed engine adapter (entry-point group
continuo_validation.adapters), runs the corresponding warehouse DDL through
it, and prints exactly one sentinel-framed result block on stdout.
It depends on continuo-validation-contract (the port + result-block) and, at
image-build time, on exactly one continuo-validation-<engine> library —
Dockerfile.postgres bakes in continuo-validation-postgres. Inside the
shipped images, the contract, the runner, and the engine adapter all install
from this repo's own workspace paths (contract/, runner/,
adapters/<engine>/) in a single pip transaction at image build time, not
from PyPI — see the Dockerfile comments for why. The container entrypoint is
python /validation_runner.py, which continuo's executor invokes.
python -m continuo_validation_runner reaches the identical main and is
convenient for local invocation, but it is not the image contract on its
own — an image built around this package standalone (e.g. for an engine
this repo doesn't ship) has more to satisfy than that one command. This
package is also published to PyPI as continuo-validation-runner for
exactly that use; see the bring-your-own-adapter section of the main
README
for the full image contract.
Job, not a service
This is not one of continuo's long-running services — see the service list at
github.com/carolsimone/continuo. It
ships as a container image (continuo-validation-<engine>) that
executor-controller dispatches as a one-shot Kubernetes Job
(BackoffLimit: 0, RestartPolicy: Never) per node or per schema op. The
process reads VALIDATION_OP, runs it once, prints one result block, and
exits — there is no process to keep alive, no gRPC/HTTP surface, and no owned
datastore.
Its entire behavior is the five ops dispatched through the ValidationAdapter
port (see continuo-validation-contract)
plus the sentinel result-block wire format. Because that surface is small and
fixed, this runner itself is very unlikely to need changes: adding support for
a new warehouse engine means adding a new continuo-validation-<engine>
adapter package and pointing VALIDATION_IMAGE at an image built from it, not
editing this code.
The sentinel result-block format is frozen: continuo's Go package
pkg/validationresult parses it, so changing it is a coordinated, versioned
event across both repos, not a local edit.
build_from_columns
A python node's output table has no compiled SELECT for the harness to shape
it from the way a SQL node's does — the script that actually produces the
node's rows only runs at python-node runtime, after validation. So instead
of build_from_sql's "materialize the candidate SQL empty," this op fetches
a JSON spec from CANDIDATE_SPEC_URI (an s3:// URI, same AWS/S3 credential
env as CANDIDATE_SQL_URI):
{"reads": ["<sql>", ...], "output_columns": [{"name": "...", "type": "...", "nullable": true}, ...]}
The body must be a JSON object; reads may be empty (a node with no
upstream reads) but output_columns must be non-empty — either failure is a
bad-input exit (2), before the adapter is ever touched. Because a python
node's own reads aren't implicitly validated the way a SQL node's SELECT is,
the harness calls the adapter's check_binds on every reads entry, in
declared order, before calling build_empty_from_columns with
output_columns. Binds gate the build: a read that fails to bind — for
example against a column an upstream node dropped — fails the op and the
output table is never created.
Each reads entry must be a single read query, and adapters enforce that by
parsing it (continuo_validation_contract.sql.ensure_single_read) before any
of it reaches the warehouse: an entry that parses as more than one statement,
or as a statement that isn't a query, fails the op rather than executing.
Parsing is the enforcement — an adapter that only wrapped the read in a
subquery would still let a read that balances the wrap's own parentheses
smuggle a statement through on any driver that batches ;-separated
statements.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file continuo_validation_runner-0.2.0.tar.gz.
File metadata
- Download URL: continuo_validation_runner-0.2.0.tar.gz
- Upload date:
- Size: 13.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a8a80c49aed43c25608c6d42460bf3453b274a376c649b05b87a6ac4e237be0
|
|
| MD5 |
2889439c351f1c0b013c786fc026bab0
|
|
| BLAKE2b-256 |
ef4d423cdb76ba0b476738178aaca25ddd21b0cd7323e05795c68c35e8973467
|
Provenance
The following attestation bundles were made for continuo_validation_runner-0.2.0.tar.gz:
Publisher:
publish-pypi.yml on carolsimone/continuo-validation
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
continuo_validation_runner-0.2.0.tar.gz -
Subject digest:
0a8a80c49aed43c25608c6d42460bf3453b274a376c649b05b87a6ac4e237be0 - Sigstore transparency entry: 2367568297
- Sigstore integration time:
-
Permalink:
carolsimone/continuo-validation@3feecb6dee8bd53f9fcbfe2725ea2a3d1903b0fe -
Branch / Tag:
refs/tags/pypi-runner-v0.2.0 - Owner: https://github.com/carolsimone
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@3feecb6dee8bd53f9fcbfe2725ea2a3d1903b0fe -
Trigger Event:
push
-
Statement type:
File details
Details for the file continuo_validation_runner-0.2.0-py3-none-any.whl.
File metadata
- Download URL: continuo_validation_runner-0.2.0-py3-none-any.whl
- Upload date:
- Size: 8.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f7610e8f35eb82447abed3b60f63f000ce44f9707270416120274b48f883d9de
|
|
| MD5 |
5d0316bc82d7b75470e49514700ac516
|
|
| BLAKE2b-256 |
d6400781ebc8fad6dd1de6ca9e8168cc69338f3575ba406696f89e9300245a1f
|
Provenance
The following attestation bundles were made for continuo_validation_runner-0.2.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on carolsimone/continuo-validation
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
continuo_validation_runner-0.2.0-py3-none-any.whl -
Subject digest:
f7610e8f35eb82447abed3b60f63f000ce44f9707270416120274b48f883d9de - Sigstore transparency entry: 2367568427
- Sigstore integration time:
-
Permalink:
carolsimone/continuo-validation@3feecb6dee8bd53f9fcbfe2725ea2a3d1903b0fe -
Branch / Tag:
refs/tags/pypi-runner-v0.2.0 - Owner: https://github.com/carolsimone
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@3feecb6dee8bd53f9fcbfe2725ea2a3d1903b0fe -
Trigger Event:
push
-
Statement type: