Deterministic dataset validation, drift detection, and lineage audit — Python wrapper for the cjc-locke Rust crate
Project description
cjc-locke (Python)
Thin PyO3 wrapper over the Rust cjc-locke crate —
deterministic dataset validation, drift detection, and lineage audit for
Python users.
Why
You want Locke's contract (byte-identical reports across runs, machines, and process boundaries) without leaving Python. This wrapper gives you exactly that: every call delegates to one Rust function. There is no business logic on the Python side, no Python-level caching, no extra allocations beyond a single column copy at the FFI boundary.
Install
pip install maturin
cd python/
maturin develop --release # local dev install
# or
maturin build --release # produce a wheel in target/wheels/
pip install target/wheels/cjc_locke-*.whl
The build needs Rust 1.63+ (Rust 1.91 is what this project uses) and
Python 3.9+. The wheel is abi3-py39 so a single artifact works for every
CPython 3.9 through latest.
Performance and determinism guarantees
- Determinism: byte-identical to a native Rust call. Python dict
insertion order is preserved per PEP 468;
cjc_data::DataFramecanonicalises everything downstream viaBTreeMap. The Rust side does not multithread by default and the wrapper introduces no threading. - Memory: one heap allocation per column at the FFI boundary
(
Vec<f64>/Vec<i64>/Vec<String>/Vec<bool>), then zero copies through to the report. For numpyf64/i64/boolcolumns the FFI read is zero-copy via the buffer protocol; only theto_vec()into Rust-owned memory counts. - Power / thermal: identical to native — the Rust side does the same
work it would do from a
cjclCLI run. No background threads, no asyncio, no extra cores. - Float / integer fidelity: numpy
f64/i64are bit-exact passed through.f32/i32widen via direct cast (lossless). Pythonintextracted asi64errors on overflow (PyO3 default).
Quick start
import numpy as np
import cjc_locke
# 1. Dict-of-arrays / lists in.
data = {
"age": np.array([20.0, 30.0, np.nan, 40.0, 99.0]),
"city": ["NY", "LA", "NY", "SF", "NY"],
"is_active": [True, True, False, True, True],
}
report = cjc_locke.validate(data, label="users")
print(report) # <LockeReport n_findings=2 ...>
print(report.severity_counts) # {'info': 0, 'notice': 0, 'warning': 1, 'error': 1}
print(report.finding_codes()) # ['E9001', 'E9041']
# 2. Full per-finding evidence via JSON round-trip (cheap).
detail = report.to_dict()
for f in detail["findings"]:
print(f["code"], f["severity"], f["message"])
# 3. Canonical bytes for downstream audit chains.
canonical = report.to_json() # byte-identical to a native Rust call
Drift detection
report = cjc_locke.compare_drift(
train={"x": np.arange(1000.0)},
test={"x": np.arange(500.0, 1500.0)},
)
print(report.finding_codes()) # ['E9030', 'E9039', ...]
# Or all in one go:
val, drift, belief = cjc_locke.validate_and_compare(train, test, label="my-data")
print(belief.score_dict())
# {'overall': 0.78, 'schema': 1.0, 'drift': 0.42, ...}
Streaming (out-of-core)
sv = cjc_locke.StreamingValidator(label="stream", config={"sample_cap": 100_000})
for chunk in iter_chunks_somehow():
sv.ingest_chunk(chunk) # chunk is a dict like above
final = sv.into_report()
Policy gates
result = cjc_locke.apply_policy(report, policy={
"suppressions": [
{"code": "E9001", "column": "phone", "reason": "PII expected"},
],
"owners": [
{"team": "data-quality", "code": "E9072"},
],
"requirements": [
{"code": "E9001", "operator": "eq_zero", "threshold": 0},
],
})
if result.gate_fails():
raise SystemExit("policy gate failed")
Lineage audit
b = cjc_locke.LineageBuilder("daily-pipeline")
src = b.add_impression("train.csv", kind="dataset", n_rows=10_000,
columns=["x", "y"])
node = b.add_idea(name="filter_active",
op_id="filter",
parents=[src],
params={"expr": "is_active == True"})
graph = b.finish()
assert graph.is_acyclic()
graph.validate_audit_monotonic() # raises ValueError if violated
print(graph.emit_mermaid()) # graph rendering for docs
Pandas / polars
The Python facade auto-detects pandas or polars DataFrames by duck-typing —
both libraries remain optional dependencies. Internally we call df[col].values
(pandas) or df[col].to_numpy() (polars) per column, then route through the
same numpy zero-copy path as a raw dict. No extra business logic.
import pandas as pd
df = pd.DataFrame({"x": [1.0, 2.0, 3.0]})
report = cjc_locke.validate(df) # works
What's exposed
Everything from the cjc-locke crate's public surface that translates
cleanly to Python:
validate,compare_drift,validate_and_comparebelief_report,apply_policycausal_guardrail,detect_temporal_issuesemit_report_json,parse_report_jsonmake_audit_event- Classes:
LockeReport,InductionRiskReport,BeliefReport,CausalGuardrailReport,StreamingValidator,LineageBuilder,LineageGraph,AuditEvent,PolicyResult
The Rust-side TracedDataFrame (which uses lifetime-borrowed references
to a builder) does not map to Python; use LineageBuilder.add_idea(...)
directly to build the same provenance graph.
License
MIT — same as the rest of the workspace.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
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 cjc_locke-0.1.1.tar.gz.
File metadata
- Download URL: cjc_locke-0.1.1.tar.gz
- Upload date:
- Size: 684.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8d4c0b322a30966e9c807a63c922020e306083dbfde7ee3a2a60081ccf3fcf6b
|
|
| MD5 |
9f0cc2bb812202486af81a71d7491f42
|
|
| BLAKE2b-256 |
dbea3eca2104aea7605789a597c8ea36f76487124be9dc3f08485a920bc95e58
|
File details
Details for the file cjc_locke-0.1.1-cp39-abi3-win_arm64.whl.
File metadata
- Download URL: cjc_locke-0.1.1-cp39-abi3-win_arm64.whl
- Upload date:
- Size: 601.6 kB
- Tags: CPython 3.9+, Windows ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca5a112f09bcee6e11d2895700e3378739e124761a6ecb64f32849cf601f9f2d
|
|
| MD5 |
bc0e61b547f867f958a00e616ada7e61
|
|
| BLAKE2b-256 |
a6dac0ec911c1c9a3c79d28fe611c5e2e2b1de9120ff034324f594f7b3e317d1
|
File details
Details for the file cjc_locke-0.1.1-cp39-abi3-win_amd64.whl.
File metadata
- Download URL: cjc_locke-0.1.1-cp39-abi3-win_amd64.whl
- Upload date:
- Size: 679.0 kB
- Tags: CPython 3.9+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5d4b0628899fb56bb47aa1a2c157e64d486dcc7badb730a3e98d64ae3df61973
|
|
| MD5 |
9a3f8bd24c164cb31bc045ded60e84ff
|
|
| BLAKE2b-256 |
75f6e421e95d788536fca56cd56538e4879b6f33e4161e0fcf862b2521fff607
|
File details
Details for the file cjc_locke-0.1.1-cp39-abi3-win32.whl.
File metadata
- Download URL: cjc_locke-0.1.1-cp39-abi3-win32.whl
- Upload date:
- Size: 613.1 kB
- Tags: CPython 3.9+, Windows x86
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
29e413393d5b246f36b499fea0b3cccfd29ec6371cf86f892dc96ed53b5d1629
|
|
| MD5 |
6cd6ae864fc12cb4285b70cebde03e35
|
|
| BLAKE2b-256 |
4b4a7e6e14f93c63fa9608e73dddf7538f017cdf980f792a96cc7730e210e51a
|
File details
Details for the file cjc_locke-0.1.1-cp39-abi3-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: cjc_locke-0.1.1-cp39-abi3-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 993.7 kB
- Tags: CPython 3.9+, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d1bec9773d0eb7190960a634f37f8689de99ac8c586527e4233781d9cbf35a9d
|
|
| MD5 |
10d1a5d176e728eab19982fdfe8434ff
|
|
| BLAKE2b-256 |
87a14c17e0091afe12b0ead986b054b332947964caca6da23ddcacd6c11e4144
|
File details
Details for the file cjc_locke-0.1.1-cp39-abi3-musllinux_1_2_i686.whl.
File metadata
- Download URL: cjc_locke-0.1.1-cp39-abi3-musllinux_1_2_i686.whl
- Upload date:
- Size: 1.0 MB
- Tags: CPython 3.9+, musllinux: musl 1.2+ i686
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef8e703cec373acb8b0e1231c0e7ca7f0fca25dc3b3897defbbf111f1862707d
|
|
| MD5 |
9aa4a63d1ec4a457c1bbe920d1573d4b
|
|
| BLAKE2b-256 |
8dc7684c409b4acf123e886c90acf0fcb547953311e562633c91ff73c874687b
|
File details
Details for the file cjc_locke-0.1.1-cp39-abi3-musllinux_1_2_armv7l.whl.
File metadata
- Download URL: cjc_locke-0.1.1-cp39-abi3-musllinux_1_2_armv7l.whl
- Upload date:
- Size: 1.0 MB
- Tags: CPython 3.9+, musllinux: musl 1.2+ ARMv7l
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f105906d8489dc25749d2e7f7c811a1a61b1682c4a3b664381e563860a59b8a5
|
|
| MD5 |
bfcbbb618a91bb6596404032f1c78a6a
|
|
| BLAKE2b-256 |
6566d279bcc9e42b44020995f8eafc196c2957c39c0e7936215556e916c22ce4
|
File details
Details for the file cjc_locke-0.1.1-cp39-abi3-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: cjc_locke-0.1.1-cp39-abi3-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 900.3 kB
- Tags: CPython 3.9+, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8868c9c66e3e63bca5a32acb834942700f69e911ed32c6632e95da02938e33ea
|
|
| MD5 |
45c51bba755a8054ff7e53a3707ba877
|
|
| BLAKE2b-256 |
e78a7a578b4091d201550a2d66b8f1b8d810d8bb3973b7d4747d93e8b71197a3
|
File details
Details for the file cjc_locke-0.1.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: cjc_locke-0.1.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 787.5 kB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5a1aedbf7b4158a20723cf0a6ac9bb25fe74807add8f988b64701b914739923a
|
|
| MD5 |
a984f60f0775c41838d38e7690ebc775
|
|
| BLAKE2b-256 |
aca53838d5ca06232ecf0eec6cf4874e3fc5f6215e31cdb295830ed593352db5
|
File details
Details for the file cjc_locke-0.1.1-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl.
File metadata
- Download URL: cjc_locke-0.1.1-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl
- Upload date:
- Size: 830.0 kB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ s390x
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
be90c47fd1fbc78886c4de2a46e359f8533c8a9d8b5bd29bb6404b30cff609f9
|
|
| MD5 |
dd5bdc8734c8471f4cc97989203f249f
|
|
| BLAKE2b-256 |
3bea1f65b5ba53f77470dbf61107dec436029b4421005b78dbf04a457f33d778
|
File details
Details for the file cjc_locke-0.1.1-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.
File metadata
- Download URL: cjc_locke-0.1.1-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
- Upload date:
- Size: 847.9 kB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ ppc64le
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7249c021dabfad63afe47ce9e86d2f877acfa620db716b6c685acb2f9f2a25bd
|
|
| MD5 |
d1e71e86578d6e92e32b202485ea03fd
|
|
| BLAKE2b-256 |
05d20f7543792a08be76fa0e9930d7f5e57009b218bbc309b76da0d4aae0bcd0
|
File details
Details for the file cjc_locke-0.1.1-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.
File metadata
- Download URL: cjc_locke-0.1.1-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
- Upload date:
- Size: 767.0 kB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ ARMv7l
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1c04f55f1fb38eae16c1fbea1b89768dce204a872a9a538480c7cf1e159f5ae6
|
|
| MD5 |
d87e228356d21327b66cacc12a9ede41
|
|
| BLAKE2b-256 |
b3e7d2b1ce65f1789acf1c65ea6ab8575ca394d5727f58cfa96b32d203743630
|
File details
Details for the file cjc_locke-0.1.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: cjc_locke-0.1.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 717.7 kB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
23dd051568ffb8f99e24246f095ec0a7ca5ba726fb769dc8cc49c7a72da5e60a
|
|
| MD5 |
a72a3a3abd0e69f46138dae8d82c0723
|
|
| BLAKE2b-256 |
6186cad3612ce0fc55826f6aa0ddc85f59626b9dc815a5377702f95eb35c4c4f
|
File details
Details for the file cjc_locke-0.1.1-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl.
File metadata
- Download URL: cjc_locke-0.1.1-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl
- Upload date:
- Size: 804.6 kB
- Tags: CPython 3.9+, manylinux: glibc 2.5+ i686
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dd4d3be2ca46eb2076b436384a4ccb1d7365b88ef17743cf0b0e511459b633bc
|
|
| MD5 |
d5135b17619cfa65fc7180d8bc20a659
|
|
| BLAKE2b-256 |
8a49136a347095606174ee18ec04c7f8d082642004ca53ed1f25215edf630fa1
|
File details
Details for the file cjc_locke-0.1.1-cp39-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: cjc_locke-0.1.1-cp39-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 691.8 kB
- Tags: CPython 3.9+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
89a556c326152b8f56cd3548c1f577989073f50fb7bf72f22df6c6acc54d0d13
|
|
| MD5 |
573844e4144296112333e9298ad4804c
|
|
| BLAKE2b-256 |
d4be668c589b71f677315ac4b3bb4e6916362d549a74e73843eb1f0320ae0443
|
File details
Details for the file cjc_locke-0.1.1-cp39-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: cjc_locke-0.1.1-cp39-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 774.1 kB
- Tags: CPython 3.9+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ab6cf82015e1e25d1420820e74cbdef660883105cedc17161b61fcf9e24f1d08
|
|
| MD5 |
ab2781656d5d02cecc951b55661fa5e5
|
|
| BLAKE2b-256 |
3b6e1d3e70280c785b34b398cacb0dd31e1141bea8b002be68e46d6750c81914
|