Skip to main content

dvm-eagraph — LeanIX → Neo4j Loader

⚠️ DEPRECATED — this package has been merged into dvm-eahelper (pip install dvm-eahelper), which combines the proxy, download and graph loading in one CLI and adds KuzuDB support. Use eahelper load instead of dvm-eagraph. This repo is archived and receives no further updates.

Downloads Application, BusinessCapability, Interface and Organization factsheets (plus all relationships between them) from SAP LeanIX and loads them into Neo4j.


Installation

pip install dvm-eagraph

Or run without installing using uvx:

uvx dvm-eagraph -- --help

Note: dvm-eagraph depends on dvm-leanix. Ensure it is installed and available in your Python environment before use.


Prerequisites

Requirement Details
Neo4j running Start the database in Neo4j Desktop before running the loader
.env file Must contain NEO4J_URI, NEO4J_USERNAME, NEO4J_PASSWORD
dvm-leanix proxy Must be running in a separate terminal before the loader is launched
uv (optional) Required for uvx — install from docs.astral.sh/uv

GitHub Copilot MCP Integration (Neo4j)

This project is pre-configured so that GitHub Copilot in VS Code can query the Neo4j database directly using natural language, via the mcp-neo4j-cypher MCP server.

How it works

The MCP server is configured in .vscode/settings.json. When Neo4j is running, Copilot can execute Cypher queries through three tools:

  • read_neo4j_cypher — run read queries (MATCH, RETURN)
  • write_neo4j_cypher — run write queries (MERGE, CREATE, DELETE)
  • get_neo4j_schema — introspect node labels and relationship types (requires APOC)

Setup

  1. Install uv — the MCP server is launched via uvx (no separate install needed after this):

    # Windows (PowerShell)
    powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
    
    # macOS / Linux
    curl -LsSf https://astral.sh/uv/install.sh | sh
    
  2. Start Neo4j in Neo4j Desktop before using Copilot chat.

  3. Open the project in VS Code — the .vscode/settings.json is already configured:

    {
      "github.copilot.chat.mcp.servers": {
        "neo4j": {
          "type": "stdio",
          "command": "uvx",
          "args": [
            "mcp-neo4j-cypher",
            "--db-url", "bolt://localhost:7687",
            "--username", "neo4j",
            "--password", "password"
          ]
        }
      }
    }
    

    Update the --password value if your Neo4j password differs from password.

  4. Verify — in Copilot Chat, the Neo4j tools will appear in the MCP tools list. Ask a question like:

    "How many Application nodes are in the graph?"

Changing credentials

If your Neo4j password is different, update .vscode/settings.json directly — or better, ask Copilot to query using your credentials. Do not commit passwords to source control; consider using a VS Code user settings override for the password.

Start the dvm-leanix proxy

dvm-leanix serve          # uses default workspace URL + legacy SSL

The proxy authenticates via your browser and listens on http://localhost:8765/graphql.


Quick Start

# Full run: download from LeanIX, load into Neo4j
dvm-eagraph

# Or with uvx (no install needed):
uvx dvm-eagraph

Usage

dvm-eagraph [OPTIONS]

Options:
  --proxy URL             dvm-leanix GraphQL proxy URL
                          (default: http://localhost:8765/graphql)
  --data-dir PATH         Directory to save raw JSON files
                          (default: data/leanix)
  --mapping PATH          Path to metamodel mapping YAML
                          (default: metamodel-mapping.yaml in CWD, then bundled default)
  --generate-mapping      Scan LeanIX and write a mapping YAML, then exit
  --all-factsheets        Download every FactSheet type (ignores mapping filter)
  --limit N               Cap downloads to N records per FactSheet type and N rows per
                          relationship type (useful for testing)
  --no-verify-ssl         Disable SSL certificate verification (insecure)
  --skip-download         Load from previously saved JSON; skip LeanIX download
  --skip-neo4j            Download only; do not write to Neo4j

Common workflows

# Download only (inspect JSON before loading)
dvm-eagraph --skip-neo4j

# Quick end-to-end test with 10 records per type
dvm-eagraph --limit 10

# Load previously downloaded JSON into Neo4j (no LeanIX connection needed)
dvm-eagraph --skip-download

# Generate a mapping YAML from your live LeanIX workspace
dvm-eagraph --generate-mapping

# Use a custom mapping file
dvm-eagraph --mapping path/to/my-mapping.yaml

# Re-run against a different proxy
dvm-eagraph --proxy http://localhost:9000/graphql

# With uvx, passing arguments after --
uvx dvm-eagraph -- --skip-download --mapping my-mapping.yaml

Mapping File

The metamodel-mapping.yaml controls which LeanIX FactSheet types are downloaded and how they map to Neo4j labels and relationship types.

  • Default: if no metamodel-mapping.yaml exists in the working directory, the bundled default is used automatically.
  • Custom: place your own metamodel-mapping.yaml in the working directory, or pass --mapping <path>.
  • Generate: run dvm-eagraph --generate-mapping to scan the live workspace and produce a new file.

What Gets Downloaded

Factsheet types

LeanIX Type Neo4j Label Key properties loaded
Application :Application id, displayName, description, technicalSuitability, businessValue, lifecycle, …
BusinessCapability :BusinessCapability id, displayName, description, level, …
Interface :Interface id, displayName, description, dataFlowDirection, …
Organization :Organization id, displayName, description, orgUnit, …

All scalar fields returned by the LeanIX GraphQL schema are downloaded and stored as node properties. The LeanIX id (UUID) is used as the unique identifier.

Raw JSON output

Downloaded data is saved to data/leanix/ for inspection and offline re-use:

data/leanix/
  Application.json
  BusinessCapability.json
  Interface.json
  Organization.json
  Application_relations.json
  BusinessCapability_relations.json
  Interface_relations.json
  Organization_relations.json

Graph Model

The script extends the base graph model with LeanIX data:

(Application)-[:SUPPORTS]->(BusinessCapability)
(Application)-[:EXPOSES]->(Interface)
(Interface)-[:CONSUMED_BY]->(Application)
(Interface)-[:CARRIES]->(DataObject)
(Application)-[:OWNED_BY]->(Organization)
(BusinessCapability)-[:CHILD_OF]->(BusinessCapability)   # hierarchy

Relationship type mapping

LeanIX relation field names are mapped to Neo4j relationship types:

LeanIX relation field Neo4j relationship type
relApplicationToBusinessCapability :SUPPORTS
relApplicationToInterface :EXPOSES
relInterfaceToApplication :CONSUMED_BY
relInterfaceToDataObject :CARRIES
relApplicationToDataObject :USES_DATA
relToParent :CHILD_OF
relApplicationToOrganization :OWNED_BY
relOrganizationToApplication :OWNS
relApplicationToITComponent :USES_COMPONENT
relITComponentToApplication :USED_BY
(any other) Auto-converted camelCase → UPPER_SNAKE_CASE

Idempotency

The script is safe to re-run — it will update existing data, not duplicate it.

  • Nodes: loaded with MERGE (n:Label {id: row.id}) SET n += row
    The LeanIX UUID is the stable key. Re-running updates all scalar properties.
  • Relationships: loaded with MERGE (src)-[:TYPE]->(tgt)
    Duplicate edges are never created.
  • Constraints: CREATE CONSTRAINT IF NOT EXISTS — harmless to run repeatedly.

Architecture

dvm_eagraph.load_leanix
│
├── download_factsheets()   ← lean_ix.download.fetch_all()
│     Introspects GraphQL schema, fetches all pages, writes {Type}.json
│
├── download_relations()    ← lean_ix.download.fetch_all_relations()
│     Fetches all relation edges, deduplicates, writes {Type}_relations.json
│
├── load_saved_json()       ← reads previously saved JSON (--skip-download)
│
└── load_to_neo4j()
      ├── create_constraints()     UNIQUE on id per label
      ├── load_nodes()             MERGE + SET per factsheet type
      └── load_relationships()     MERGE per relationship type (batched by type)

Troubleshooting

Symptom Likely cause Fix
Connection refused on proxy URL Proxy not running Run dvm-leanix serve in another terminal
AuthError from Neo4j Wrong credentials Check .env values
SSL / certificate errors Corporate proxy Run dvm-leanix diagnose or use --no-verify-ssl
Empty download for a type Type doesn't exist in workspace Check available types with dvm-leanix download --list-types
Unknown relation in Neo4j Unmapped LeanIX relation name Add entry to metamodel-mapping.yaml

List available types and relations

# List all factsheet types in the workspace
dvm-leanix download --list-types

# List all relation fields for a type
dvm-leanix download --type Application --list-relations

Metadata

Release files for dvm-eagraph 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dvm-eagraph 0.1.3
File Size Uploaded
dvm_eagraph-0.1.3.tar.gz 78.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for dvm-eagraph 0.1.3
File Interpreter ABI Platform
dvm_eagraph-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 100.6 kB

Release files / dvm_eagraph-0.1.3.tar.gz

Download URL dvm_eagraph-0.1.3.tar.gz
Size 78.8 kB
Tags Source
SHA-256 checksum
How to use checksums
d257d2734593ea88e870011fa6234f0894b74d003c2e4df0a944d6fef4638c88
BLAKE2b-256 checksum
How to use checksums
797b67ec8138b7c8cb15a4d9566d804b56a32f22666bad0bbe7d3595efc69132
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 12, 2026.

Transparency log

Release files / dvm_eagraph-0.1.3-py3-none-any.whl

Download URL dvm_eagraph-0.1.3-py3-none-any.whl
Size 21.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
02487516c6eb210229b3a90129cd2e902a71ba3fdc93cd825accbf91101b02e0
BLAKE2b-256 checksum
How to use checksums
f2c518d856e8d41194c417d34af9dbcb65f9ea0a8b58942032694ec623755598
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 12, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.3 This release

2 release files

0.1.2

2 release files

0.1.1

2 release files

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