Skip to main content

Understand your Python dependencies. Find cycles, dead modules, and architecture problems.

Project description

DependaMan

Understand your Python project's internal structure. Find cycles, dead modules, hotspots, and architecture problems — visualized as an interactive graph.

No external Python dependencies. Pure stdlib only.


Goal

Given a Python project directory, DependaMan produces an interactive HTML graph showing:

  • Which modules import which (directed dependency graph)
  • Which modules are never imported (dead code candidates)
  • Circular import chains
  • Modules with high fan-in (many dependents) or high fan-out (many dependencies)
  • Module size (lines of code, number of functions/classes)
  • Git churn: how often each module changes

Architecture

Phase 1 — File Discovery

Walk the project directory, collect all .py files, and determine the package root. Distinguish internal modules from external ones (stdlib + third-party are ignored).

Phase 2 — Import Parsing

Use ast to parse each file and extract import and from ... import statements. Resolve relative imports. Filter to internal-only imports.

Phase 3 — Graph Construction

Build a directed graph as an adjacency structure:

  • Node = internal module
  • Edge A → B = "module A imports module B"

Attach metadata to each node: file path, line count, function/class count.

Phase 4 — Analysis

Run these passes on the graph:

  • Dead code: nodes with no incoming edges and not an entry point
  • Circular imports: detect cycles (DFS-based)
  • Hotspots: nodes ranked by fan-in (most imported)
  • Coupling: nodes ranked by fan-out (imports the most)

Phase 5 — Git Integration

Use subprocess + git log to compute per-file:

  • Commit frequency (how often it changes)
  • Lines added/removed over time (churn)
  • Last author that changed the file

Attach this data to graph nodes. Optional: skipped if the project is not a git repo.

Phase 6 — HTML Output

Generate a self-contained .html file (or return HTML as a string for web integration).

The HTML template is a static string embedded in Python. Only the data changes between runs. Python serializes the graph to JSON and injects it into the template — no templating library needed:

import json

data = json.dumps({"nodes": [...], "edges": [...]})
html = TEMPLATE.replace("__GRAPH_DATA__", data)

The template contains a <script> block that reads the injected data and renders the graph using the browser's <canvas> or SVG API. No external JS libraries required.

The graph supports:

  • Hover tooltips: quick summary (import count, churn score)
  • Click modals: full detail panel (git log, list of dependents/dependencies, size metrics)

The output function signature is designed to be framework-agnostic:

def render(graph, analysis) -> str:  # returns HTML string
    ...

This makes it trivial to plug into FastAPI, Flask, or any other framework:

# FastAPI example
@app.get("/graph", response_class=HTMLResponse)
def dependency_graph():
    graph = build_graph(".")
    analysis = analyze(graph)
    return render(graph, analysis)

Package Structure

DependaMan is distributed as a Python package (dependaman). The current layout:

dependaman/
    __init__.py        # public API: dependaman()
    __main__.py        # CLI entry point
    core.py            # orchestration
    discovery.py       # Phase 1 — file discovery
    parser.py          # Phase 2 — import parsing
    graph.py           # Phase 3 — graph construction
    analysis.py        # Phase 4 — analysis passes
    git.py             # Phase 5 — git integration
    renderer.py        # Phase 6 — HTML output
    pool.py            # GIL-aware executor selection

Entry point via pyproject.toml:

[project.scripts]
dependaman = "dependaman.__main__:dependaman"

Usage

CLI:

dependaman              # analyzes current directory, opens browser
dependaman /path/to/project

Python API:

from dependaman import dependaman

html = dependaman(".", in_memory=True)   # returns HTML string
dependaman(".")                          # writes output.html + opens browser

Roadmap

  • Phase 1: File discovery
  • Phase 2: Import parsing (ast)
  • Phase 3: Graph construction
  • Phase 4: Analysis (dead code, cycles, hotspots)
  • Phase 5: Git integration
  • Phase 6: HTML renderer
  • Phase 7: Unused symbol detection (functions, classes, methods never imported)
  • Phase 8: Installable package (uv pip install -e .)
  • Phase 9: CLI entry point with auto project root detection and browser open
  • Phase 10: Performance — parallel git stats (ThreadPoolExecutor), GIL-aware pool for parsing and graph construction
  • Phase 11: Published to PyPI (v1.0.2)

Phase 12 — Visualization overhaul

  • Hierarchical circle packing layout — packages contain sub-packages, no circle/node overlap
  • Zoom-to-fit button + F shortcut (fits all package circles in view)
  • Color encoding — node fill: (pastel) blue→red by commit frequency; package border brightness by nesting depth
  • Test filter toggle — hide/show nodes, edges, and packages containing "test"
  • Node spacing fix + minimum arrow length
  • Click interaction — select node + open modal; click package circle to zoom into it; click empty to deselect
  • Modal navigation — click any import/imported-by entry to jump to that node
  • Middle-click panning; Escape closes modal and deselects in one press
  • Search/filter bar — fuzzy search by module name, jump to and highlight it
  • Performance — rAF-throttled panning/zoom, precomputed draw order
  • Publish v1.0.3

Future ideas

  • Call graph (function/method level, not just module level)
  • Documentation site
  • Web integration example (FastAPI/Flask endpoint returning HTML)
  • --format json output option for external tooling

Project details


Download files

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

Source Distribution

dependaman-1.0.3.tar.gz (22.8 kB view details)

Uploaded Source

Built Distribution

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

dependaman-1.0.3-py3-none-any.whl (23.2 kB view details)

Uploaded Python 3

File details

Details for the file dependaman-1.0.3.tar.gz.

File metadata

  • Download URL: dependaman-1.0.3.tar.gz
  • Upload date:
  • Size: 22.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for dependaman-1.0.3.tar.gz
Algorithm Hash digest
SHA256 80d7b7b78fa59b0532a7f535a1d816a686baeebb45790b606142212bc2ad2cd5
MD5 17e39619e56494202d1c90d49fc13935
BLAKE2b-256 07497723bdd3daa956fbcb36b0d61120964f7803edf26b443cf33bd79588def4

See more details on using hashes here.

File details

Details for the file dependaman-1.0.3-py3-none-any.whl.

File metadata

  • Download URL: dependaman-1.0.3-py3-none-any.whl
  • Upload date:
  • Size: 23.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for dependaman-1.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 d9b99aa2a55d4cde9cd41455598c21e4eae62c9b17439cbf9770517487272929
MD5 c634aa84d9bab5319c5d68bf55ddb5fe
BLAKE2b-256 1d9b41637ccff2e5681d97ef37af494823623c9ba5fed8a80e3458e09e60faa6

See more details on using hashes here.

Supported by

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