Skip to main content

uni-pydantic

Pydantic-based OGM (Object-Graph Mapping) for the Uni Graph Database.

PyPI License

Features

  • Type Safety: Full IDE autocomplete and type checking for graph operations.
  • Pydantic v2: Leverage Pydantic's validation, computed fields, and serialization.
  • Schema-from-Models: Auto-generate Uni schema from Pydantic model definitions.
  • Relationships: Edges as declarative fields with direction support.
  • Query DSL: Type-safe filter builder with raw Cypher escape hatch.
  • Vector Search: Built-in K-NN similarity search.
  • Lifecycle Hooks: @before_create, @after_create decorators.

Installation

pip install uni-pydantic

Quick Start

import uni_db
from uni_pydantic import UniNode, UniEdge, UniSession, Field, Relationship, Vector

# Define models
class Person(UniNode):
    __label__ = "Person"

    name: str
    age: int | None = None
    email: str = Field(unique=True, index="btree")
    embedding: Vector[128] = Field(metric="cosine")

    friends: list["Person"] = Relationship("FRIEND_OF", direction="both")


class Company(UniNode):
    __label__ = "Company"

    name: str = Field(unique=True)


class WorksAt(UniEdge):
    __edge_type__ = "WORKS_AT"
    __from__ = Person
    __to__ = Company

    role: str = "engineer"


# Connect and sync schema
db = uni_db.Uni("./my_graph")
session = UniSession(db)
session.register(Person, Company, WorksAt)
session.sync_schema()

# Create
alice = Person(name="Alice", age=30, email="alice@example.com")
session.add(alice)
session.commit()

# Query with DSL
adults = (
    session.query(Person)
    .filter(Person.age >= 18)
    .order_by(Person.name)
    .limit(10)
    .all()
)

# Vector search
similar = (
    session.query(Person)
    .vector_search("embedding", query_vector, k=10)
    .all()
)

Model Definition

Nodes

from uni_pydantic import UniNode, Field, Vector

class Article(UniNode):
    __label__ = "Article"      # optional — defaults to class name

    title: str
    slug: str = Field(index="btree", unique=True)
    views: int = Field(default=0)
    tags: list[str] = Field(default_factory=list)
    embedding: Vector[768] = Field(metric="cosine")

Edges

from uni_pydantic import UniEdge

class Authored(UniEdge):
    __edge_type__ = "AUTHORED"
    __from__ = Person
    __to__ = Article

    role: str = "primary"

Relationships

class Person(UniNode):
    follows:   list["Person"]        = Relationship("FOLLOWS")
    followers: list["Person"]        = Relationship("FOLLOWS", direction="incoming")
    friends:   list["Person"]        = Relationship("FRIEND_OF", direction="both")
    manager:   "Person | None"       = Relationship("REPORTS_TO")

Query DSL

# Filter
people = session.query(Person).filter(Person.name == "Alice").all()

# Chained
results = (
    session.query(Person)
    .filter(Person.age >= 18)
    .order_by(Person.name, descending=True)
    .limit(10)
    .skip(20)
    .all()
)

# Filter helpers
Person.name.starts_with("A")
Person.name.contains("lic")
Person.age.in_([25, 30, 35])
Person.email.is_null()
Person.email.is_not_null()

# Vector search
similar = (
    session.query(Person)
    .vector_search("embedding", query_vec, k=10)
    .all()
)

CRUD

# Create
person = Person(name="Bob", age=25)
session.add(person)
session.commit()

# Bulk
session.add_all([Person(name=f"User{i}") for i in range(100)])
session.commit()

# Update
person.age = 26
session.commit()

# Delete
session.delete(person)
session.commit()

Lifecycle Hooks

from datetime import datetime
from uni_pydantic import before_create, after_create

class Person(UniNode):
    name: str
    created_at: datetime | None = None

    @before_create
    def set_created_at(self):
        self.created_at = datetime.now()

    @after_create
    def log_creation(self):
        print(f"Created: {self.name}")

Raw Cypher

results = session.cypher(
    "MATCH (p:Person)-[:FRIEND_OF]->(f:Person) WHERE p.name = $name RETURN f",
    params={"name": "Alice"},
    result_type=Person,
)

Async

from uni_pydantic import AsyncUniSession

session = AsyncUniSession(db)
await session.sync_schema()

alice = Person(name="Alice", email="alice@example.com")
session.add(alice)
await session.commit()

results = await session.query(Person).filter(Person.age >= 18).all()

Links

License

Apache-2.0

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

uni_pydantic-3.2.0.tar.gz (212.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

uni_pydantic-3.2.0-py3-none-any.whl (50.6 kB view details)

Uploaded Python 3

File details

Details for the file uni_pydantic-3.2.0.tar.gz.

File metadata

  • Download URL: uni_pydantic-3.2.0.tar.gz
  • Upload date:
  • Size: 212.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for uni_pydantic-3.2.0.tar.gz
Algorithm Hash digest
SHA256 35534a767721c389e604a1181ad1a5072d4f70b551eb8715385b5748328be54e
MD5 04b111350d90f6af1418659b45970ca5
BLAKE2b-256 35e16996bc0ad8dc518dfdd725a70bf08daa4d9ec79909330638ed3d0ea44457

See more details on using hashes here.

File details

Details for the file uni_pydantic-3.2.0-py3-none-any.whl.

File metadata

  • Download URL: uni_pydantic-3.2.0-py3-none-any.whl
  • Upload date:
  • Size: 50.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for uni_pydantic-3.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3f51831c91ccaf295f5b118d8f7224586b60c9aa559bae722d75196ecf9485ab
MD5 85493848dd933de9c66fb97a2573f88b
BLAKE2b-256 c7ee99f3dea5c53a81f36bd81f14cf3199a42e5d7a40e54c762fc3d090a6bcec

See more details on using hashes here.

Release history Release notifications | RSS feed

3.4.0

2 files

3.3.0

2 files

This release

3.2.0 This release

2 files

3.0.1

2 files

3.0.0

2 files

2.4.1

2 files

2.3.0

2 files

2.2.5

2 files

1.1.0

2 files

1.0.2

2 files

1.0.0

2 files

0.3.0

2 files

0.2.0

2 files

0.1.18

2 files

0.1.17

2 files

0.1.6

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page