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. Useeahelper loadinstead ofdvm-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-eagraphdepends ondvm-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
-
Install
uv— the MCP server is launched viauvx(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
-
Start Neo4j in Neo4j Desktop before using Copilot chat.
-
Open the project in VS Code — the
.vscode/settings.jsonis 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
--passwordvalue if your Neo4j password differs frompassword. -
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.yamlexists in the working directory, the bundled default is used automatically. - Custom: place your own
metamodel-mapping.yamlin the working directory, or pass--mapping <path>. - Generate: run
dvm-eagraph --generate-mappingto 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)
| File | Size | Uploaded | |
|---|---|---|---|
| dvm_eagraph-0.1.3.tar.gz | 78.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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 logRelease 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