How to Configure Polyglot Graph Storage in Semantica: RDF (Blazegraph/Oxigraph) and LPG (Neo4j) Backends

To configure polyglot graph storage in Semantica, define separate graph_db (LPG) and triplet_store (RDF) sections in your config.yaml, then instantiate GraphStore for Neo4j and TripletStore for Blazegraph or Oxigraph via the ConfigManager or programmatic constructors.

Semantica supports polyglot graph storage by maintaining two distinct but interoperable storage APIs within the same application. This architecture allows you to run property-graph queries against Neo4j while simultaneously executing SPARQL queries against RDF backends like Blazegraph or Oxigraph, all orchestrated through a unified configuration layer.

Understanding the Dual-Store Architecture

Semantica separates storage concerns into two primary layers, each with dedicated Python classes and backend implementations.

LPG Store Layer

The property-graph store handles nodes, properties, and relationships using Cypher-style semantics. The primary interface is the GraphStore class in [semantica/graph_store/graph_store.py](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/graph_store.py). Supported backends include Neo4j, FalkorDB, Amazon Neptune, and Apache AGE.

RDF Store Layer

The RDF triple store manages subject-predicate-object triples and SPARQL queries via the TripletStore class in [semantica/triplet_store/triplet_store.py](https://github.com/semantica-agi/semantica/blob/main/semantica/triplet_store/triplet_store.py). Supported backends include Blazegraph, Oxigraph, Jena, RDF4J, and Anzo.

Both layers are driven by a single YAML configuration file loaded by the ConfigManager in [semantica/core/config_manager.py](https://github.com/semantica-agi/semantica/blob/main/semantica/core/config_manager.py).

YAML Configuration for Polyglot Deployment

Create a config.yaml that defines both storage backends simultaneously. The graph_db key configures the LPG connection, while triplet_store configures the RDF connection.


# config.yaml – polyglot deployment example

graph_db:
  backend: neo4j
  uri: bolt://localhost:7687
  user: neo4j
  password: <YOUR_PASSWORD>

triplet_store:
  backend: blazegraph
  endpoint: http://localhost:9999/blazegraph
  # Alternative RDF backend:

  # backend: oxigraph

  # store_path: /var/oxigraph/data

Semantica reads this configuration via ConfigManager. The CLI entry point in [semantica/cli.py](https://github.com/semantica-agi/semantica/blob/main/semantica/cli.py) (lines 1087-1100) passes the graph_db block to GraphStore and the triplet_store block to TripletStore. Configuration validation occurs in [semantica/graph_store/config.py](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/config.py) (lines 52-56), where the backend name is extracted from the configuration dictionary.

Programmatic Initialization

You can bypass YAML configuration and instantiate stores directly in Python. This approach is useful for dynamic connection management or testing environments.

from semantica.graph_store import GraphStore
from semantica.triplet_store import TripletStore

# Initialize LPG store (Neo4j)

g_store = GraphStore(
    backend="neo4j",
    uri="bolt://localhost:7687",
    user="neo4j",
    password="secret"
)
g_store.connect()

# Initialize RDF store (Blazegraph)

t_store = TripletStore(
    backend="blazegraph",
    endpoint="http://localhost:9999/blazegraph"
)
t_store.connect()

Behind the scenes, GraphStore._initialize_store_backend() (lines 66-94 in graph_store.py) dispatches to concrete implementations like [semantica/graph_store/neo4j_store.py](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/neo4j_store.py). Similarly, TripletStore instantiates [semantica/triplet_store/blazegraph_store.py](https://github.com/semantica-agi/semantica/blob/main/semantica/triplet_store/blazegraph_store.py) or [semantica/triplet_store/oxigraph_store.py](https://github.com/semantica-agi/semantica/blob/main/semantica/triplet_store/oxigraph_store.py) based on the backend parameter.

Unified Workflow Integration

Semantica's DecisionContext aggregates both storage types into a single execution environment, enabling hybrid graph operations.

from semantica.context import DecisionContext

ctx = DecisionContext(
    vector_store=my_vec,
    graph_store=g_store,      # Neo4j LPG instance

    triplet_store=t_store     # Blazegraph/Oxigraph RDF instance

)

# Execute property-graph analytics

neighbors = ctx.graph_store.get_neighbors(node_id)

# Execute SPARQL queries simultaneously

results = ctx.triplet_store.query("SELECT ?s ?p ?o WHERE { ?s ?p ?o } LIMIT 10")

The KnowledgeGraph wrapper normalizes payloads before they reach either backend, maintaining consistent node identifiers across both stores. This interoperability is demonstrated in [tests/vector_store/test_kg_integration.py](https://github.com/semantica-agi/semantica/blob/main/tests/vector_store/test_kg_integration.py).

Command-Line Interface Configuration

The Semantica CLI supports direct initialization of either storage backend without writing Python code. CLI flags override YAML configuration values when both are present.


# Connect to Neo4j LPG store

semantica store connect --backend neo4j \
  --uri bolt://localhost:7687 \
  --user neo4j \
  --password secret

# Connect to Blazegraph RDF store

semantica store connect --backend blazegraph \
  --endpoint http://localhost:9999/blazegraph

Dependency Management and Installation

Oxigraph and Blazegraph support are optional dependencies not included in the base installation. Install them using pip extras syntax to avoid import errors when configuring these backends.


# For Oxigraph support

pip install "semantica[tripletstore-oxigraph]"

# For Blazegraph support

pip install "semantica[tripletstore-blazegraph]"

Authentication requirements differ by backend: Neo4j, Amazon Neptune, and Apache AGE require credentials in the graph_db configuration block, while Blazegraph and Oxigraph typically expose unauthenticated HTTP endpoints suitable for reverse-proxy security.

Summary

  • Polyglot storage in Semantica relies on two distinct APIs: GraphStore for LPG backends (Neo4j) and TripletStore for RDF backends (Blazegraph/Oxigraph).
  • Configuration is centralized in YAML under graph_db and triplet_store keys, parsed by ConfigManager and consumed by the CLI and programmatic factories.
  • Concrete backend implementations reside in [semantica/graph_store/neo4j_store.py](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/neo4j_store.py) and semantica/triplet_store/ modules.
  • Optional dependencies must be installed via pip extras (e.g., semantica[tripletstore-oxigraph]) before configuring non-default RDF backends.
  • The DecisionContext class enables unified workflows that query both LPG and RDF stores simultaneously while maintaining identifier consistency.

Frequently Asked Questions

How do I switch between Oxigraph and Blazegraph without changing my code?

Change the backend value in your config.yaml from blazegraph to oxigraph and update the connection parameters accordingly. Both backends implement the same TripletStore interface in [semantica/triplet_store/triplet_store.py](https://github.com/semantica-agi/semantica/blob/main/semantica/triplet_store/triplet_store.py), so application code remains unchanged.

Can I use only one storage type (LPG or RDF) and ignore the other?

Yes. The DecisionContext accepts optional parameters, and you can instantiate only GraphStore or only TripletStore if your use case requires only property-graph or only RDF semantics. The configuration file can safely omit the unused section.

What authentication methods are supported for Neo4j in the LPG store?

The GraphStore class supports username/password authentication via the user and password keys in the graph_db configuration block, as implemented in [semantica/graph_store/neo4j_store.py](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/neo4j_store.py). Enterprise features like Kerberos or certificate-based authentication require extending the concrete store class.

How does Semantica keep data synchronized between the LPG and RDF stores?

Semantica does not automatically synchronize data between stores. To maintain consistency across both representations, use the KGNormalizer utility in [semantica/graph_store/graph_store_provenance.py](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/graph_store_provenance.py), which maps RDF triples to LPG nodes and relationships before writing to either backend.

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 →