Skip to main content

Daffy — Validate pandas & Polars DataFrames with Python Decorators

PyPI conda-forge Python Docs CI codecov

Validate your pandas and Polars DataFrames at runtime with simple Python decorators. Daffy catches missing columns, wrong data types, and invalid values before they cause downstream errors in your data pipeline.

Also supports Modin and PyArrow DataFrames.

  • Column & dtype validation — lightweight, minimal overhead
  • Value constraints — nullability, uniqueness, range checks
  • Row validation with Pydantic — when you need deeper checks
  • Works with pandas, Polars, Modin, PyArrow — no lock-in

Installation

pip install daffy

or with conda:

conda install -c conda-forge daffy

Works with whatever DataFrame library you already have installed. Python 3.10–3.14.


Quickstart

from daffy import df_in, df_out

@df_in(["price", "bedrooms", "location"])
@df_out(["price_per_room", "price_category"])
def analyze_housing(houses_df):
    # Transform raw housing data into price analysis
    return analyzed_df

If a column is missing, has wrong dtype, or violates a constraint — Daffy fails fast with a clear error message at the function boundary.


Why Daffy?

Most DataFrame validation tools are schema-first (define schemas separately) or pipeline-wide (run suites over datasets). Daffy is decorator-first: validate inputs and outputs where transformations happen.

Non-intrusive Just add decorators — no refactoring, no custom DataFrame types, no schema files
Easy to adopt Add in 30 seconds, remove just as fast if needed
In-process No external stores, orchestrators, or infrastructure
Pay for what you use Column validation is essentially free; opt into row validation when needed

Examples

Column validation

from daffy import df_in, df_out

@df_in(["Brand", "Price"])
@df_out(["Brand", "Price", "Discount"])
def apply_discount(df):
    df = df.copy()
    df["Discount"] = df["Price"] * 0.1
    return df

Regex column matching

Match dynamic column names with regex patterns:

@df_in(["id", "r/feature_\\d+/"])
def process_features(df):
    return df

Value constraints

Vectorized checks with zero row iteration overhead:

@df_in({
    "price": {"checks": {"gt": 0, "lt": 10000}},
    "status": {"checks": {"isin": ["active", "pending", "closed"]}},
    "email": {"checks": {"str_regex": r"^[^@]+@[^@]+\.[^@]+$"}},
})
def process_orders(df):
    return df

Available checks: gt, ge, lt, le, between, eq, ne, isin, notnull, str_regex Also supported: notin, str_startswith, str_endswith, str_contains, str_length

Nullability and uniqueness

@df_in({
    "user_id": {"unique": True, "nullable": False},  # user_id must be unique and not null
    "email": {"nullable": False},  # email cannot be null
    "age": {"dtype": "int64"},
})
def clean_users(df):
    return df

Row validation with Pydantic

For complex, cross-field validation:

pip install 'daffy[pydantic]'
from pydantic import BaseModel, Field
from daffy import df_in

class Product(BaseModel):
    name: str
    price: float = Field(gt=0)
    stock: int = Field(ge=0)

@df_in(row_validator=Product)
def process_inventory(df):
    return df

Daffy vs Alternatives

Use Case Daffy Pandera Great Expectations
Function boundary guardrails ✅ Primary focus ⚠️ Possible ❌ Not designed for
Quick column/type checks ✅ Lightweight ⚠️ Requires schemas ⚠️ Requires setup
Complex statistical checks ⚠️ Limited ✅ Extensive ✅ Extensive
Pipeline/warehouse QA ❌ Not designed for ⚠️ Some support ✅ Primary focus
Multi-backend support ⚠️ Varies

Configuration

Configure Daffy project-wide via pyproject.toml:

[tool.daffy]
strict = true

Documentation

Full documentation available at daffy.readthedocs.io


Contributing

Issues and pull requests welcome on GitHub.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

daffy-3.0.0.tar.gz (61.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

daffy-3.0.0-py3-none-any.whl (27.8 kB view details)

Uploaded Python 3

File details

Details for the file daffy-3.0.0.tar.gz.

File metadata

  • Download URL: daffy-3.0.0.tar.gz
  • Upload date:
  • Size: 61.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for daffy-3.0.0.tar.gz
Algorithm Hash digest
SHA256 0c1cc4092b1ca008f988f55ad81e6fffe13a93360d3ec58d287e7927c525516a
MD5 14413343cefa141ecb1e0f1b2831e08c
BLAKE2b-256 576082b7c9f4d5cb845b1797a2f371d37d03a74a4bd84a777801a080fdfbe1dc

See more details on using hashes here.

Provenance

The following attestation bundles were made for daffy-3.0.0.tar.gz:

Publisher: release.yml on vertti/daffy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file daffy-3.0.0-py3-none-any.whl.

File metadata

  • Download URL: daffy-3.0.0-py3-none-any.whl
  • Upload date:
  • Size: 27.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for daffy-3.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 df5ca1e1e34fa3f497e71cf3b8ed13a029a789ede6b041dd90eb6996d6ab8c51
MD5 0c708f25ce95a9557e6b24bf97048c73
BLAKE2b-256 aaa8c45bee7c62ac0b8ad9ddd97398a9c9a63d059cc14603f58e504f7012b5e0

See more details on using hashes here.

Provenance

The following attestation bundles were made for daffy-3.0.0-py3-none-any.whl:

Publisher: release.yml on vertti/daffy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

3.1.0

2 files

This release

3.0.0 This release

2 files

2.8.0

2 files

2.7.0

2 files

2.6.1

2 files

2.6.0

2 files

2.5.1

2 files

2.5.0

2 files

2.4.1

2 files

2.4.0

2 files

2.3.1

2 files

2.3.0

2 files

2.2.0

2 files

2.1.0

2 files

2.0.2

2 files

2.0.1

2 files

2.0.0

2 files

1.4.0

2 files

1.3.0

2 files

1.2.0

2 files

1.1.0

2 files

1.0.2

2 files

1.0.1

2 files

1.0.0

2 files

0.19.0

2 files

0.18.0

2 files

0.17.1

2 files

0.17.0

2 files

0.16.1

2 files

0.16.0

2 files

0.15.0

2 files

0.14.2

2 files

0.14.1

2 files

0.14.0

2 files

0.13.2

2 files

0.13.1

2 files

0.13.0

2 files

0.12.0

2 files

0.11.0

2 files

0.10.1

2 files

0.10.0

2 files

0.9.4

2 files

0.9.3

2 files

0.9.2

2 files

0.9.1

2 files

0.9.0

2 files

0.8.0

2 files

0.7.0

2 files

0.6.0

2 files

0.5.0

2 files

0.4.2

2 files

0.4.1

2 files

0.4.0

2 files

0.3.0

2 files

0.2.1

2 files

0.2.0

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page