Graph (lexigram-graph)
Graph database support for the Lexigram Framework (Neo4j, in-memory).
Overview
Section titled “Overview”lexigram-graph provides graph storage backends with DI wiring for in-memory and Neo4j implementations behind the graph contracts. It supports node and edge creation, graph traversal queries, Cypher compilation for Neo4j, and lazy graph creation with lifecycle events.
Full documentation: docs.lexigram.dev
Install
Section titled “Install”uv add lexigram-graph# With Neo4j supportuv add "lexigram-graph[neo4j]"Quick Start
Section titled “Quick Start”from lexigram import Applicationfrom lexigram.di.module import Module, modulefrom lexigram.graph import GraphConfig, GraphModulefrom lexigram.contracts.data.graph import GraphStoreProtocol, TraversalQuery, StartSpec, TraversalStep
@module(imports=[GraphModule.configure(GraphConfig(backend="memory"))])class AppModule(Module): pass
async def main() -> None: async with Application.boot(modules=[AppModule]) as app: store = await app.container.resolve(GraphStoreProtocol) graph = await store.get_graph()
await graph.create_node(["Person"], {"name": "Alice"}, node_id="alice") await graph.create_node(["Person"], {"name": "Bob"}, node_id="bob") await graph.create_edge("alice", "bob", "KNOWS")
paths = await graph.traverse( TraversalQuery( start=StartSpec(node_ids=("alice",)), steps=(TraversalStep(edge_types=("KNOWS",)),), ) ) assert paths
if __name__ == "__main__": import asyncio asyncio.run(main())Configuration
Section titled “Configuration”Zero-config usage: Call
GraphModule.configure()with no arguments to use all defaults (in-memory backend).
Option 1 — YAML file
Section titled “Option 1 — YAML file”graph: enabled: true backend: neo4j default_traversal_max_depth: 10 neo4j: uri: bolt://localhost:7687 password: "${NEO4J_PASSWORD}"Option 2 — Profiles + Environment Variables (recommended)
Section titled “Option 2 — Profiles + Environment Variables (recommended)”export LEX_GRAPH__BACKEND=neo4jexport LEX_GRAPH__NEO4J__URI=bolt://localhost:7687Option 3 — Python
Section titled “Option 3 — Python”from lexigram.graph import GraphConfig, GraphModulefrom lexigram.graph.config import Neo4jConfig
GraphModule.configure( GraphConfig( backend="neo4j", neo4j=Neo4jConfig( uri="bolt://localhost:7687", password="${NEO4J_PASSWORD}", ), ))Config reference
Section titled “Config reference”| Field | Default | Env var | Description |
|---|---|---|---|
enabled | true | LEX_GRAPH__ENABLED | Enable or disable the graph subsystem |
backend | memory | LEX_GRAPH__BACKEND | Graph backend to use (memory or neo4j) |
default_traversal_max_depth | 10 | LEX_GRAPH__DEFAULT_TRAVERSAL_MAX_DEPTH | Maximum depth for graph traversals |
default_query_limit | 100 | LEX_GRAPH__DEFAULT_QUERY_LIMIT | Default result limit for graph queries |
bulk_batch_size | 1000 | LEX_GRAPH__BULK_BATCH_SIZE | Batch size for bulk insert and update operations |
max_retries | 3 | LEX_GRAPH__MAX_RETRIES | Retry attempts on transient graph errors |
retry_delay | 1.0 | LEX_GRAPH__RETRY_DELAY | Seconds between retry attempts |
neo4j.uri | bolt://localhost:7687 | LEX_GRAPH__NEO4J__URI | Neo4j Bolt connection URI |
neo4j.username | neo4j | LEX_GRAPH__NEO4J__USERNAME | Neo4j authentication username |
neo4j.password | — | LEX_GRAPH__NEO4J__PASSWORD | Neo4j authentication password (required for production) |
neo4j.database | neo4j | LEX_GRAPH__NEO4J__DATABASE | Target Neo4j database name |
neo4j.max_connection_pool_size | 100 | LEX_GRAPH__NEO4J__MAX_CONNECTION_POOL_SIZE | Maximum driver connection pool size |
memory.max_nodes | 1000000 | LEX_GRAPH__MEMORY__MAX_NODES | Node capacity for the in-memory backend |
Module Factory Methods
Section titled “Module Factory Methods”| Method | Description |
|---|---|
GraphModule.configure(config=None) | Register GraphProvider with a config |
GraphModule.stub(config=None) | Lightweight test module with in-memory backend |
Key Features
Section titled “Key Features”- In-memory backend — no external service needed; for development and tests
- Neo4j backend — async Neo4j driver with Cypher query compilation
- Graph traversal —
TraversalQuery,StartSpec,TraversalStepfor graph walks - Named graphs — lazy graph creation per name with lifecycle events
- Connection pooling — configurable pool size for Neo4j driver
Testing
Section titled “Testing”async with Application.boot(modules=[GraphModule.stub()]) as app: store = await app.container.resolve(GraphStoreProtocol) graph = await store.get_graph() # Test with in-memory backendKey Source Files
Section titled “Key Source Files”| File | What it contains |
|---|---|
src/lexigram/graph/module.py | GraphModule.configure(), .stub() |
src/lexigram/graph/config.py | GraphConfig, Neo4jConfig |
src/lexigram/graph/di/provider.py | GraphProvider boot and registration |
src/lexigram/graph/backends/memory/backend.py | InMemoryGraphStore implementation |
src/lexigram/graph/backends/neo4j/backend.py | Neo4jGraphStore implementation |
src/lexigram/graph/backends/neo4j/cypher.py | CypherCompiler |