Skip to main content

polspec

Declare a Polars schema once. Generate data that matches it, and validate data against it — from the same declaration.

Early alpha. The API, the YAML format, and the exact values a given seed produces are all still moving. See Roadmap and stability before depending on any of it.

import polars as pl
from polspec import ColSpec, FrameSpec

class Orders(FrameSpec):
    order_id = ColSpec(pl.Int64, bounds=(1, None))
    status   = ColSpec(pl.Enum(["NEW", "PAID", "SHIPPED"]))
    total    = ColSpec(pl.Float64, bounds=(0.0, None))
    placed   = ColSpec(pl.Date, nullable=True)

df = Orders.generate(1_000_000, seed=42)   # a million rows in well under a second
Orders.validate(df)                        # raises ValidationError on any breach

The generator is a Rust extension that fills columns in parallel — ten million rows across four columns generates in well under 50ms on a release build. validate() compiles every check across every column into a single Polars aggregation, so validating a wide table costs about the same as a narrow one.

Why generate and validate from one declaration

A validation library tells you when production data drifted. A fixture library gives you something to test against. Keeping both behind one declaration means the fixtures and the contract can't quietly disagree — and where they still can today, it's written down in Known limitations, each backed by a test that fails the moment it's fixed.

Install

Package install (when published to PyPI)

uv add polspec           # preferred
pip install polspec      # alternative
uv add "polspec[arrow]"  # extra: PyArrow for the Parquet/IPC sinks

Not published to PyPI yet — install from a checkout. The generator is a compiled Rust extension, so this needs a Rust toolchain and maturin:

git clone https://github.com/MaxwellB13/polspec.git
cd polspec
uv sync --group dev        # or: pip install -e ".[arrow]" && pip install maturin
maturin develop --release

maturin develop builds the extension and installs the package into your active environment, editable. Writing Parquet or Arrow IPC needs PyArrow, included via [arrow]/the dev group above.

What you can declare

  • Types and shape — every scalar and temporal Polars dtype, nullability, bounds (including open-ended, bounds=(0, None)), string lengths, and value domains with weights.
  • Rules and invariants — conditional values (ColRule), single-column validators, multi-column checks, composite uniqueness, and foreign keys between specs.
  • Data on demand — random or coverage-guaranteeing (method="cartesian") generation, reproducible seeds, batched streaming straight to Parquet, CSV, Arrow IPC or NDJSON.
  • Specs from elsewhere — infer a spec by profiling an existing DataFrame, or load one from YAML.
  • Shared categories — a CatSpec registry so several tables agree on an Enum/Categorical domain instead of each restating it.
class Categories(CatSpec):
    STATUS   = pl.Enum(["NEW", "PAID", "SHIPPED"])
    CURRENCY = pl.Categorical(pl.Categories("CURRENCY", physical=pl.UInt8))

ColSpec(Categories.STATUS)

Command line

polspec schema infer orders.parquet -o orders.yaml   # profile data into a schema
polspec schema new Payments -o payments.py           # or start from a blank one
polspec test orders.yaml -o test_orders.py           # generate a round-trip pytest file

The generated test disables whatever validate() flags a constraint generation can't yet satisfy (unique=True, __checks__, ...) with a comment explaining why, and skips a foreign key that needs parent data it wasn't given — see Command line.

Documentation

Full docs: maxwellb13.github.io/polspec

To edit and preview the docs locally instead, see zensical:

zensical serve

Benchmarks — polspec vs NumPy vs pure Python

The benchmarks/bench_generate.py script compares the Rust-backed generator to:

  • a NumPy-based generator that builds equivalent columns, and
  • a pure-Python implementation using random.

Run locally:

uv run --group bench python benchmarks/bench_generate.py

Example results (illustrative; your hardware will differ):

n_rows polspec (Rust) NumPy Python Polspec v NumPy Speedup
1,000 0.0003s 0.0008s 0.0016s 2.7x
10,000 0.0006s 0.0052s 0.0145s 8.7x
100,000 0.0027s 0.0480s 0.1447s 17.8x
1,000,000 0.0083s 0.4867s 1.4862s 58.6x
5,000,000 0.0256s 2.4326s skipped 95.0x
20,000,000 0.0827s 9.7523s skipped 117.9x

Measured 2026-09-03 on an Intel 13900K with 64GB DDR5; the same run backs the table in Comparison.

Notes

  • All three implementations emit a Polars DataFrame with the same schema to keep the comparison fair. The NumPy version uses a fixed-width trick for strings (since vectorized ragged strings are not available), and the pure-Python version builds lists then constructs a DataFrame.
  • The script warms each implementation once, then times increasing sizes; the pure-Python path is skipped for very large sizes once it exceeds a cutoff.

Development

After the install steps above:

uv run pytest
uv run ruff check . && uv run ruff format --check .
cargo test --release && cargo clippy --release
uv run python examples/related_specs.py

See CONTRIBUTING.md for conventions and the release process, and CHANGELOG.md for what changed.

License

MIT.

Release files for polspec 0.1.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for polspec 0.1.5
File Size Uploaded
polspec-0.1.5.tar.gz 204.9 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for polspec 0.1.5
File
polspec-0.1.5-cp312-abi3-win_amd64.whl CPython 3.12 abi3 Windows x86-64 Details
polspec-0.1.5-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.12 abi3 Linux glibc 2.17+ x86-64 Details
polspec-0.1.5-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.12 abi3 Linux glibc 2.17+ ARM64 Details
polspec-0.1.5-cp312-abi3-macosx_11_0_arm64.whl CPython 3.12 abi3 macOS 11.0+ ARM64 Details
polspec-0.1.5-cp312-abi3-macosx_10_12_x86_64.whl CPython 3.12 abi3 macOS 10.12+ x86-64 Details

Total release size: 32.3 MB

Release files / polspec-0.1.5.tar.gz

Download URL polspec-0.1.5.tar.gz
Size 204.9 kB
Tags Source
SHA-256 checksum
How to use checksums
1a190697932a7ee1d02b38a82043be01a5bfa1876ed684839fa604937f4f0f09
BLAKE2b-256 checksum
How to use checksums
cf773d2095244e67019d4fe9e96fccf48d5cb89c766bdad11908777d4ef3c071
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Release files / polspec-0.1.5-cp312-abi3-win_amd64.whl

Download URL polspec-0.1.5-cp312-abi3-win_amd64.whl
Size 6.3 MB
Tags CPython 3.12 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
788a14edbc48d4355c31260362f3d4513b3fbcc9e5de941d292f2ef64da18f5d
BLAKE2b-256 checksum
How to use checksums
d1ea62bbf11c707ec28982c9e8f07aca45617f75ee7fd80a40dda0ee11a02a89
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Release files / polspec-0.1.5-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL polspec-0.1.5-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 6.6 MB
Tags CPython 3.12 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
40b3697b5d146a60e728227f2e460fff734711149f67d714e5a538163ad27714
BLAKE2b-256 checksum
How to use checksums
fc711d40954b4dcac129540febe6802a1b830b22ec0a68773687d72da4f9d54c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Release files / polspec-0.1.5-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL polspec-0.1.5-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 7.2 MB
Tags CPython 3.12 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
b22824cd0e158bb13e53fa4f7c327a3ba025c7ad7ecd2dd2efb4f7612c6259e9
BLAKE2b-256 checksum
How to use checksums
0b244e98f69e935097f4113e3d8d5e50e45ae1817440a793f37b16a3a5a02a46
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Release files / polspec-0.1.5-cp312-abi3-macosx_11_0_arm64.whl

Download URL polspec-0.1.5-cp312-abi3-macosx_11_0_arm64.whl
Size 5.8 MB
Tags CPython 3.12 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
b3f6668ed27acc887e802ba2875a1b382b177c0a22d3349481e2417b39974fa7
BLAKE2b-256 checksum
How to use checksums
feab1258cd34534a457500aead5432b61be4fed073d53313200565a1b1e5c533
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Release files / polspec-0.1.5-cp312-abi3-macosx_10_12_x86_64.whl

Download URL polspec-0.1.5-cp312-abi3-macosx_10_12_x86_64.whl
Size 6.3 MB
Tags CPython 3.12 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
b0f32ef635954354c268ef6028b43185c1a95efeb095cdad7f58a8e8afc59545
BLAKE2b-256 checksum
How to use checksums
ab870ac5bc05574ee92f69a4c75e2ee30168c3e7dbdc71cd319d64247829d979
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Release history Release notifications | RSS feed

0.9.1

6 release files

0.9.0

6 release files

0.8.0

6 release files

0.7.0

6 release files

0.6.0

6 release files

0.5.0

6 release files

0.4.1

6 release files

0.4.0

6 release files

0.3.0

6 release files

0.2.0

6 release files

This release

0.1.5 This release

6 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page