Skip to main content

lean-ix — SAP LeanIX GraphQL Proxy

⚠️ 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 proxy / eahelper download instead. This repo is archived and receives no further updates.

A local proxy server that:

  • Connects to your already-logged-in browser via Playwright CDP
  • Extracts the active Bearer token from LeanIX network requests
  • Exposes a local GraphQL endpoint that proxies to LeanIX
  • Serves a GraphiQL UI for interactive exploration

Prerequisites

  • Python 3.14+ and uv
  • Google Chrome or Microsoft Edge installed
  • Playwright browsers installed (one-time step)
# One-time: install Playwright browser binaries
uv run playwright install chromium

Quick Start

Step 1 — Launch a debug Edge/Chrome instance

If Edge or Chrome is already running, you cannot simply add --remote-debugging-port to a new shortcut — the flag is silently ignored and the port never opens. You must launch a separate isolated instance using a different --user-data-dir.

# Edge (recommended — already installed on Windows)
Start-Process "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" `
  "--remote-debugging-port=9222 --user-data-dir=C:\Temp\edge-debug --no-first-run --no-default-browser-check"

# Chrome
Start-Process "C:\Program Files\Google\Chrome\Application\chrome.exe" `
  "--remote-debugging-port=9222 --user-data-dir=C:\Temp\chrome-debug --no-first-run"

Verify the debug port is active before continuing:

Invoke-RestMethod http://localhost:9222/json/version

You should see a JSON response with browser version info. If you get a connection error, the browser did not start with the debug port — check that you closed all existing windows of that browser first, or that the --user-data-dir path differs from your normal profile.

Log in to LeanIX in that browser window before proceeding.

Step 2 — Start the proxy

cd lean-ix
dvm-leanix

You will be prompted for the LeanIX workspace URL if not provided via --url.
The tool connects to Chrome, captures the Bearer token, then starts the local server.

Step 3 — Open GraphiQL

Navigate to: http://localhost:8765/graphql


CLI Options

dvm-leanix [OPTIONS]

Options:
  --url URL           LeanIX workspace base URL
                      (default: https://eu-10.leanix.net/YourInstance)
  --port PORT         Local port (default: 8765)
  --connect CDP_URL   Chrome DevTools Protocol endpoint (default: http://localhost:9222)
  --token TOKEN       Use this Bearer token directly — skips browser extraction
  --api-token KEY     LeanIX Technical User API key — exchanges for Bearer token via OAuth2
                      (no browser needed; also read from env var LEANIX_API_TOKEN)
  --ca-bundle PATH    PEM CA bundle (corporate SSL proxy fix)
  --no-verify-ssl     Disable SSL verification entirely (insecure)

Examples

# Use default URL, prompted if missing
dvm-leanix

# Specify workspace URL explicitly
dvm-leanix --url https://eu-10.leanix.net/MyOtherWorkspace

# Use Technical User API key (no browser needed)
dvm-leanix --api-token "your-api-key-here"

# API key via environment variable
$env:LEANIX_API_TOKEN = "your-api-key-here"
dvm-leanix

# Corporate SSL proxy — point at exported CA bundle
dvm-leanix --ca-bundle "$env:USERPROFILE\.lean-ix\corporate-ca.pem"

# Disable SSL verification (quick test only)
dvm-leanix --no-verify-ssl

# Use a known Bearer token (no browser needed)
dvm-leanix --token "eyJhbGci..."

# Different port
dvm-leanix --port 9000

Endpoints

Method Path Description
GET / Redirects to /graphql
GET /graphql GraphiQL interactive UI
POST /graphql GraphQL proxy to LeanIX
GET /health Health check + upstream URL
GET /token Show masked current Bearer token
POST /token Replace Bearer token at runtime

Replace token at runtime

If the token expires, refresh it without restarting:

Invoke-RestMethod -Uri http://localhost:8765/token -Method POST `
  -ContentType "application/json" `
  -Body '{"token": "eyJhbGci..."}'


Technical User Credentials (No Browser Required)

For automated scripts, CI pipelines, or headless environments you can authenticate with a Technical User API key instead of a browser session.

Create a Technical User

  1. In your LeanIX workspace go to Administration → Technical Users
  2. Click Create Technical User, set a name, assign roles
  3. Copy the generated API key (shown only once)

Start the proxy with an API key

# Pass directly
dvm-leanix --api-token "your-api-key-here"

# Or export as environment variable
$env:LEANIX_API_TOKEN = "your-api-key-here"
dvm-leanix

The proxy exchanges the key for a Bearer token via OAuth2 at startup and automatically re-exchanges it whenever the token expires — no browser interaction needed.

How it works

API key
  │
  │  POST /services/mtm/v1/oauth2/token
  │  auth: ("apitoken", API_KEY)
  │  body: grant_type=client_credentials
  ▼
Bearer access_token
  │
  ▼
server.py (FastAPI on localhost:8765)
  │  POST /graphql  { query, variables }
  │  Authorization: Bearer <token>
  ▼
https://eu-10.leanix.net/services/pathfinder/v1/graphql

SAP LeanIX GraphQL API

Full reference: docs/graphql-api.md

The SAP LeanIX GraphQL API conforms to the October 2021 GraphQL specification.

Key concepts

Concept Detail
Fact Sheets Core entities: Application, ITComponent, BusinessCapability, Process, Interface, DataObject, Provider, TechnicalStack, UserGroup, Project
Queries Read data — factSheet(id), allFactSheets(filter, sort, first, after)
Mutations Write data — createFactSheet, updateFactSheet, archiveFactSheet
Pagination Relay cursor-based (first + after with pageInfo.endCursor)
Filtering facetFilters with OR / AND / NOR operators on facet keys

GraphQL endpoint

POST https://{HOST}/services/pathfinder/v1/graphql
Authorization: Bearer {access_token}
Content-Type: application/json

Quick example

{
  allFactSheets(factSheetType: Application, first: 10) {
    totalCount
    pageInfo { hasNextPage endCursor }
    edges {
      node { id name displayName lxState completion { percentage } }
    }
  }
}

Error handling

GraphQL always returns HTTP 200. Check the errors array in the response body:

{
  "data": null,
  "errors": [{ "message": "No fact sheet found with id '...'" }]
}

See docs/graphql-api.md for filtering, pagination, mutations, the REST migration guide, and best practices.


Architecture

Browser (logged in)
    │
    │  Chrome DevTools Protocol (port 9222)
    ▼
token.py  ── intercepts Authorization header ──► Bearer token
    │
    ▼
server.py (FastAPI on localhost:8765)
    │  POST /graphql  { query, variables }
    │
    │  Authorization: Bearer <token>
    ▼
https://eu-10.leanix.net/services/pathfinder/v1/graphql

Troubleshooting

"Could not connect to browser at http://localhost:9222"
→ If Edge/Chrome is already running, the --remote-debugging-port flag is silently ignored by any new window you open — it only works on a fresh browser process. Launch a separate isolated instance with its own profile:

Start-Process "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" `
  "--remote-debugging-port=9222 --user-data-dir=C:\Temp\edge-debug --no-first-run --no-default-browser-check"

Then verify the port is open before retrying lean-ix:

Invoke-RestMethod http://localhost:9222/json/version   # must return JSON

"Timed out waiting for a Bearer token"
→ No LeanIX API calls were detected. Make sure you are logged in and try navigating within LeanIX to trigger an API request.

SSL: CERTIFICATE_VERIFY_FAILED — self-signed certificate in chain
→ Your corporate network uses SSL inspection (a man-in-the-middle proxy that replaces certificates with ones signed by an internal CA). Python's SSL stack rejects these because the corporate root CA is not in its trust bundle.

Option 1 — Export the corporate CA and point lean-ix at it (recommended)

# Export all trusted root CAs from the Windows certificate store to a PEM file
$certs = Get-ChildItem -Path Cert:\LocalMachine\Root
$pem = $certs | ForEach-Object { "-----BEGIN CERTIFICATE-----`n" + [Convert]::ToBase64String($_.RawData, 'InsertLineBreaks') + "`n-----END CERTIFICATE-----" }
$pem | Set-Content -Path "$env:USERPROFILE\.lean-ix\corporate-ca.pem" -Encoding ascii

Then run lean-ix with the bundle:

dvm-leanix --ca-bundle "$env:USERPROFILE\.lean-ix\corporate-ca.pem"

Option 2 — Disable verification entirely (quick test only, not recommended)

dvm-leanix --no-verify-ssl

Token expired mid-session
→ Navigate in the LeanIX browser tab (which triggers a token refresh) then POST the new token to /token, or restart lean-ix.

Download files

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

Source Distribution

dvm_leanix-0.5.3.tar.gz (97.9 kB view details)

Uploaded Source

Built Distribution

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

dvm_leanix-0.5.3-py3-none-any.whl (33.8 kB view details)

Uploaded Python 3

File details

Details for the file dvm_leanix-0.5.3.tar.gz.

File metadata

  • Download URL: dvm_leanix-0.5.3.tar.gz
  • Upload date:
  • Size: 97.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dvm_leanix-0.5.3.tar.gz
Algorithm Hash digest
SHA256 9fbdb73bf7f78dab0cd4778b2f69cc1cbbc8eb431bbae3643ed971a058ba9e8c
MD5 b5a6bdd6dc530925bf5191b2e1f12c32
BLAKE2b-256 53013d29c358683642eead707dbc6ecb587ab2660d6a20502b77342290d24b33

See more details on using hashes here.

Provenance

The following attestation bundles were made for dvm_leanix-0.5.3.tar.gz:

Publisher: publish.yml on divyavanmahajan/dvm-leanix

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dvm_leanix-0.5.3-py3-none-any.whl.

File metadata

  • Download URL: dvm_leanix-0.5.3-py3-none-any.whl
  • Upload date:
  • Size: 33.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dvm_leanix-0.5.3-py3-none-any.whl
Algorithm Hash digest
SHA256 df742e3c69b3f240eca9f70984a243e200ecb58993593c80ba782b09ddad90ee
MD5 73077caab64f13eb2bdc7be965624556
BLAKE2b-256 0de5e7a98717e2304faa0f7ef0717e13a8c0564762ca365fff78a94c33d5daa5

See more details on using hashes here.

Provenance

The following attestation bundles were made for dvm_leanix-0.5.3-py3-none-any.whl:

Publisher: publish.yml on divyavanmahajan/dvm-leanix

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.5.3 This release

2 files

0.5.2

2 files

0.5.1

2 files

0.5.0

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page