Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes

How to Generate a Dependency Graph for Python Projects

This script walks through a Python project directory, parses each .py file's imports, and prints a dependency graph showing which modules depend on which other modules.

Medium Python 3.9+ Jun 28, 2026 Automation & scripting 19 views 0 copies

Python code

36 lines
Python 3.9+
import os
import ast
from pathlib import Path
from collections import defaultdict

def get_imports(filepath):
    with open(filepath) as f:
        try:
            tree = ast.parse(f.read())
        except SyntaxError:
            return []
    imports = []
    for node in ast.walk(tree):
        if isinstance(node, ast.Import):
            for alias in node.names:
                imports.append(alias.name.split('.')[0])
        elif isinstance(node, ast.ImportFrom):
            if node.module:
                imports.append(node.module.split('.')[0])
    return imports

def build_dependency_graph(project_dir):
    dependencies = defaultdict(set)
    project_path = Path(project_dir)
    
    for pyfile in project_path.rglob("*.py"):
        module = pyfile.stem
        for imp in get_imports(pyfile):
            dependencies[module].add(imp)
    
    for module, deps in dependencies.items():
        if deps:
            print(f"{module}: {', '.join(sorted(deps))}")

if __name__ == "__main__":
    build_dependency_graph(".")

Output

stdout
main: utils, config
db: utils
utils: os

How it works

The script uses ast.parse to safely extract all import statements without executing the code. get_imports returns the top-level package name for each import, ignoring submodules. Dependencies are aggregated in a defaultdict(set) to avoid duplicates. Finally, each module and its sorted dependencies are printed to stdout.

Common mistakes

  • Forgetting to handle syntax errors when parsing individual files.
  • Mistaking `ast.ImportFrom` with an empty `node.module` for relative imports.
  • Not resolving submodule imports (e.g., importing `os.path` and logging only `os`).

Variations

  1. Generate a visual graph using Graphviz instead of text output.
  2. Filter out standard library imports to see only third-party dependencies.

Real-world use cases

  • Auditing a legacy codebase to understand module coupling before refactoring.
  • Enforcing architectural boundaries in a CI pipeline by checking for forbidden dependencies.
  • Generating documentation for new contributors about the project's internal module structure.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Automation & scripting

Related tutorials and quizzes for this topic.