Python Nodes
Checks
Validate tasks, assets, loaders, and SQL relations with Python checks.
Checks are Python nodes that validate the output of tasks, assets, and loaders, or the data in SQL models, sources, and seeds. They are the Python analog of SQL audits. See Python Nodes for the shared model.
Checks are separate graph nodes, not callbacks embedded in a task or asset. A check declares what it validates through depends_on.
Defining a check
Section titled “Defining a check”Place Python files under python/ (the playgrounds use python/checks/) and decorate functions with @check. depends_on is required:
from sqlbuild.checks import check, CheckContextfrom python.tasks.orders import export_orders
@check(depends_on=export_orders)def check_orders_exported(ctx: CheckContext): """Check orders exported.""" result = ctx.result_of(export_orders) if result.metadata.get("rows", 0) == 0: return ctx.fail(message="no orders exported") return ctx.pass_(message="orders exported")The check receives a CheckContext and reads its dependencies’ persisted results with ctx.result_of(...).
A check can also validate SQL relations. Declare them with model(), source(), or seed() from sqlbuild.refs, and resolve them with ctx.relation(...):
from sqlbuild.checks import checkfrom sqlbuild.refs import model
@check(depends_on=model("fact_orders"))def orders_present(ctx): """Orders present.""" orders = ctx.relation(model("fact_orders")) count = ctx.query(f"SELECT count(*) FROM {orders}").fetchone()[0] return ctx.pass_() if count else ctx.fail(message="no orders")Do not hard-code relation names in check SQL; see Hard-coded relation names.
Results
Section titled “Results”Return a result through the context helpers, or a bool shorthand:
@check(depends_on=orders_asset)def rows_present(ctx): """Rows present.""" return ctx.result_of(orders_asset).payload["rows"] > 0 # True -> pass, False -> fail| Return | Meaning |
|---|---|
ctx.pass_(message=None, metadata=None) |
Passing |
ctx.fail(message, metadata=None) |
Failing, using the check’s severity |
ctx.warn(message, metadata=None) |
Warning, regardless of severity |
True |
Pass |
False |
Fail |
Returning None is not allowed - checks must be explicit.
Severity
Section titled “Severity”@check takes a severity of error (default) or warn:
@check(depends_on=export_orders, severity="warn")def orders_freshness(ctx): """Orders freshness.""" if stale(): return ctx.fail(message="export is stale") # recorded as a warning, does not fail the build return ctx.pass_()error(default) - a failing check failssqb build.warn- a failing check is reported but does not fail the build.
ctx.warn(...) always produces a warning regardless of the declared severity.
What checks can depend on
Section titled “What checks can depend on”- Checks may depend on tasks, assets, and loaders.
- Checks may depend on SQL models, sources, and seeds through
model(),source(), andseed()references. They may not depend on functions. - Checks may not depend on other checks.
- Checks may not depend on a terminal source loader directly. Validate loaded source data with a source audit instead.
A check that depends on a single node is displayed grouped under that node. Multi-dependency checks are shown as standalone validation nodes, grouped by group, tags, or path.
Decorator parameters
Section titled “Decorator parameters”| Parameter | Description |
|---|---|
depends_on |
Required. Tasks/assets/loaders to validate, and model()/source()/seed() references (function, reference, tuple, or list) |
name |
Override the node name (defaults to the function name) |
severity |
error (default) or warn |
tags |
Labels for selection and grouping |
group |
Display/catalog grouping |
description |
Docs (defaults to docstring) |
meta |
Freeform JSON metadata |
Checks do not support columns, column_lineage, or retry.
Running checks
Section titled “Running checks”Checks run automatically at the end of sqb build when all their Python and SQL dependencies ran in that build. They are skipped when --no-audits is passed. To run checks on their own, use sqb check:
# Run all checkssqb check
# Run a specific check (and its required dependencies)sqb check --select +check_orders_exported
# Run checks by tagsqb check --select tag:exportssqb check rejects selecting non-check nodes; use sqb build to run tasks and assets. The models, sources, and seeds a check depends on must already exist; sqb check does not build them. Check results are written to target/run/checks/python_checks.json, and sqb check --json prints them to stdout.
Checks vs audits
Section titled “Checks vs audits”| Checks | Audits | |
|---|---|---|
| Validates | Python tasks, assets, loaders, and SQL relations | SQL relations |
| Authored in | python/ (Python) |
MODEL() headers / audits/ (SQL) |
| Run by | sqb build, sqb check |
sqb build, sqb audit |
| Severity | error, warn |
error, warn |
sqb build runs both. sqb audit runs SQL audits only; sqb check runs Python checks only.