Validate.add_steps()

Add the steps from one or more Steps collections to the validation.

Usage

Source

Validate.add_steps(
    *steps,
    active=None,
    thresholds=None,
    exclude=None,
    columns_map=None,
)

This method appends previously recorded validation steps to the validation plan. The main source of steps is a Steps collection: a reusable group of steps built with the same methods as Validate but not attached to any table. Each recorded step is applied to this validation as if its method had been called directly, in the order the steps were recorded. Several collections can be added in one call, and the result can be chained with other validation methods, so shared steps and steps specific to this table can be combined in one plan. A Validate object can also be given, in which case its steps are copied into this validation.

Steps written for one table don’t always fit another one exactly. The optional arguments adapt the added steps without changing the collections themselves: columns_map= renames columns, thresholds= and active= replace those settings on every added step, and exclude= leaves out steps that don’t apply.

Parameters

*steps: Steps | Validate

One or more Steps or Validate objects whose steps should be added, in the order given.

active: bool | Callable | None = None

Replace the active= setting of every added step. If None (the default), each step keeps its own setting. Use False to add the steps in an inactive state, or a callable (such as has_columns()) to decide at interrogation time.

thresholds: int | float | bool | tuple | dict | Thresholds | None = None

Replace the thresholds= setting of every added step. If None (the default), each step keeps its own thresholds and otherwise uses the thresholds of this validation. Accepts the same values as the thresholds= argument of Validate.

exclude: list[str | int] | None = None

Steps to leave out, as a list of method names (e.g., ["col_vals_regex"] skips every regex step) or of 1-based positions (e.g., [2] skips the second step). Positions count within each collection, so [2] skips the second step of every collection given.

columns_map: dict[str, str] | None = None
A dictionary that renames columns in the added steps, mapping the column names used in the collection to the names in this table (e.g., {"customer_id": "cust_id"}). It applies to column names given as strings or lists of strings in a step’s columns=, column=, or columns_subset= argument. Column selectors such as starts_with() are left as they are.

Returns

Validate
The Validate object with the steps added, for further method chaining.

Raises

ValueError

If no Steps or Validate objects are given.

TypeError
If an argument in *steps isn’t a Steps or Validate object, if an item in exclude= isn’t a string or an integer, or if a step’s arguments don’t fit its validation method.

Examples

Let’s define two collections of steps for order data: one for completeness and one for valid amounts.

import pointblank as pb
import polars as pl

completeness = (
    pb.Steps()
    .col_vals_not_null(columns="order_id")
    .col_vals_not_null(columns="email")
)

valid_amounts = (
    pb.Steps()
    .col_vals_gt(columns="amount", value=0)
    .col_vals_le(columns="amount", value=10_000)
)

Both collections can be added to a validation of an orders table, along with a check that only applies to this table (the region values):

orders = pl.DataFrame(
    {
        "order_id": ["A1", "A2", None, "A4"],
        "email": ["a@x.com", None, "c@z.com", "d@w.net"],
        "amount": [25.0, 120.0, 0.0, 18_500.0],
        "region": ["east", "west", "east", "north"],
    }
)

(
    pb.Validate(data=orders, tbl_name="orders")
    .add_steps(completeness, valid_amounts)
    .col_vals_in_set(columns="region", set=["east", "west"])
    .interrogate()
)
Pointblank Validation
2026-10-29|18:36:11
Polarsorders
STEP COLUMNS VALUES TBL EVAL UNITS PASS FAIL W E C EXT
#4CA64C66 1
col_vals_not_null
col_vals_not_null()
order_id — ✓ 4 3
0.75
1
0.25
— — —
#4CA64C66 2
col_vals_not_null
col_vals_not_null()
email — ✓ 4 3
0.75
1
0.25
— — —
#4CA64C66 3
col_vals_gt
col_vals_gt()
amount 0 ✓ 4 3
0.75
1
0.25
— — —
#4CA64C66 4
col_vals_le
col_vals_le()
amount 10000 ✓ 4 3
0.75
1
0.25
— — —
#4CA64C66 5
col_vals_in_set
col_vals_in_set()
region east, west ✓ 4 3
0.75
1
0.25
— — —

The first four steps come from the two collections, in order, and the fifth is the table-specific check. Each step finds one failing row.

A table of refunds uses the same rules, but with different column names, no email column, and a stricter tolerance for failures. Here, columns_map= renames the columns, exclude= skips the second completeness step (the email check), and thresholds= makes any failure an error.

refunds = pl.DataFrame(
    {"refund_ref": ["R1", "R2", "R3"], "refund_amt": [15.0, -4.0, 60.0]}
)

(
    pb.Validate(data=refunds, tbl_name="refunds")
    .add_steps(
        completeness,
        valid_amounts,
        columns_map={"order_id": "refund_ref", "amount": "refund_amt"},
        exclude=[2],
        thresholds=pb.Thresholds(error=1),
    )
    .interrogate()
)
Pointblank Validation
2026-10-29|18:36:11
Polarsrefunds
STEP COLUMNS VALUES TBL EVAL UNITS PASS FAIL W E C EXT
#4CA64C 1
col_vals_not_null
col_vals_not_null()
refund_ref — ✓ 3 3
1.00
0
0.00
— ○ — —
#EBBC14 2
col_vals_gt
col_vals_gt()
refund_amt 0 ✓ 3 2
0.67
1
0.33
— ● —

Notes

Step 1 (local_thresholds) Step-specific thresholds set with E:1.

Step 2 (local_thresholds) Step-specific thresholds set with E:1.

Because positions count within each collection, exclude=[2] also skips the second step of valid_amounts (the upper limit on the amount). The negative refund fails the remaining amount check and reaches the error threshold.