ORM like library and CLI for cypher query language supporting graph databases.
Project description
CypherGraphDB Library
Overview
CypherGraphDB is a unified Python toolkit for working with Cypher-capable graph databases. It provides three core capabilities:
1. Generalized API - Vendor-Neutral Graph Database Access
Work with multiple graph database backends through a unified, consistent interface:
- Vendor Neutrality – Same API works across Apache AGE, Memgraph, and other Cypher databases
- Extensible Architecture – Add new backends by implementing the
CypherBackendabstract class - Connection Management – Pooled connections with automatic reconnection and configuration
- Query Execution – Direct Cypher queries with result processing and statistics
- Data Exchange – Built-in import/export tools for CSV, Excel, JSON formats
- Schema Operations – Graph introspection, schema dumping, and analysis tools
2. Typed ORM-Like Access Layer
Optional Pydantic-based object mapping for type-safe graph operations:
- Model Decorators –
@node,@edge,@relationfor defining graph schemas - Type Safety – Automatic validation and IDE support with autocompletion
- Custom Methods – Add business logic directly to your graph models
- Schema Generation – Automatic JSON schema generation from Python models
3. Interactive CLI - Vendor-Neutral Graph Database Operations
Comprehensive command-line interface that works identically across all supported backends:
- 44+ Commands – Full suite of graph operations, schema management, and analysis tools
- Rich Formatting – Colorized output with tables, trees, and JSON highlighting
- Cross-Platform – Same commands work with Apache AGE, Memgraph, or any supported backend
- Interactive Exploration – Real-time graph querying and visualization
Supported Backends
- age – Apache AGE extension on PostgreSQL
- memgraph – Memgraph database via Bolt protocol
Extensible: Add new Cypher-compatible backends by implementing the CypherBackend abstract class.
Prerequisites
| Tool | Purpose | Install |
|---|---|---|
| Python 3.13+ | Runtime | uv python install 3.13 |
| uv | Dependency & venv manager | curl -LsSf https://astral.sh/uv/install.sh | sh |
| Task | Automation | brew install go-task |
| Docker | Integration tests | brew install --cask docker |
Quick Start
git clone https://github.com/petrarca/cypher-graphdb-core.git
cd cypher-graphdb-core
task install # Create venv + install library
task test:unit # Run unit tests
task run:cli # Launch interactive CLI
Backend Configuration
Apache AGE (backend="age")
Apache AGE runs as a PostgreSQL extension. Connection strings use PostgreSQL format.
Key Parameters:
| Parameter | Description | Default |
|---|---|---|
host |
PostgreSQL server hostname | localhost |
port |
PostgreSQL server port | 5432 |
dbname |
Database name | (required) |
user |
Username for authentication | - |
password |
Password for authentication | - |
graph_name |
AGE graph name to use/create | - |
Connection Examples:
# CLI with connection info
cypher-graphdb --backend age --cinfo "host=localhost port=5432 dbname=postgres"
# Environment variable
export CGDB_CINFO="postgresql://postgres:secret@localhost:5432/postgres"
cypher-graphdb --backend age
Memgraph (backend="memgraph")
Memgraph uses the Bolt protocol for connections.
Key Parameters:
| Parameter | Description | Default |
|---|---|---|
host |
Memgraph server hostname | 127.0.0.1 |
port |
Memgraph Bolt port | 7687 |
username |
Username for authentication | (empty) |
password |
Password for authentication | (empty) |
Connection Formats:
- Bolt URI:
bolt://[username:password@]hostname:port - Key=value:
host=localhost port=7687 username=user password=secret - Partial:
port=1234orhost=192.168.1.100
Connection Examples:
# Bolt URI
cypher-graphdb --backend memgraph --cinfo "bolt://localhost:7687"
# Environment variable
export CGDB_CINFO="bolt://user:pass@localhost:7687"
cypher-graphdb --backend memgraph
1. Generalized API Usage
Vendor-Neutral Database Access
The unified API provides consistent access to different graph database backends:
Connection (Recommended)
The recommended connection method is connect_url for simplicity:
from cypher_graphdb import CypherGraphDB
# Memgraph - recommended
db = CypherGraphDB(backend="memgraph", connect_url="bolt://localhost:7687")
# Apache AGE
db = CypherGraphDB(backend="age", connect_url="postgresql://postgres:secret@localhost:5432/postgres")
# Context manager (recommended - auto-cleanup)
with CypherGraphDB(backend="memgraph", connect_url="bolt://localhost:7687") as db:
result = db.execute("RETURN 1 AS value", unnest_result=True)
print(result) # 1
Alternative connection methods (CINFO parameter, individual params, environment variables) are also supported. See documentation for details.
Configuration
The library reads configuration from environment variables (can be overridden by CLI flags or constructor parameters):
| Setting | Env Var | CLI Flag | Default | Description |
|---|---|---|---|---|
| backend | CGDB_BACKEND |
-b / --backend |
None |
Backend type (memgraph, age) |
| cinfo | CGDB_CINFO |
-c / --cinfo |
None |
Connection string / DSN |
| graph | CGDB_GRAPH |
-g / --graph |
None |
Graph name (backend-specific) |
| read_only | CGDB_READ_ONLY |
-r / --read-only |
False |
Block write operations |
| create_graph | CGDB_CREATE_GRAPH_IF_NOT_EXISTS |
- | False |
Auto-create graph if missing (AGE only) |
Precedence: CLI arguments > Environment variables > Constructor parameters > Defaults
Example .env files:
.env.memgraph.example- Pre-configured for Memgraph Docker Compose stack.env.age.example- Pre-configured for Apache AGE Docker Compose stack
Copy the appropriate example file to .env and the library will automatically load it:
# For Memgraph
cp .env.memgraph.example .env
# For Apache AGE
cp .env.age.example .env
Basic Queries
from cypher_graphdb import CypherGraphDB
db = CypherGraphDB(backend="memgraph", connect_url="bolt://localhost:7687")
# Execute query with multiple results
rows = db.execute("MATCH (n:Person) RETURN n.name, n.age LIMIT 5")
for name, age in rows:
print(f"{name}: {age}")
# Unnest single scalar result
count = db.execute("MATCH (n) RETURN count(n)", unnest_result=True)
print(f"Total nodes: {count}") # 42
# Fetch one row
result = db.execute("RETURN 1 AS x, 2 AS y", fetch_one=True, unnest_result=True)
print(result) # (1, 2)
Create & Merge Nodes and Edges
from cypher_graphdb import CypherGraphDB, GraphNode, GraphEdge
db = CypherGraphDB(backend="memgraph", connect_url="bolt://localhost:7687")
# Create nodes
person = GraphNode(label_="Person", properties_={"name": "Alice", "age": 30})
person = db.create_or_merge(person) # Returns node with ID assigned
print(f"Created person with ID: {person.id_}")
company = GraphNode(label_="Company", properties_={"name": "TechCorp"})
company = db.create_or_merge(company)
# Create relationship
rel = GraphEdge.build(person, company, label_="WORKS_FOR", properties_={"since": 2020})
rel = db.create_or_merge(rel)
print(f"Created relationship: {person.properties_['name']} WORKS_FOR {company.properties_['name']}")
Fetch Nodes (Multiple Methods)
from cypher_graphdb import CypherGraphDB
db = CypherGraphDB(backend="memgraph", connect_url="bolt://localhost:7687")
# Fetch by database ID
node = db.fetch_nodes(12345, unnest_result=True)
# Fetch by GID (string identifier)
node = db.fetch_nodes("6f628f1e7tFZHfis", unnest_result=True)
# Fetch by properties
nodes = db.fetch_nodes({"label_": "Product", "name": "CypherGraph"})
# Fetch all nodes of a type (with typed models)
from my_models import Product
products = db.fetch_nodes({"label_": Product})
Bulk Data Setup
from cypher_graphdb import CypherGraphDB
db = CypherGraphDB(backend="memgraph", connect_url="bolt://localhost:7687")
# Create multiple nodes and relationships in one query
db.execute("""
CREATE (p1:Person {name: 'Alice', age: 30, email: 'alice@example.com'})
CREATE (p2:Person {name: 'Bob', age: 25, email: 'bob@example.com'})
CREATE (c:Company {name: 'TechCorp', founded: 2010})
CREATE (p1)-[:WORKS_FOR {since: 2020, role: 'Engineer'}]->(c)
CREATE (p2)-[:WORKS_FOR {since: 2021, role: 'Designer'}]->(c)
CREATE (p1)-[:KNOWS {since: 2019}]->(p2)
""")
3. Interactive CLI - Vendor-Neutral Graph Operations
The library includes a comprehensive interactive CLI with 44+ commands for exploring graph databases. The CLI provides identical functionality across all supported backends.
Running the CLI
# Using task automation
task run:cli
# Direct execution
.venv/bin/cypher-graphdb
Command Categories
Connection Management:
connect memgraph bolt://localhost:7687– Connect to Memgraphconnect age postgresql://...– Connect to Apache AGEdisconnect– Close current connection
Query Execution:
MATCH (n) RETURN n LIMIT 5;– Execute any Cypher querystats– Show last query execution statisticsformat_output– Configure result display format
Graph Operations:
create_node– Create nodes with propertiescreate_edge– Create relationships between nodesfetch_nodes– Retrieve nodes by criteriafetch_edges– Retrieve edges by criteriadelete_graphobj– Remove nodes or edges
Schema & Introspection:
dump_schema– Export graph schema definitionsdump_labels– List all node and edge labelsdump_models– Show registered model classesload_models– Import model definitions
Import/Export:
import_graph– Load data from CSV, Excel, JSON filesexport_graph– Export graph data to various formats
Schema Generation:
schema generate– Generate JSON schema from Python models (standalone, no DB required)
Transaction Control:
commit– Commit current transactionrollback– Rollback current transaction
Utilities:
help– Show all available commandsexit– Exit CLI (aliases:quit,q,bye)search– Full-text search across graph datagraph_to_tree– Visualize graph structure as tree
Vendor Neutrality: All CLI commands work identically across Apache AGE, Memgraph, and any other supported backend.
Schema Generation (Standalone)
Generate JSON schema files from Python graph models without requiring a database connection:
# Generate from a single Python file
cypher-graphdb schema generate --models ./models.py --output ./schemas/
# Generate from a package directory (with __init__.py)
cypher-graphdb schema generate -m ./graph_models/ -o ./output/
# Specify output filename
cypher-graphdb schema generate -m ./models.py -o ./my-schema.json
# With verbose output
cypher-graphdb schema generate -m ./models.py -o ./schemas/ --verbose
# Skip confirmation prompt
cypher-graphdb schema generate -m ./models.py -o ./schemas/ --yes
Options:
-m, --models– Path to Python file or directory with@node/@edgedecorated models-o, --output– Output path (directory usesgraph.schema.json, or specify filename)-v, --verbose– Show detailed output--overwrite– Overwrite existing file without prompting-y, --yes– Skip confirmation prompt
Package Support: Directories with __init__.py are loaded as packages, enabling relative imports between model files.
2. Typed ORM-Like Access Layer
Define typed models with decorators for better type safety and metadata:
from cypher_graphdb import GraphNode, GraphEdge, node, edge, relation
@node(label="Product")
@relation(rel_type="USES_TECHNOLOGY", to_type="Technology")
class Product(GraphNode):
name: str
multi_tenancy: bool | None = None
@node(label="Technology")
class Technology(GraphNode):
name: str
@edge(label="USES_TECHNOLOGY")
class UsesTechnology(GraphEdge):
version: str | None = None
Using Typed Models
from cypher_graphdb import CypherGraphDB
db = CypherGraphDB(backend="memgraph", connect_url="bolt://localhost:7687")
# Create typed nodes
demo_product = Product(name="CypherGraph Demo", multi_tenancy=True)
db.create_or_merge(demo_product)
demo_technology = Technology(name="Python")
db.create_or_merge(demo_technology)
# Create typed relationship
demo_relation = UsesTechnology.build(demo_product, demo_technology, version="3.13")
db.create_or_merge(demo_relation)
# Fetch typed nodes
products = db.fetch_nodes({"label_": Product})
for product in products:
print(f"Product: {product.name}, Multi-tenant: {product.multi_tenancy}")
Result Unnesting
Simplify common query patterns:
# Single scalar
value = db.execute("RETURN 42", unnest_result=True) # 42 (not [(42,)])
# Single row
row = db.execute("RETURN 1, 2", fetch_one=True, unnest_result=True) # (1, 2)
Task Automation
| Task | Purpose |
|---|---|
install |
Install library with dependencies |
test:unit |
Run unit tests |
test:integration |
Integration tests (requires Docker) |
format |
Format code with Ruff |
check |
Lint and check code quality |
run:cli |
Run interactive CLI |
fct |
Format + check + test |
Development Workflow
See CONTRIBUTING.md for the development workflow and guidelines.
Documentation
Library documentation is built with MkDocs:
task build:docs # Build docs site
Output: site/ directory. API reference auto-generated from docstrings.
License
Apache License 2.0 -- see LICENSE.md.
Happy graph hacking!
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cypher_graphdb-0.1.2.tar.gz.
File metadata
- Download URL: cypher_graphdb-0.1.2.tar.gz
- Upload date:
- Size: 523.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
74459f58052f932c8b92e3a4329b6e5b07953080eac7c85353119fc9ab04388a
|
|
| MD5 |
5e25d4e9c67d461aad6a77d37fea9d34
|
|
| BLAKE2b-256 |
232ae503192dce4eed14d18829780b0e924fdc2c2b90fe41eeb5931d38e4175d
|
Provenance
The following attestation bundles were made for cypher_graphdb-0.1.2.tar.gz:
Publisher:
publish.yml on petrarca/cypher-graphdb-core
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cypher_graphdb-0.1.2.tar.gz -
Subject digest:
74459f58052f932c8b92e3a4329b6e5b07953080eac7c85353119fc9ab04388a - Sigstore transparency entry: 1318344576
- Sigstore integration time:
-
Permalink:
petrarca/cypher-graphdb-core@3c338c8ab9642e46b202fae4c5c844efaed4c096 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/petrarca
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3c338c8ab9642e46b202fae4c5c844efaed4c096 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cypher_graphdb-0.1.2-py3-none-any.whl.
File metadata
- Download URL: cypher_graphdb-0.1.2-py3-none-any.whl
- Upload date:
- Size: 447.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e3ecac6ba8855d257fc72c74df96b32a02922a0328dd1c1af25148f2e8744330
|
|
| MD5 |
1a2528af5c83c839deb074b53e242c67
|
|
| BLAKE2b-256 |
d2df7e0c08a12469df1229d28e9ee07974e402e023f46c794b8fe7ec98ee3874
|
Provenance
The following attestation bundles were made for cypher_graphdb-0.1.2-py3-none-any.whl:
Publisher:
publish.yml on petrarca/cypher-graphdb-core
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cypher_graphdb-0.1.2-py3-none-any.whl -
Subject digest:
e3ecac6ba8855d257fc72c74df96b32a02922a0328dd1c1af25148f2e8744330 - Sigstore transparency entry: 1318344660
- Sigstore integration time:
-
Permalink:
petrarca/cypher-graphdb-core@3c338c8ab9642e46b202fae4c5c844efaed4c096 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/petrarca
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3c338c8ab9642e46b202fae4c5c844efaed4c096 -
Trigger Event:
push
-
Statement type: