Skip to Content
COREValidation

Validation

The validation module checks data quality against a set of rules and produces a structured ValidationResult. Rules observe data and report whether it satisfies conditions; they never modify the data.

validate()

The primary entry point:

import polars as pl from hermes.validation import validate, NotNull, RangeCheck data = pl.read_csv("data.csv") report = validate( data=data, rules=[ NotNull("country_code"), RangeCheck("value", min=0, max=100), ], ) print(report.passed) # True if every rule passed print(report.summary()) # human-readable summary

Parameters

ParameterTypeDescription
dataAnypl.DataFrame, pl.LazyFrame, pyarrow.Table, or dict/list of dicts
rules`list[ValidationRule]None`
context`ValidationContextNone`

Rules run independently against the original input — they never feed results to each other.

ValidationResult

FieldTypeDescription
successboolThe validation process completed without engine errors
passedboolsuccess and every rule passed
resultslist[RuleResult]Per-rule outcomes
errorslist[str]Engine errors (e.g. a rule raised)
warningslist[str]Rule warnings

Methods: summary() (formatted text), to_dict() (JSON-serializable), bool(report) is passed.

RuleResult

FieldTypeDescription
rulestrRule name
passedboolWhether the rule passed
statisticsdictCheck-specific stats (e.g. null counts, violation counts)
violationslist[Violation]Offending values
messagestrHuman-readable result
warningslist[str]Warnings

Violation

Violation(field, row=None, value=None, expected=None, message="") — a single offending value.

ValidationEngine

For running a configured rule pipeline:

from hermes.validation import ValidationEngine, NotNull engine = ValidationEngine(rules=[NotNull("id")]) engine.add_rule(RangeCheck("value", min=0)) result = engine.validate(data) engine.rules # list of configured rules engine.describe() # rule metadata as dicts

Built-in Rules

All rules are exported from hermes.validation. Each exposes name, check(data, context) -> RuleResult, validate() (raises RuleConfigurationError if misconfigured), and describe(). Column-based rules take a field argument (the column name).

RuleConstructorChecks
NotNullNotNull("col")Column has no nulls
UniqueUnique("col")Column values are unique
UniqueCombinationUniqueCombination(["a", "b"])Row tuples are unique
TypeCheckTypeCheck("col", "float") or TypeCheck({"a": "float"})Column schema types
RangeCheckRangeCheck("col", min=0, max=100)Numeric values within range
EnumCheckEnumCheck("col", ["US", "GB"])Values are in an allowed set
RegexCheckRegexCheck("col", r"\d{4}")Values match a regex
PatternCheckPatternCheck("col", "pattern")Named pattern match
LengthCheckLengthCheck("col", min=..., max=...)String lengths
DateRangeCheckDateRangeCheck("date", min=..., max=...)Dates within range
DateOrderCheckDateOrderCheck("start", "end")start is not later than end
SchemaCheckSchemaCheck({"col": "type"})Column names/types match exactly
ColumnCheckColumnCheck(["a", "b"], allow_extra=True)Required columns present
RowCountCheckRowCountCheck(min=None, max=None, exact=None)Row count bounds
NullRateCheckNullRateCheck("col", max_rate=0.1)Null ratio below threshold
DuplicateCheckDuplicateCheck(columns=None)Duplicate rows (whole row or subset)
CompletenessCheckCompletenessCheck(["a"], min_rate=1.0)Combined completeness of columns
FreshnessCheckFreshnessCheck("date", max_age="7d")Most recent value is not stale
ReferentialCheckReferentialCheck("col", reference_data=...)Values exist in a reference dataset
ForeignKeyCheckForeignKeyCheck("col", reference=...)Values match a reference column
ConstantCheckConstantCheck("col", expected=None)Column is constant
CardinalityCheckCardinalityCheck("col", unique_min=..., unique_max=...)Distinct-count bounds

register_pattern(name, compiled_regex) registers named patterns used by PatternCheck.

Top-Level API

import hermes as hr from hermes.validation import NotNull report = hr.validate(df, rules=[NotNull("country_code")])

Errors

from hermes.validation import ( ValidationError, # base error RuleConfigurationError, # a rule is misconfigured RuleExecutionError, # a rule failed while running )
Last updated on