Skip to main content

Pydantic meet Cypher, Cypher meet Pydantic.

Project description

cypherantic

Pydantic meet Cypher, Cypher meet Pydantic.

⚠️ ALPHA SOFTWARE: This project is in early development and has not been released. The API is subject to change without notice. Use at your own risk.

Overview

Cypherantic is a Python library that makes interacting with Neo4j simple and typesafe by leveraging Pydantic models. Define your graph structure using familiar Pydantic syntax, and let cypherantic handle the Cypher query generation and type validation.

Features

  • Type-safe graph modeling: Use Pydantic models to define nodes and relationships with full type checking support
  • Automatic constraint management: Unique constraints are created automatically based on field metadata
  • Relationship traversal: Navigate graph relationships with simple method calls that preserve type information
  • Async-first: Built on neo4j's async driver for modern Python applications
  • Zero boilerplate: No manual Cypher query writing for common operations

Installation

Since this is an unreleased alpha project, install directly from source:

uv pip install git+https://github.com/yourusername/cypherantic.git

Quick Example

Using the Neo4j movies database as an example:

import typing
import neo4j
import pydantic
import cypherantic


class MovieReviewEdge(typing.NamedTuple):
    node: 'User'
    properties: 'MovieReview'


class Movie(pydantic.BaseModel):
    title: typing.Annotated[str, cypherantic.Field(unique=True)]
    released: typing.Annotated[int, cypherantic.Field(unique=True)]
    tagline: str | None = None
    reviews: typing.Annotated[
        list[MovieReviewEdge],
        cypherantic.Relationship(rel_type='REVIEWED', direction='INCOMING'),
    ] = []


class User(pydantic.BaseModel):
    cypherantic_config: typing.ClassVar[cypherantic.NodeConfig] = {
        'labels': ['Person'],
    }
    name: typing.Annotated[str, cypherantic.Field(unique=True)]


class MovieReview(pydantic.BaseModel):
    cypherantic_config: typing.ClassVar[cypherantic.RelationshipConfig] = {
        'rel_type': 'REVIEWED',
    }
    rating: float
    summary: str


async def main() -> None:
    async with neo4j.AsyncGraphDatabase().driver(
        'bolt://localhost:7687', auth=('neo4j', 'password')
    ) as driver:
        movie = Movie(
            title='Cloud Atlas',
            released=2012,
            tagline='Everything is connected',
        )
        async with driver.session() as session:
            # Load all reviews for the movie
            await cypherantic.refresh_relationship(session, movie, 'reviews')
            for edge in movie.reviews:
                print(f'{edge.node.name}: {edge.properties.rating}/5')

Key Concepts

Node Models

Define graph nodes using Pydantic models. Use cypherantic.Field(unique=True) to mark properties that should have uniqueness constraints:

class Person(pydantic.BaseModel):
    name: typing.Annotated[str, cypherantic.Field(unique=True)]
    born: int

Override the node labels using the cypherantic_config class variable:

class User(pydantic.BaseModel):
    cypherantic_config: typing.ClassVar[cypherantic.NodeConfig] = {
        'labels': ['Person', 'User'],
    }
    name: str

Relationship Models

Define relationship properties using Pydantic models with a cypherantic_config that specifies the relationship type:

class ActedIn(pydantic.BaseModel):
    cypherantic_config: typing.ClassVar[cypherantic.RelationshipConfig] = {
        'rel_type': 'ACTED_IN',
    }
    roles: list[str]

Edge Types

Connect nodes and relationship properties using NamedTuples:

class ActedInEdge(typing.NamedTuple):
    node: Movie
    properties: ActedIn

Relationships on Node Models

Declare relationships on node models using the cypherantic.Relationship annotation:

class Actor(pydantic.BaseModel):
    name: str
    movies: typing.Annotated[
        list[ActedInEdge],
        cypherantic.Relationship(rel_type='ACTED_IN', direction='OUTGOING'),
    ] = []

Core API

Node Operations

  • create_node(session, model): Create a node from a Pydantic model
  • unwrap_node_as(model_cls, node): Convert a Neo4j node to a Pydantic model

Relationship Operations

  • create_relationship(session, from_node, to_node, rel_props): Create a relationship between nodes
  • refresh_relationship(session, model, rel_property): Load relationship edges into a model's relationship field
  • retrieve_relationship_edges(session, model, rel_name, direction, edge_cls): Retrieve relationship edges with full type information

Requirements

  • Python 3.12+
  • Neo4j 6.0+
  • Pydantic 2.12+

License

BSD-3-Clause License. See LICENSE file for details.

Contributing

Since this is an alpha project, contributions and feedback are welcome. Please open an issue to discuss proposed changes.

Project details


Download files

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

Source Distribution

cypherantic-0.0.1.tar.gz (69.5 kB view details)

Uploaded Source

Built Distribution

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

cypherantic-0.0.1-py3-none-any.whl (8.2 kB view details)

Uploaded Python 3

File details

Details for the file cypherantic-0.0.1.tar.gz.

File metadata

  • Download URL: cypherantic-0.0.1.tar.gz
  • Upload date:
  • Size: 69.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for cypherantic-0.0.1.tar.gz
Algorithm Hash digest
SHA256 0e1e315d6be2b6156ef88069fb661005943073590adc044f2ee46e761d05675b
MD5 38457b0de7a30fc047b6c80f532f6c73
BLAKE2b-256 bf38839b2cd8bd244ded23c840ea6c924c8ec39dfa849616c69368ffb5ddf14c

See more details on using hashes here.

Provenance

The following attestation bundles were made for cypherantic-0.0.1.tar.gz:

Publisher: publish.yml on dave-shawley/cypherantic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cypherantic-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: cypherantic-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 8.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for cypherantic-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e546356579f259a3afd3d136604889c7537de3e1375d8c5c4d98e68f9f9347e9
MD5 4007898ec8259cd2b3d2ad125b0abd40
BLAKE2b-256 1e24dd91cd82b123ea26af27cf199470f977bc432f1aa69526c452e37e026cd3

See more details on using hashes here.

Provenance

The following attestation bundles were made for cypherantic-0.0.1-py3-none-any.whl:

Publisher: publish.yml on dave-shawley/cypherantic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page