How to Integrate Neo4j as a Graph Store Backend in Semantica: A Complete Setup Guide

To integrate Neo4j as a graph store backend in Semantica, install the Neo4j Python driver, configure the backend in your semantica.yaml file or via CLI flags, and instantiate the GraphStore with the "neo4j" backend identifier.

Semantica provides a pluggable graph-store architecture that supports multiple backends including Neo4j, Amazon Neptune, FalkorDB, and an in-memory store. This guide walks you through configuring Neo4j integration using the actual source implementation from the semantica-agi/semantica repository.


Architecture Overview

The Neo4j integration in Semantica consists of three core modules:

Component File Path Purpose
Neo4jStore semantica/graph_store/neo4j_store.py Low-level CRUD operations, Cypher query generation, and transaction management
Backend Registry semantica/graph_store/registry.py Maps the "neo4j" string identifier to the Neo4jStore implementation class
Configuration Parser semantica/graph_store/config.py Pydantic models for validating Neo4j connection settings (URI, auth, TLS)

All high-level graph operations in Semantica route through the GraphStore facade, which delegates to Neo4jStore when the backend parameter is set to "neo4j".


Step 1: Install the Neo4j Python Driver

Semantica keeps the core framework lightweight by not bundling backend-specific drivers. Add the official Neo4j driver to your environment:

pip install neo4j

The neo4j_store.py module imports the driver at line 251:

from neo4j import GraphDatabase

This provides the GraphDatabase.driver() method used for connection pooling and session management.


Step 2: Configure the Neo4j Backend

Semantica reads configuration from a YAML file (default: semantica.yaml in the project root). Add a graph_db section with the Neo4j backend specified:

graph_db:
  backend: neo4j
  uri: bolt://localhost:7687
  username: neo4j
  password: your_secure_password
  
  # Optional TLS configuration

  tls: false
  # tls_cert_path: /path/to/ca-cert.pem

The GraphStoreConfig class in semantica/graph_store/config.py validates these fields and provides defaults for optional parameters.


Step 3: Initialize the Graph Store

Option A: Using the Semantica CLI

The CLI provides a convenience command for connecting to a graph store backend:

semantica store connect \
    --backend neo4j \
    --uri bolt://localhost:7687 \
    --username neo4j \
    --password your_secure_password

The CLI parses these arguments and constructs a GraphStore instance with the appropriate configuration.

Option B: Direct Python Instantiation

from semantica.graph_store import GraphStore

# Configuration auto-discovered from semantica.yaml

store = GraphStore(backend="neo4j")

Or pass configuration explicitly:

from semantica.graph_store import GraphStore
from semantica.graph_store.config import GraphStoreConfig

config = GraphStoreConfig(
    backend="neo4j",
    uri="bolt://localhost:7687",
    username="neo4j",
    password="your_secure_password"
)

store = GraphStore(config=config)

Internally, GraphStore.__init__ resolves the backend string through the registry. At line 567 of graph_store.py, the implementation performs:

if backend == "neo4j":
    from .neo4j_store import Neo4jStore
    self.store = Neo4jStore(self.config)

Step 4: Execute Graph Operations

Once initialized, the GraphStore exposes a unified API regardless of backend. All operations delegate to Neo4jStore methods that generate and execute Cypher queries.

Create Nodes


# Create a node with labels and properties

node_id = store.create_node(
    labels=["Person", "Employee"],
    properties={
        "name": "Alice Chen",
        "department": "Engineering",
        "joined": 2023
    }
)
print(f"Created node with ID: {node_id}")

Create Relationships


# Create a directed relationship between nodes

store.create_relationship(
    start_node_id=alice_id,
    end_node_id=bob_id,
    rel_type="MANAGES",
    properties={"since": "2024-01-15"}
)

Run Custom Cypher Queries

The store sanitizes all inputs to prevent Cypher injection:


# Parameterized query execution

results = store.query(
    "MATCH (p:Person {department: $dept})-[:MANAGES]->(sub) RETURN p.name, sub.name",
    parameters={"dept": "Engineering"}
)

for record in results:
    print(f"{record['p.name']} manages {record['sub.name']}")

The Neo4jStore class implements query parameterization in neo4j_store.py (lines 252–260), ensuring user inputs are never concatenated directly into Cypher strings.


Step 5: Transaction Control

For operations requiring atomicity, use explicit transaction blocks via the Neo4jTransaction wrapper:

with store.begin_transaction() as tx:
    # Multiple operations in a single transaction

    tx.run(
        "CREATE (p:Person {id: $id, name: $name})",
        id=1001, name="Dana Smith"
    )
    tx.run(
        "MATCH (m:Person {name: $manager}) CREATE (p)-[:REPORTS_TO]->(m)",
        manager="Alice Chen"
    )
    # Commit occurs automatically on successful exit

The Neo4jTransaction class in neo4j_store.py handles session.begin_transaction() lifecycle management, including proper rollback on exceptions.


Step 6: Verify the Integration

Semantica includes integration tests for the Neo4j backend. After configuring a live Neo4j instance (or using the Neo4j test container), run:


# Run all Neo4j-specific tests

pytest tests/ -k neo4j -v

# Run the full graph store test suite

pytest tests/test_graph_store.py

Key test modules to verify functionality:

Test File Coverage
tests/graph_store/test_neo4j_store.py Connection, CRUD, and query operations
tests/graph_store/test_cypher_injection.py Input sanitization and security
tests/utils/test_normalize_graph_payload.py Data serialization round-trips

Successful test execution confirms that Neo4jStore correctly implements the GraphStore interface contract.


Configuration Reference

Parameter Required Default Description
backend Yes — Must be "neo4j"
uri Yes — Bolt URI (e.g., bolt://host:7687)
username Yes — Neo4j authentication username
password Yes — Neo4j authentication password
database No "neo4j" Target database name
tls No false Enable encrypted connections
tls_cert_path No null Path to custom CA certificate
max_connection_pool_size No 50 Driver connection pool limit

These fields are defined in the Neo4jConfig Pydantic model within semantica/graph_store/config.py.


Summary

  • Install dependency: pip install neo4j to provide the driver that neo4j_store.py imports
  • Configure backend: Set backend: neo4j in semantica.yaml with connection credentials
  • Instantiate store: Use GraphStore(backend="neo4j") or the CLI store connect command
  • Execute operations: Standard create_node, create_relationship, and query methods automatically generate sanitized Cypher
  • Manage transactions: Use begin_transaction() context manager for atomic multi-operation batches

The Semantica Neo4j integration provides production-ready graph persistence with connection pooling, parameterized queries, and full transaction support.


Frequently Asked Questions

What versions of Neo4j are compatible with Semantica?

Semantica uses the official neo4j Python driver, which supports Neo4j server versions 4.x and 5.x. The driver handles protocol negotiation automatically. Check your driver version with pip show neo4j and consult the Neo4j driver documentation for specific server compatibility matrices.

Can I use Neo4j AuraDB with Semantica?

Yes. Configure the uri parameter with your AuraDB connection string (format: neo4j+s://xxxx.databases.neo4j.io) and enable TLS by setting tls: true in your configuration. AuraDB's required encryption is handled transparently by the driver's neo4j+s scheme.

How does Semantica prevent Cypher injection attacks?

The Neo4jStore implementation in neo4j_store.py exclusively uses parameterized queries. All user-provided values are passed through the driver's parameter binding mechanism (e.g., $param_name placeholders) rather than string concatenation. This approach eliminates injection vectors at the driver level.

What happens if the Neo4j connection fails during initialization?

Neo4jStore.__init__ validates connectivity by attempting a lightweight server handshake. If the connection fails, it raises a GraphStoreConnectionError with details from the underlying Neo4j driver exception. The error includes the target URI and suggested troubleshooting steps (check credentials, network, server status).

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →