| name | dhi-python |
| description | Ultra-fast data validation library for Python (520x faster than Pydantic). Use when building validated data models, API request/response schemas, or configuration objects. Provides Pydantic v2-compatible BaseModel API with Zig-powered native validation. |
| license | MIT |
| metadata | {"dependencies":"dhi>=1.1.3","pypi":"https://pypi.org/project/dhi/","github":"https://github.com/justrach/dhi"} |
dhi - Ultra-Fast Python Validation
Overview
dhi is a high-performance data validation library for Python, powered by Zig and native C extensions. It provides a Pydantic v2-compatible API while being 520x faster for validation operations.
Use dhi when you need:
- Validated data models for APIs
- Fast request/response parsing
- Configuration object validation
- Type-safe data structures
Installation
pip install dhi
Quick Start
Basic Model
from dhi import BaseModel, Field
from typing import Annotated
class User(BaseModel):
name: Annotated[str, Field(min_length=1, max_length=100)]
age: Annotated[int, Field(ge=0, le=120)]
email: str
score: float = 0.0
user = User(name="Alice", age=25, email="alice@example.com")
print(user.model_dump())
Nested Models
from dhi import BaseModel
class Address(BaseModel):
street: str
city: str
zip_code: str
class Person(BaseModel):
name: str
address: Address
person = Person(
name="Bob",
address={"street": "123 Main St", "city": "NYC", "zip_code": "10001"}
)
Constrained Types
from dhi import BaseModel, PositiveInt, EmailStr, HttpUrl
from typing import Annotated
class Account(BaseModel):
user_id: PositiveInt
email: EmailStr
website: HttpUrl
balance: Annotated[float, Field(ge=0)]
Key Features
Pydantic v2 Compatible API
user = User.model_validate({"name": "Alice", "age": 25, "email": "a@b.com"})
user_dict = user.model_dump()
user_json = user.model_dump_json()
user_copy = user.model_copy(update={"age": 26})
ConfigDict Support
from dhi import BaseModel, ConfigDict
class StrictUser(BaseModel):
model_config = ConfigDict(
strict=True,
frozen=True,
extra='forbid',
str_strip_whitespace=True
)
name: str
age: int
Validators
from dhi import BaseModel, field_validator, model_validator
class User(BaseModel):
name: str
password: str
confirm_password: str
@field_validator('name')
@classmethod
def name_must_be_alpha(cls, v):
if not v.isalpha():
raise ValueError('must be alphabetic')
return v.title()
@model_validator(mode='after')
def passwords_match(self):
if self.password != self.confirm_password:
raise ValueError('passwords do not match')
return self
Computed Fields
from dhi import BaseModel, computed_field
class Rectangle(BaseModel):
width: float
height: float
@computed_field
@property
def area(self) -> float:
return self.width * self.height
Private Attributes
from dhi import BaseModel, PrivateAttr
class Model(BaseModel):
name: str
_secret: str = PrivateAttr(default="hidden")
_counter: int = PrivateAttr(default_factory=int)
Available Constrained Types
String Types
EmailStr - Valid email addresses
HttpUrl / AnyUrl - URL validation
IPvAnyAddress - IP address validation
Numeric Types
PositiveInt / NegativeInt
PositiveFloat / NegativeFloat
NonNegativeInt / NonPositiveInt
StrictInt / StrictFloat / StrictBool
Other Types
SecretStr / SecretBytes - Masked sensitive data
Json - JSON string parsing
UUID types
Field Constraints
from dhi import Field
Field(gt=0)
Field(ge=0)
Field(lt=100)
Field(le=100)
Field(multiple_of=5)
Field(min_length=1)
Field(max_length=100)
Field(pattern=r"^[a-z]+$")
Field(strict=True)
Field(frozen=True)
Field(exclude=True)
Serialization Options
user.model_dump(
mode='json',
by_alias=True,
exclude_unset=True,
exclude_defaults=True,
exclude_none=True,
include={'name'},
exclude={'password'},
)
Performance
dhi is 520x faster than Pydantic for validation operations:
| Operation | dhi | Pydantic | Speedup |
|---|
| Basic model | 2.55M/sec | 2.16M/sec | 1.18x |
| Nested model | 2.59M/sec | 2.23M/sec | 1.16x |
| model_dump | 4.37M/sec | 1.97M/sec | 2.22x |
| model_dump_json | 2.56M/sec | 1.77M/sec | 1.45x |
When to Use
Use dhi when:
- Building high-performance APIs (FastAPI, Flask, etc.)
- Processing large volumes of validated data
- Need Pydantic compatibility with better performance
- Building configuration systems with validation
Migration from Pydantic
dhi is designed as a drop-in replacement:
from pydantic import BaseModel, Field
from dhi import BaseModel, Field
Most Pydantic v2 code works unchanged with dhi.
Resources