DepAtlas
(Originally released as DepGraph — renamed to DepAtlas. The original
design doc in docs/SPEC.pdf predates the rename and
still uses the old name.)
DepAtlas reads your codebase and builds a living dependency graph across services, teams, and repositories — so blockers surface before they cost you a sprint.
Engineering organizations above a certain size develop an invisible coordination tax: teams block each other without knowing it, status updates are written from memory, and nobody has a system that actually knows what depends on what. DepAtlas reads the code itself — the one source of truth that can't drift out of date — and turns it into a queryable graph, automatically.
Full original design in docs/SPEC.pdf.
Status
v1 core complete. Three language parsers, three code sources, a persisted queryable graph with history and diffing, full ownership resolution, all five spec'd alert types (including signature-level breaking-change detection), and both JSON and DOT export — all covered by 184 passing tests. Some gaps are known and listed in Known limitations.
| Area | What's there |
|---|---|
| Languages | Python (ast), Java (tree-sitter), JavaScript/TypeScript (esprima) |
| Code sources | Local directory, GitHub (REST API), AWS CodeCommit (boto3) |
| Persistence | SQLite-backed graph store; every scan saves an immutable snapshot |
| Ownership | CODEOWNERS, with a depatlas.yaml manifest fallback |
| Intelligence | Diff engine (snapshot-to-snapshot) + 5 alert types, incl. breaking-change signature detection |
| Export | JSON and Graphviz DOT |
Quick start
pip install -e ".[dev]"
# Scan a local repo, resolving ownership from CODEOWNERS:
depatlas scan \
--repo tests/fixtures/sample_repo/payments \
--services tests/fixtures/payments_services.json \
--codeowners tests/fixtures/sample_repo/payments/CODEOWNERS
# Query what it found:
depatlas query --service payments-service --direction downstream
depatlas query --team @payments-team
# See what changed since the last scan (run the scan above twice to
# see this produce real output; on a first scan there's nothing yet
# to compare against):
depatlas diff --last 2 --repo tests/fixtures/sample_repo/payments
# Check for cross-team dependencies, breaking changes, and more:
depatlas alerts
# Export the whole graph:
depatlas export --format dot --output graph.dot
# A repo that mixes languages is still one service -- scan them together:
depatlas scan --repo . --services services.json --language all
# (or repeat the option: --language java --language javascript;
# with no --language, languages are detected from file extensions)
# Exit with status 3 if an alert at or above a severity is raised (status 1
# means the tool itself failed). This needs a graph database that persists
# between runs, so it suits a shared database; on a fresh CI runner use
# `depatlas check` instead (see "Using it in CI"):
depatlas scan --repo . --services services.json --fail-on high
The --services file is a small JSON manifest mapping importable module
names to service names, plus a special __self__ key naming the service
being scanned:
{
"__self__": "payments-service",
"auth_client": "auth-service",
"endpoints": {
"auth.internal": "auth-service"
}
}
More usage examples — Java, JS/TS, GitHub, CodeCommit, ownership manifests — are in Full usage below.
CLI reference
| Command | Purpose |
|---|---|
depatlas scan |
Parse a repo (local, GitHub, or CodeCommit) and persist the resulting graph |
depatlas query |
Look up a service's dependencies (--direction downstream|upstream) or a team's services |
depatlas snapshots |
List saved snapshots for a repo |
depatlas diff |
Compare two snapshots (--from/--to or --last 2) |
depatlas alerts |
Check the stored graph for all 5 alert types |
depatlas check |
Stateless pull-request check: compare HEAD with its merge-base, no database needed |
depatlas export |
Export the whole graph as JSON or DOT |
Every command supports --help for full option details.
How it works
Language parsers
Each parser walks a real AST (never regex) and extracts dependencies at three confidence levels — high (an explicit, unambiguous signal), medium (a configured endpoint match), and low (a heuristic match) — plus public function/method signatures for breaking-change detection.
- Python (
ast):import/from...importstatements (high);requests.get/post/etc.calls resolved via an endpoint registry (medium) or name heuristic (low). - Java (
tree-sitter):importstatements resolved against known package namespaces (high);@FeignClientannotations, an explicit dependency declaration (high); RestTemplate/WebClient-style calls (medium/low, same scheme as Python). - JavaScript/TypeScript (
esprima):import/require(...)(high);fetch/axios.<method>/got.<method>calls (medium/low);package.jsondependencies asshared_libraryedges (high).
Tests: tests/test_parsers/.
Code sources
depatlas scan takes exactly one of:
--repo <path>— a local directory.--github-repo owner/repo— downloaded via the GitHub REST API's zipball endpoint (nogit clonedependency). RequiresDEPATLAS_GITHUB_TOKEN.--codecommit-repo <name>— needs the optional AWS extra (pip install "depatlas[aws]"); downloaded viaboto3, walking the repo tree withget_folder/get_file(CodeCommit has no bulk-download endpoint). Uses the AWS profile inDEPATLAS_AWS_PROFILE, or the default credential chain.
Tests: tests/test_connectors/ (all network/AWS calls mocked — no real
credentials needed to run the suite).
Persistence and diffing
Every scan persists to a local SQLite store (default
.depatlas/graph.db) and saves an immutable snapshot of that scan's
edges. Rescanning a repo replaces its live edges (so the graph always
reflects current code) while snapshots accumulate, giving
depatlas diff a timeline to compare. Services known only as a
dependency (not yet scanned directly) get a placeholder node, filled in
once their own repo is scanned.
Tests: tests/test_graph/, tests/test_intelligence/test_diff.py.
Ownership
Resolved in priority order: CODEOWNERS (majority owner across a
repo's files, last-matching-rule-wins) → depatlas.yaml manifest
fallback (explicit service→team mapping) → unowned.
Tests: tests/test_ownership/.
Alerts
All five SPEC.pdf alert types, checked automatically after every scan
(--no-alerts to disable) or on demand via depatlas alerts:
BREAKING_CHANGE(high) — a public function removed, its parameter count changed, or a parameter's type changed at the same position (only when both old and new have a known type) — on a service with at least one known dependent. A pure parameter rename is deliberately not flagged, since most real callers invoke positionally.NEW_CROSS_TEAM_DEPENDENCY(medium) — a new edge crossing a team boundary.HIGH_FAN_IN(medium) — a service's distinct dependent count crosses a threshold (default 10).ORPHANED_SERVICE(low) — no dependents and no dependencies.UNOWNED_SERVICE(low) — no resolved team.
Tests: tests/test_intelligence/test_alerts.py.
Using it in CI
A fresh CI runner has no stored history and has only your repo, so scan
alertscannot see what changed or who depends on you.depatlas checkdoes the before/after comparison in one run, with no database:
depatlas check --base origin/main --services services.json \
--graph org-graph.json --fail-on high
It finds the merge-base of --base and HEAD, scans that commit and your
working tree, and reports BREAKING_CHANGE and
NEW_CROSS_TEAM_DEPENDENCY for what changed. org-graph.json is the
output of depatlas export --format json, produced by a scheduled job
that scans every repo; it supplies the teams and the services that depend
on you (which one repo cannot know). Without --graph the check still
runs but says that no alert can fire. Exit status: 0 clean, 3 an alert
reached --fail-on, 1 the check could not run. --repo can point at a
subfolder of a monorepo.
# .github/workflows/depatlas.yml
on: pull_request
jobs:
depatlas:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 } # check needs history to find the merge-base
- uses: actions/setup-python@v5
with: { python-version: "3.12" }
- run: pip install depatlas
- run: depatlas check --base origin/${{ github.base_ref }} --services services.json --graph org-graph.json --fail-on high
The point-in-time alerts (HIGH_FAN_IN, ORPHANED_SERVICE,
UNOWNED_SERVICE) describe the whole graph rather than a change, so they
stay in depatlas alerts.
Full usage
# Scan a Java repo:
depatlas scan \
--repo tests/fixtures/sample_repo_java/payments \
--services tests/fixtures/payments_services_java.json \
--language java
# Scan a JS/TS repo:
depatlas scan \
--repo tests/fixtures/sample_repo_js/payments \
--services tests/fixtures/payments_services_js.json \
--language javascript
# Scan a real GitHub repo (requires DEPATLAS_GITHUB_TOKEN):
depatlas scan \
--github-repo sshafeeq84/DepAtlas \
--services tests/fixtures/payments_services.json
# Scan a real AWS CodeCommit repo (requires an AWS profile):
depatlas scan \
--codecommit-repo my-payments-repo \
--region us-east-1 \
--services tests/fixtures/payments_services.json
# Resolve ownership from a depatlas.yaml manifest instead of CODEOWNERS:
depatlas scan \
--repo tests/fixtures/sample_repo/payments \
--services tests/fixtures/payments_services.json \
--ownership-manifest tests/fixtures/depatlas.yaml
# List and diff snapshots explicitly:
depatlas snapshots --repo tests/fixtures/sample_repo/payments
depatlas diff --from 1 --to 2
# Filter alerts by severity:
depatlas alerts --severity medium
Tried on a real project
Run against the Java services of
Spring PetClinic Microservices
(one depatlas scan per service, with a small services/endpoints JSON):
DepAtlas found the API gateway's calls to the customers and visits
services (Spring WebClient) and the GenAI service's call to the vets
service. Running it on a real project also exposed bugs that the unit
tests had missed (a crash on modern Java syntax and undetected
WebClient calls), which are now fixed and covered by tests.
Known limitations
Known gaps, documented in the relevant modules and in
docs/CONTRIBUTING.md:
-
Full TypeScript syntax —
esprimaparses JavaScript, not TypeScript-specific syntax (type annotations, interfaces). A.tsfile using real TS syntax is skipped with a warning, not crashed on. Moving the JS/TS parser totree-sitter(as Java already uses) would fix this. -
Python signature rules — a parameter's kind (keyword-only, default value,
*args/**kwargs) is not modelled yet, so adding an optional parameter can be flagged as breaking, and a keyword-argument rename is not flagged. -
Dependents of a breaking change — every dependent is counted, not only those that import the changed code (HTTP callers depend on routes, which are not extracted yet).
-
Service manifest —
--servicesmust be written by hand; inferring module-to-service mappings is not built. -
CI graph —
depatlas checkneeds the org-wide graph file from somewhere: a scheduled job that scans every repo and runsdepatlas export. DepAtlas does not run that job for you, and the file is only as fresh as its last run.scan --fail-onstill needs a database that persists between runs. -
HTTP calls that name no service — only the hostname of an absolute URL is matched against service names. Calls routed through a gateway (
https://api.company.com/payments/...) or made through a base-URL client (webClient.uri("/owners")) needendpointsentries in the manifest. -
Test code — edges found in test files are stored and tagged (
from_test) but ignored by alerts. -
Not built yet:
boto3/grpccall detection, Maven/Gradle shared-library detection, and thewatchandinitcommands. -
The CodeCommit connector is tested against a mocked AWS API but has not been exercised against a real AWS account.
Running tests
pytest tests/ -v
Repository structure
depatlas/
├── depatlas/
│ ├── cli/ # CLI entry point (click)
│ ├── connectors/ # GitHub, AWS CodeCommit
│ ├── parsers/ # python_parser (ast), java_parser (tree-sitter),
│ │ js_ts_parser (esprima)
│ ├── graph/ # Models, graph builder, SQLite store
│ ├── ownership/ # CODEOWNERS + depatlas.yaml manifest
│ ├── intelligence/ # Diff engine, alerts
│ └── output/ # JSON and DOT exporters
├── tests/ # Mirrors the structure above, 1:1
├── docs/
│ ├── SPEC.pdf # Original v0.1 spec
│ └── CONTRIBUTING.md
└── pyproject.toml
Contributing
See docs/CONTRIBUTING.md for setup,
testing conventions, and known scope boundaries.
License
Apache 2.0 — see LICENSE.
Metadata
Release files for depatlas 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| depatlas-0.2.0.tar.gz | 69.0 kB | Without provenance | Details for depatlas-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| depatlas-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for depatlas-0.2.0-py3-none-any.whl |
Total release size: 134.2 kB
Release files / depatlas-0.2.0.tar.gz
| Download URL | depatlas-0.2.0.tar.gz |
|---|---|
| Size | 69.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
11804ef649236ba80d22e77fc1cca08e8f97b90a9b671228efbf0d5de1977b74
|
|
BLAKE2b-256 checksum How to use checksums |
c0a0040971df9035377bb918a472f2ac2e9ef2429e7d96f052d65014cc08593c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Release files / depatlas-0.2.0-py3-none-any.whl
| Download URL | depatlas-0.2.0-py3-none-any.whl |
|---|---|
| Size | 65.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
99af58573af77de774fc9aa37a9cd27655e11ac5680d792d6128c105d3bc839f
|
|
BLAKE2b-256 checksum How to use checksums |
28b46e59728c282fd2fadd3343667df2c3d12401ec58ca95a82df4261e80cf6b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Security for depatlas 0.2.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.