Advanced State¶
Draive models are typed State classes. Schema and JSON support is derived from the declared
field types. Adding State, serializable=True turns that into a requirement, so a class whose
fields cannot produce a JSON schema fails at declaration time instead of silently losing it.
Serialization And Schema¶
from draive import State
from draive.utils import simplified_schema
class Example(State, serializable=True):
name: str
value: int
item = Example(name="converted", value=42)
encoded = item.to_json()
decoded = Example.from_json(encoded)
print(decoded)
print(Example.json_schema(indent=2))
print(simplified_schema(Example.__SPECIFICATION__, indent=2))
json_schema(...) is precise and machine-oriented; simplified_schema(...) is compact and often
useful when injecting schema hints into LLM prompts.
strict_schema(...) sits next to it and converts a JSON schema into its OpenAI strict mode
equivalent, returning None when the schema holds something strict mode cannot express.
Immutability And Updates¶
from draive import State
class MutableExample(State):
identifier: str
value: int
initial = MutableExample(identifier="pre", value=42)
updated = initial.updating(identifier="post")
Schema Customization With Annotations¶
You can enrich field schema using Annotated metadata.
from typing import Annotated
from draive import Alias, Description, Specification, State
class Customized(State, serializable=True):
described: Annotated[int, Description("Field description")]
aliased: Annotated[str, Alias("field_alias")]
fully_custom: Annotated[int, Specification({"type": "integer", "description": "Custom"})]
print(Customized.json_schema(indent=2))
Defaults And Factories¶
from collections.abc import Sequence
from draive import Default, State
class Defaults(State, serializable=True):
retries: int = 3
tags: Sequence[str] = Default(factory=tuple)
Attribute Paths And Requirements¶
Attribute paths let you reference fields in a typed way for indexing, filtering, and reusable rules.
from collections.abc import Sequence
from typing import cast
from draive import AttributePath, AttributeRequirement, State
class Nested(State, serializable=True):
values: Sequence[int]
class Model(State, serializable=True):
nested: Nested
value: int
instance = Model(nested=Nested(values=(42, 21)), value=21)
# `Model._` mimics the model type for static typing, so paths pass straight into
# APIs accepting them - like the requirement below or `VectorIndex.index(attribute=...)`.
# Keeping one around and applying it yourself requires a local cast to its actual type.
path = cast(AttributePath[Model, Sequence[int]], Model._.nested.values)
print(path(instance))
req = AttributeRequirement[Model].equal(42, path=Model._.nested.values[0])
print(req.check(instance))