Skip to content

Declare an ontology with Python classes again - #345

Merged
paul-paliychuk merged 1 commit into
v4from
feat/v4-ontology-dsl
Aug 25, 2026
Merged

Declare an ontology with Python classes again#345
paul-paliychuk merged 1 commit into
v4from
feat/v4-ontology-dsl

Conversation

@paul-paliychuk

Copy link
Copy Markdown
Contributor

set_ontology takes lists of EntityType and EdgeType, so building an ontology by hand means repeating every property's name, type and description as data. Earlier SDK versions let you declare it once as Pydantic classes and derived the payload; that layer targeted the old types and was dropped when this branch moved to generated output.

Usage

from zep_cloud.ontology import EdgeModel, EntityModel, EntityText, build_ontology
from zep_cloud.types import EdgeSourceTarget

class Traveler(EntityModel):
    """Someone who takes trips."""
    home_city: EntityText = None

class TraveledTo(EdgeModel):
    """A traveler visiting a destination."""
    purpose: EntityText = Field(default=None, description="Why they went")

entity_types, edge_types = build_ontology(
    entities={"Traveler": Traveler},
    edges={"TRAVELED_TO": (TraveledTo, [EdgeSourceTarget(
        source_entity_type="Traveler", target_entity_type="Destination")])},
)
client.graph.set_ontology(graph_uuid, entity_types=entity_types, edge_types=edge_types)

The same output goes to client.project.set_ontology for the project default. The class docstring becomes the type description; a field's description becomes the property description.

Two deliberate differences from the old layer

A function, not a client subclass. The generated clients expose sub-clients as read-only properties and already define set_ontology, so subclassing collided with both. A function also means one hand-written file to preserve instead of five.

The property type comes off an annotation marker, not a JSON-schema round trip. Shorter, and it keeps the wire spelling in a single place — which matters because the generated EntityPropertyType is a Literal union rather than an enum, so there are no members to reference.

Behavior worth noting

An unannotated field raises, naming the field:

ValueError: Bad.oops is not an ontology property: annotate it with
EntityText, EntityInt, EntityFloat or EntityBoolean

Silently dropping it would ship an ontology missing a property the caller declared.

Verification

mypy clean across 168 files; 7 new tests covering type derivation, each annotation's wire value, field descriptions, source targets present and absent, the unannotated-field error, and empty input.

Adds src/zep_cloud/ontology.py and tests/ontology/ to .fernignore — everything it builds on (EntityType, EdgeType, EntityProperty) stays generated. Also drops two stale .fern/replay entries whose file no longer exists.

set_ontology takes lists of EntityType and EdgeType, so building an ontology
by hand means repeating every property's name, type and description as data.
v3 let a caller declare it once as Pydantic classes and derived the payload;
that layer targeted v3 types and was dropped when this branch moved to
generated output.

Adds zep_cloud.ontology: annotate model fields with EntityText, EntityInt,
EntityFloat or EntityBoolean, and build_ontology returns the two lists to hand
to graph.set_ontology or project.set_ontology.

Two differences from the v3 layer, both deliberate. It is a function rather
than a client subclass: the generated clients expose sub-clients as read-only
properties and already define set_ontology, so subclassing collided with
both, and a function needs one frozen file instead of five. And the property
type comes off an annotation marker rather than a JSON-schema round trip,
which is shorter and keeps the wire spelling in one place.

An unannotated field is an error naming the field, rather than being dropped:
silently omitting a declared property would ship an ontology missing part of
what the caller wrote.

Also drops two stale .fern/replay entries from .fernignore. The lock file was
removed when Replay was reset, and Fern owns that state.
@paul-paliychuk
paul-paliychuk merged commit b4fcb71 into v4 Aug 25, 2026
4 checks passed
@paul-paliychuk
paul-paliychuk deleted the feat/v4-ontology-dsl branch August 25, 2026 16:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant