Skip to main content

valguard: A lightweight framework for defining and validating values in data pipelines.

Project description

valguard

Constraint-aware value types for semantic validation in Python pipelines

valguard is a lightweight framework for defining and validating values in data pipelines. It separates values from constraints. This allows a source to publish the constraint against which it will validate each value. An implies function can determine whether values satisfying an upstream constraint are guaranteed to satisfy a downstream constraint.

License PyPI Python


Key Features

  • Declarative value types
  • Validators for clean pipeline integration
  • Type-safe abstractions compatible with Python 3.12+

Usage

Values

A Value stores a particular kind of value. It is immutable. Different methods are provided for accessing the value depending on its type: this provides a concise way to validate type and access the value simultaneously. If x is not an integer then x.as_int will raise an exception.

To avoid raising an exception, use isinstance() to test the type beforehand.

A subclass of NumericValue will have the method .to_float.

>>> from valguard import FloatValue, IntValue, NumericValue, BoolValue
>>> fv = FloatValue(1.0)    # Must use 1.0 and not 1
>>> iv = IntValue(1)
>>> bv = BoolValue(True)
>>> isinstance(bv,NumericValue)
False
>>> isinstance(iv,NumericValue)
True
>>> bv.as_float
Traceback (most recent call last):
    ...
valguard.exceptions.TypeMismatchError: Incompatible accessor
>>> iv.as_float
Traceback (most recent call last):
    ...
valguard.exceptions.TypeMismatchError: Incompatible accessor
>>> iv.to_float
1.0
>>> iv.as_int
1
>>> fv.as_float
1.0
>>> fv.to_float
1.0

Constraints

Constraints can be placed on both type and value.

>>> from valguard import IntValue, BoolValue, IntervalConstraint, NumericConstraint, IntConstraint
>>> iv = IntValue(23)
>>> bv = BoolValue(False)
>>> interval_a = IntervalConstraint(0,100)
>>> interval_b = IntervalConstraint(10,20)
>>> interval_a.validate(iv)
IntValue(23)
>>> interval_b.validate(iv)
Traceback (most recent call last):
    ...
valguard.exceptions.ValidationError: Invalid value: 23.0 lies outside [10.0, 20.0]
>>> interval_a.validate(bv)
Traceback (most recent call last):
    ...
valguard.exceptions.ValidationError: Invalid value: expected a numeric, got BoolValue(False)
>>> IntConstraint().validate(iv)
IntValue(23)
>>> IntConstraint().validate(iv).as_int
23
>>> NumericConstraint().validate(iv).to_float
23.0
>>> NumericConstraint().validate(bv).to_float
Traceback (most recent call last):
    ...
valguard.exceptions.ValidationError: Invalid value: expected a numeric, got BoolValue(False)

The implies function

The implies function determines whether one constraint implies another constraint. Constraint A implies constraint B if every value that satisfies A will also satisfy B.

>>> from valguard import BoundedIntConstraint, NumericConstraint, FloatConstraint, implies
>>> interval_A = BoundedIntConstraint(0,100)
>>> interval_B = BoundedIntConstraint(20,80)
>>> implies(interval_A, interval_B)
False
>>> implies(interval_B, interval_A)
True
>>> implies(interval_A, FloatConstraint)
False
>>> implies(interval_A, NumericConstraint)
True
>>> implies(NumericConstraint, interval_A)
False

Constraints that are parametrised (such as IntervalConstraint and LiteralStrConstraint) can be used in two ways: as an instance with specific parameters, or as a class. When used as a class, implies behaves differently depending on whether the class appears as the first or second argument to implies. As the first argument, implies(class, B) is True if all instances of class would imply B. As the second argument, implies(A, class) is True if at least one instance of class would be implied by A. For non-parametrised classes, there is no difference whether a class or an instance is used.

Constrained Value Dictionary

A ConstrainedValueDict behaves like a dictionary but its values are validated against a constraint at the time of insertion.

It is intentional that no type casting is performed, not even from int to IntValue.

>>> from valguard import IntValue, IntConstraint, ConstrainedValueDict
>>> d = ConstrainedValueDict(IntConstraint())                             
>>> d["one"] = IntValue(1)
>>> d["one"]
IntValue(1)
>>> d["two"] = 2
Traceback (most recent call last):
    ...
valguard.exceptions.ValidationError: Invalid value: expected an integer, got 2

Installation

pip install valguard

Project details


Download files

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

Source Distribution

valguard-1.0.0.tar.gz (13.3 kB view details)

Uploaded Source

Built Distribution

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

valguard-1.0.0-py3-none-any.whl (14.2 kB view details)

Uploaded Python 3

File details

Details for the file valguard-1.0.0.tar.gz.

File metadata

  • Download URL: valguard-1.0.0.tar.gz
  • Upload date:
  • Size: 13.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.3 CPython/3.13.5 Windows/11

File hashes

Hashes for valguard-1.0.0.tar.gz
Algorithm Hash digest
SHA256 f4dbba1f947d5151ba309940a2da61bd0b5352e484ac80a99388b0066c69c199
MD5 d680790fd965b73804b37cdf4268ac57
BLAKE2b-256 2b22f280f91be3e56a05a10c3a9f59bbcf99fd01f65ecb3e8f8a179c6aaa8f5d

See more details on using hashes here.

File details

Details for the file valguard-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: valguard-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 14.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.3 CPython/3.13.5 Windows/11

File hashes

Hashes for valguard-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 66ba8d3e8f44ad8f6e9b903b431e31ef8b8f31a365f36f972072b87d5442c42c
MD5 24421a4364fc563d81b4b0f245db1dea
BLAKE2b-256 441c98b9a00b930c803f48d52bacad578f918a23968cf83629346e70cf3a29f6

See more details on using hashes here.

Supported by

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