Static analysis tool that maps Python codebases. Dependency graphs, call graphs, and code complexity visualization.
CodeMap reads any Python codebase and tells you how it's wired together:
- Which files import which, the module-level dependency graph
- Which functions call which, the call graph at the symbol level
- Where the tangled parts are, complexity hotspots and circular dependencies
Point it at any project, get an X-ray of its structure in under 30 seconds.
When you join a new codebase, or come back to your own after six months, the hardest question is "where does anything live?" CodeMap answers that question visually, so you stop guessing and start reading the right files.
After installation:
codemap analyze path/to/your_file.pyYou get a Rich-formatted breakdown of every import, top-level function, class (with its methods), and call site in the file. Sample output (analyzing CodeMap's own CLI module): ╭──── 🗺️ CodeMap Analysis ────╮ │ src/codemap/cli.py │ ╰──────────────────────────────╯ ╭──────── Imports (9) ─────────╮ │ future annotations │ │ pathlib Path │ │ typer typer │ │ rich.console Console │ │ ... │ ╰──────────────────────────────╯ ╭─────── Functions (4) ────────╮ │ hello () line 30 │ │ version () line 41 │ │ analyze (path) line 47 │ │ main () line 72 │ ╰──────────────────────────────╯
Phase 3 adds project-wide dependency analysis:
codemap scan src/You get a digest of your codebase's wiring: total modules, internal vs external imports, the most-imported modules (your foundation layer), any circular dependencies, and any files that failed to parse. Exit codes are CI-friendly: 0 clean, 1 scan failed, 2 cycles detected.
Sample output (CodeMap scanning itself): ╭ 🕸️ CodeMap Dependency Graph ╮ │ src │ ╰──────────────────────────────╯ ╭──────── Stats ───────────────╮ │ Modules 11 │ │ Internal edges 11 │ │ External imports 26 │ │ Cycles 0 │ │ Parse errors 0 │ ╰──────────────────────────────╯ ╭──── Top imported ────────────────╮ │ 1 codemap.ast_engine.models 3 │ │ 2 codemap.ast_engine.parser 2 │ │ 3 codemap.version 2 │ │ 4 codemap.graph.builder 1 │ │ ... │ ╰──────────────────────────────────╯
Tip on the path argument. Point codemap scan at the directory that contains your top-level packages. For a src/ layout, that's src/. For a flat layout (with mypkg/ at the repo root), that's the repo root. Dotted paths in the output are computed relative to this directory and must match the import strings in your code for resolution to work.
Phase 4 goes one level deeper, from modules down to individual functions:
codemap callgraph src/You get a symbol-level map of which function calls which, with McCabe complexity attached to every function and a hotspot table that ranks functions by complexity × fan-in, the parts of the codebase most worth your attention when reading or refactoring. Sample output (CodeMap analyzing its own source):
╭ 📞 CodeMap Call Graph ───────╮
│ src │
╰──────────────────────────────╯
╭──────── Stats ───────────────╮
│ Functions 104 │
│ Internal edges 89 │
│ Self edges 17 │
│ External edges 61 │
│ Unresolved edges 262 │
╰──────────────────────────────╯
╭──── Hotspots (top 5) ──────────────────────────────────────────────────╮
│ 1 codemap.graph.resolver.resolve_import cx 8 fan-in 2 16 │
│ 2 codemap.callgraph.extractor._handle_call cx 6 fan-in 2 12 │
│ 3 codemap.graph.discovery.discover_modules cx 6 fan-in 2 12 │
│ 4 codemap.ast_engine.parser._resolve_callee cx 5 fan-in 2 10 │
│ 5 codemap.callgraph.builder.build_call_graph cx 9 fan-in 1 9 │
╰────────────────────────────────────────────────────────────────────────╯
Export the graph for visualization. Pipe to Graphviz or feed to your own tooling:
codemap callgraph src/ --format dot --output callgraph.dot
codemap callgraph src/ --format json --output callgraph.jsonTip on unresolved calls. Calls to Python builtins (len, str, isinstance), third-party functions, and dynamic dispatch (self.x() where x is computed) show up as unresolved by design. CodeMap reports them so you can see what your code depends on without pretending to resolve calls it can't statically prove.
Tip on hotspot scoring. complexity × fan-in ranks functions that are both internally complex and depended on from many callers. A function with complexity 12 called from one place is a refactoring candidate. A function with complexity 12 called from twenty places is a refactoring priority.
✅ Released, v0.4.0. Feature-complete for the original design.
Phase 1, Foundation ✅
- Project scaffold (src layout, pyproject.toml, hatchling)
- Typer CLI with
helloandversioncommands - Ruff + mypy + pytest config
- GitHub Actions CI on Python 3.11 and 3.12
Phase 2, AST parser ✅
- Domain models (immutable, slotted dataclasses)
- Import extraction (
import x,from x import y, aliases, dotted, relative) - Top-level function extraction (sync and async)
- Class extraction with methods
- Call-site extraction (Name and Attribute callees,
<unknown>for the rest) -
parse_file(path)integration entry point -
codemap analyze <path>CLI command with Rich output - 85 tests passing across the engine and CLI
Phase 3, Dependency graph ✅
- Project-wide module discovery (skips venvs, caches, VCS metadata)
- Import resolver (absolute, relative, submodule vs name disambiguation)
- networkx-backed
nx.DiGraphof module dependencies - Deterministic circular dependency detection (Johnson's algorithm via networkx)
- Parse-error tolerance: broken files don't abort the scan
-
codemap scan <directory>CLI with CI-friendly exit codes - 167 tests passing across the engine, graph, rendering, and CLI
Phase 4, Call graph & complexity ✅
- Symbol-level call graph with three-stage resolver (local names, dotted chains,
self.xmethods) - McCabe cyclomatic complexity per function
- Hotspot scoring (complexity × fan-in)
- Graph export (DOT and JSON)
-
codemap callgraph <path>CLI command - 367 tests passing across all engines, graphs, exporters, and CLIs
- Python 3.11+
ast(Python standard library) for parsingnetworkxfor the dependency graph and cycle detection- Typer + Rich for the CLI and pretty terminal output
- pytest + ruff + mypy for testing, linting, and type checking
git clone https://github.com/Purrnanssh/codemap.git
cd codemap
python3.11 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pytestMIT, see LICENSE.
Built by Purrnanssh Sinha.