A validation plan you build in Python isn’t locked inside the Validate object. Pointblank can render an in-memory plan back into canonical source, either as a Python method chain, a YAML configuration, or a language-neutral JSON Schema document. This is the inverse of writing a plan by hand: you hand it a Validate object and it gives you a portable representation.
Three methods do this:
Validate.to_code() produces the pb.Validate(...).col_vals_*()... chain as a string
The first two are ordinary, deterministic utilities that round-trip through Pointblank itself. to_json_schema() produces a standard that tools in many ecosystems can consume. All three are useful for sharing plans, reviewing changes in a diff, and persisting a plan alongside its results. to_code() and to_yaml() are also the foundation for the AI Validation Editor, which sends the current plan to a model as editable code.
Rendering a Plan as Python Code
Given any validation plan, to_code() returns a self-contained block of Python that reproduces it:
import pointblank as pb
validation = (
pb.Validate(
data=your_data, # Replace your_data with the actual data variable
tbl_name="small_table",
label="Small table checks",
thresholds=pb.Thresholds(warning=0.1, error=0.25),
)
.col_vals_gt(columns="d", value=100)
.col_vals_not_null(columns=["a", "b"])
.col_vals_in_set(columns="f", set=["low", "mid", "high"])
.rows_distinct()
.row_count_match(count=13)
)
validation
A few things to notice in the output:
The table-level configuration (tbl_name, label, thresholds) is reproduced on the pb.Validate(...) call.
The data source is rendered as the placeholder your_data, since the plan doesn’t know the name of the variable your data lives in. Replace it with your actual data variable before running the code.
Adjacent steps that differ only by column are collapsed into a single call: the two col_vals_not_null() steps above become col_vals_not_null(columns=["a", "b"]). This keeps the output compact and diffs minimal.
Only non-default arguments are emitted. A step-level threshold that matches the table-level default is omitted, na_pass=True appears only where it was set, and so on.
The result is regular source you can paste into a script or notebook, commit to version control, or share with a colleague.
tbl: small_table
tbl_name: small_table
label: Small table checks
thresholds:
warning: 0.1
error: 0.25
steps:
- col_vals_gt:
columns: d
value: 100
- col_vals_not_null:
columns:
- a
- b
- col_vals_in_set:
columns: f
set:
- low
- mid
- high
- rows_distinct
- row_count_match:
count: 13
The tbl field is set from tbl_name when available, otherwise to the placeholder your_data. Set it to a loadable data source (a dataset name, file path, or Python expression) before handing the YAML to yaml_interrogate(). See the YAML Validation Workflows page for the full YAML schema.
You can also write the YAML directly to a file by passing path=:
2026-08-13 19:31:31 UTC< 1 s2026-08-13 19:31:31 UTC
The rebuilt plan carries the same steps as the original. The Python code from to_code() round-trips in the same way: executing it (after replacing your_data) reconstructs an equivalent plan.
Fidelity and Limitations
Most validation steps round-trip exactly. The exceptions are steps that carry live Python objects that can’t be reconstructed from source:
For these, Pointblank emits a clearly-marked placeholder so the generated code still parses and runs, and raises a warning describing what was lost. The following plan uses a pre= callable that can’t be serialized:
import warningsflagged = pb.Validate(data=pb.load_dataset("small_table")).col_vals_gt( columns="d", value=100, pre=lambda df: df)with warnings.catch_warnings(record=True) as caught: warnings.simplefilter("always") code = flagged.to_code()for w in caught:print("warning:", w.message)
warning: Some parts of the validation plan could not be fully serialized to code:
- Step 'col_vals_gt' has a `pre=` preprocessing callable that cannot be serialized; it was dropped from the generated plan.
When you see such a warning, review the generated plan and restore the affected step by hand. Plans built entirely from literal arguments (values, ranges, sets, patterns, counts, schemas) serialize without any loss.
When to Use Serialization
Rendering a plan back to source is helpful whenever you want the plan to leave the current Python session:
Sharing. Send a colleague the exact plan as code or YAML rather than describing it.
Code review. Serialize a plan before and after a change and diff the two to see precisely what moved. You can produce this comparison directly with EditValidation.from_plans() (no LLM required), which is also how the AI Validation Editor presents proposed edits.
Persistence. Store the plan (not just the results) alongside a validation run, so you have a durable, human-readable record of what was checked.
Migrating between formats. Move a plan from Python to YAML (or, via yaml_to_python(), from YAML to Python) to fit it into a configuration-driven workflow.
Exporting a Plan as JSON Schema
While to_code() and to_yaml() reproduce your plan as Pointblank-specific source, to_json_schema() converts your validation rules into a JSON Schema document. JSON Schema is a widely adopted, language-neutral standard, so the exported schema can be consumed by validation libraries in JavaScript, Java, Go, and many other ecosystems.
When the Validate object has data attached, the schema is automatically enriched with column type information ("type": "integer", "type": "string", etc.) inferred from the data. Steps that have no natural JSON Schema equivalent (e.g., rows_distinct(), tbl_match()) are silently skipped.
Writing to a File
Pass a path= argument to write the JSON Schema to disk. Parent directories are created automatically:
Under the hood, to_json_schema() delegates to the export_contract() function with format="json_schema". The convenience method adds type enrichment from the data and handles file output. If you need the raw adapter behavior (for example, to export without type enrichment, or to work with a Contract object rather than a Validate object), use export_contract() directly. See the Importing and Exporting Contracts guide for the full story on contract adapters.
Conclusion
to_code(), to_yaml(), and to_json_schema() turn a live validation plan back into portable source. The first two are deterministic, Pointblank-specific formats that round-trip through execution and yaml_interrogate() respectively. The third produces a language-neutral JSON Schema that any JSON-Schema-aware tool can consume. Beyond sharing and persistence, these representations provide the reviewable, diffable record that powers the AI Validation Editor covered in the next section.