Skip to main content

lexigram-graph

Graph database support for the Lexigram Framework (Neo4j, in-memory).


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.


Full documentation: docs.lexigram.dev

Install

uv add lexigram-graph
# With Neo4j support
uv add "lexigram-graph[neo4j]"

Quick Start

from lexigram import Application
from lexigram.di.module import Module, module
from lexigram.graph import GraphConfig, GraphModule
from 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

Zero-config usage: Call GraphModule.configure() with no arguments to use all defaults (in-memory backend).

Option 1 — YAML file

# application.yaml
graph:
  enabled: true
  backend: neo4j
  default_traversal_max_depth: 10
  neo4j:
    uri: bolt://localhost:7687
    password: "${NEO4J_PASSWORD}"

Option 2 — Profiles + Environment Variables (recommended)

export LEX_GRAPH__BACKEND=neo4j
export LEX_GRAPH__NEO4J__URI=bolt://localhost:7687

Option 3 — Python

from lexigram.graph import GraphConfig, GraphModule
from lexigram.graph.config import Neo4jConfig

GraphModule.configure(
    GraphConfig(
        backend="neo4j",
        neo4j=Neo4jConfig(
            uri="bolt://localhost:7687",
            password="${NEO4J_PASSWORD}",
        ),
    )
)

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
tenancy.enabled False Enable per-tenant graph isolation
tenancy.strategy "node_property" "node_property" or "graph_per_tenant"
tenancy.template "{logical}_t_{tenant}" Template for resolving tenant-specific graph names

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

  • In-memory backend — no external service needed; for development and tests
  • Neo4j backend — async Neo4j driver with Cypher query compilation
  • Graph traversalTraversalQuery, StartSpec, TraversalStep for graph walks
  • Named graphs — lazy graph creation per name
  • Connection pooling — configurable pool size for Neo4j driver

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 backend

Key Source Files

File What it contains
src/lexigram/graph/module.py GraphModule.configure(), .stub()
src/lexigram/graph/config.py GraphConfig, GraphTenancyConfig, 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
src/lexigram/graph/tenancy/ Tenancy decorator and resolver (decorator.py, resolver.py); strategy enum lives in lexigram.contracts.data.graph.tenancy

Multi-Tenancy

lexigram-graph supports two isolation strategies:

Strategies

Strategy GraphTenancyStrategy How It Works
Graph per tenant GRAPH_PER_TENANT Graph names are resolved through a TemplatedTenantCollectionResolver, giving each tenant an isolated named graph
Node property NODE_PROPERTY Graph names pass through unchanged; every node/edge gets a tenant_id property, and find_nodes auto-injects a tenant_id filter

Configuration

from lexigram.graph import GraphModule
from lexigram.graph.config import GraphConfig, GraphTenancyConfig

config = GraphConfig(
    backend="neo4j",
    tenancy=GraphTenancyConfig(
        enabled=True,
        strategy="node_property",
        template="{logical}_t_{tenant}",
    ),
)
GraphModule.configure(config)

Components

Component Role
GraphTenancyConfig Dataclass with enabled, strategy, and template
TemplatedTenantCollectionResolver Resolves logical → physical graph names
TenantGraphStoreDecorator Strategy-aware decorator: resolves names (GRAPH_PER_TENANT) or wraps returned graphs (NODE_PROPERTY)
TenantPropertyFilterGraph Auto-injects tenant_id into create_node/create_edge properties and find_nodes filters

Download files

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

Source Distribution

lexigram_graph-0.1.5001.tar.gz (48.7 kB view details)

Uploaded Source

Built Distribution

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

lexigram_graph-0.1.5001-py3-none-any.whl (31.0 kB view details)

Uploaded Python 3

File details

Details for the file lexigram_graph-0.1.5001.tar.gz.

File metadata

  • Download URL: lexigram_graph-0.1.5001.tar.gz
  • Upload date:
  • Size: 48.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.14

File hashes

Hashes for lexigram_graph-0.1.5001.tar.gz
Algorithm Hash digest
SHA256 6ae5fd08f4f2fe6b3f0c2c0f707bc6801e0b3ae47a8941d669cd2bede3385764
MD5 d1bd86dc3c27b0dd77c26b70c3b93cd6
BLAKE2b-256 749c2079a82c38b34aa51a8af7fab1bfc4f9df07acead49b3c4021750ddaff82

See more details on using hashes here.

File details

Details for the file lexigram_graph-0.1.5001-py3-none-any.whl.

File metadata

File hashes

Hashes for lexigram_graph-0.1.5001-py3-none-any.whl
Algorithm Hash digest
SHA256 6aba652c8c872673c4f18958ade62d12a22efc6b93c10f1563bfc32dee67ead2
MD5 3db89a0c0bc2b42842f0952ea686c12c
BLAKE2b-256 66ff498fc0e2383597df82ae99dc9459458981c632781462c3617611b930096c

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.5008

1 file

0.1.5004

2 files

This release

0.1.5001 This release

2 files

0.1.3007

1 file

0.1.3006

1 file

0.1.3005

1 file

0.1.4

2 files

0.1.2

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page