Skip to content

ucon.integrations.pydantic

Pydantic v2 integration for type-safe dimensional fields. Install with pip install ucon[pydantic].

ucon.pydantic

Pydantic v2 integration for ucon.

Provides type-annotated wrappers for use in Pydantic models with full JSON serialization support.

Usage

from pydantic import BaseModel from ucon.pydantic import Number

class Measurement(BaseModel): ... value: Number ... m = Measurement(value={"quantity": 5, "unit": "km"}) print(m.value) <5 km> print(m.model_dump_json()) {"value": {"quantity": 5.0, "unit": "km", "uncertainty": null}}

Installation

Requires Pydantic v2. Install with::

pip install ucon[pydantic]

Number = _NumberType module-attribute

Pydantic-compatible Number type with optional dimension constraints.

Use this as a type hint in Pydantic models to enable automatic validation and JSON serialization of ucon Number instances.

Basic usage (any dimension)::

from pydantic import BaseModel
from ucon.pydantic import Number

class Measurement(BaseModel):
    value: Number

m = Measurement(value={"quantity": 5, "unit": "km"})
print(m.value)  # <5 km>

With dimension constraint::

from ucon import Dimension
from ucon.pydantic import Number

class Vehicle(BaseModel):
    mass: Number[Dimension.mass]
    speed: Number[Dimension.velocity]

# Valid
v = Vehicle(
    mass={"quantity": 1500, "unit": "kg"},
    speed={"quantity": 100, "unit": "km/h"}
)

# Invalid - wrong dimension
Vehicle(
    mass={"quantity": 5, "unit": "m"},  # ValueError: expected 'mass', got 'length'
    speed={"quantity": 100, "unit": "km/h"}
)

From Number instance::

from ucon import units
m2 = Measurement(value=units.meter(10))

Serialize to JSON::

print(m.model_dump_json())
# {"value": {"quantity": 5.0, "unit": "km", "uncertainty": null}}

constrained_number(*validators)

Factory to create subscriptable Number types with additional validators.

Usage::

from pydantic.functional_validators import AfterValidator

def must_be_positive(n):
    if n.quantity <= 0:
        raise ValueError("must be positive")
    return n

PositiveNumber = constrained_number(AfterValidator(must_be_positive))

class Model(BaseModel):
    value: PositiveNumber[Dimension.time]  # positive time value