Pydantic interop¶
The didactic-pydantic distribution provides two adapters for moving
Models between didactic and Pydantic v2.
Installation¶
The package contributes didactic.pydantic to the namespace.
from_pydantic¶
Convert a pydantic.BaseModel subclass into a dx.Model subclass:
from pydantic import BaseModel, Field
from didactic.pydantic import from_pydantic
class PydUser(BaseModel):
id: str
email: str = Field(description="primary contact")
User = from_pydantic(PydUser) # dx.Model subclass
u = User(id="u1", email="a@b.c")
Metadata that survives:
- field annotations, including
Annotated[T, ...]constraint metadata (Ge,Le,MinLen, ...) - defaults and factories
- aliases (
alias,validation_alias,serialization_aliascollapse to a singlealias) - descriptions, examples
- the
deprecatedflag json_schema_extralands underdx.field(extras=...)
Pydantic features that do not flow across:
@field_validatorand@model_validatormethods. Re-author with @dx.validates (per-field) or axioms (cross-field).@computed_field. Re-author with @dx.computed or @dx.derived.- Discriminated unions. Re-author as dx.TaggedUnion.
to_pydantic¶
The inverse direction. Use it to expose a dx.Model to FastAPI,
OpenAPI generators, or any other Pydantic-shaped tool:
import didactic.api as dx
from didactic.pydantic import to_pydantic
class User(dx.Model):
id: str
email: str = dx.field(description="primary contact")
PydUser = to_pydantic(User) # pydantic.BaseModel subclass
PydUser(id="u1", email="a@b.c")
The conversion is cached: a second call with the same input class returns the same Pydantic class.
Round-tripping¶
from_pydantic(to_pydantic(M)) and to_pydantic(from_pydantic(P))
both round-trip the cross-format-stable metadata exactly. Computed
fields and discriminated unions are dropped on the
dx.Model -> Pydantic direction; everything else survives.