Skip to main content

Analyze and visualize complexity hotspots in Python codebases.

Project description

codaviz

A lightweight CLI that analyzes complexity in Python codebases and emits a single, self-contained, interactive HTML report — a simpler, local alternative to SonarQube for spotting where to refactor.

Point it at a repo and it ranks complexity hotspots, draws a treemap (sized by lines of code, colored by a metric you pick), lets you drill into any module to read its functions and source, and flags circular imports and over-threshold functions. No server, no database, no network — the report is one HTML file you can open offline or email to a teammate.

codaviz interactive report — treemap, top-modules chart, and per-function drill-down with cyclomatic + cognitive complexity

Quick start

codaviz is a uv project. From a checkout:

uv sync                          # install
uv run codaviz /path/to/project  # writes ./report.html
open report.html                 # (macOS; use xdg-open on Linux)

Try it on codaviz itself:

uv run codaviz . && open report.html

To install it as a standalone command:

uv tool install .        # then, anywhere: codaviz /path/to/project

Usage

codaviz [OPTIONS] [PATHS...]

  PATHS                Project directories to analyze (default: current dir).
                       Pass several to merge a workspace into one report.

  -f, --format         html | json | csv          (default: html)
  -o, --output FILE    Output file
                       (html → report.html; json/csv → stdout unless set)
      --no-source      Omit embedded source snippets (smaller, shareable report)
      --version        Show version and exit
  -h, --help           Show help and exit

Examples:

codaviz ~/src/myapp                     # interactive report.html
codaviz ~/src/myapp -o myapp.html       # custom output path
codaviz ~/src/myapp --no-source -o share.html   # no source embedded
codaviz ~/src/myapp -f json > data.json # raw entity data
codaviz ~/src/myapp -f csv  > data.csv  # one row per package/module/function
codaviz packages/*                      # merge a workspace into one report

The report

  • Treemap — packages and modules as nested tiles, sized by lines of code and colored by the selected metric (packages by their aggregate over all descendants; greener = better). Click a package to zoom in; a depth control caps how many levels show at once so large trees stay readable.
  • Metric selector — switch between Maintainability index (default), max/total cyclomatic, max/total cognitive, and lines of code; the treemap, bar chart, and table all re-rank instantly.
  • Hotspots table & bar chart — ranked by the selected metric, with LOC / MI / max & total cyclomatic / max & total cognitive / function count. A Modules / Packages toggle switches between per-module rows and package aggregates — so a complex package still stands out even when it's split into many small modules.
  • Function detail — click a tile, bar, or row to see that module's functions, each with a CC (cyclomatic) and Cog (cognitive) badge, line number, and source snippet. Functions over either threshold get a "consider extracting" / "hard to follow" hint.
  • Circular imports — modules that import each other (statically detected) are listed as cycles.

What gets analyzed

Inside a git repo, codaviz analyzes the Python files git knows about — tracked and uncommitted — while honoring .gitignore (so .venv, build output, and ignored trees are skipped). Outside a repo, it walks the directory. On top of that it always skips common noise: virtualenvs, caches, build/, dist/, node_modules/, site-packages/, migrations/, and test files (tests/, test_*.py, *_test.py, conftest.py) unless you opt in.

Metrics

Metric Meaning Direction
Cyclomatic (CC) McCabe complexity — branch/loop count + 1. Per function. Matches Ruff's C901 / python -m mccabe. higher = worse
Cognitive (Cog) SonarSource cognitive complexity — penalises nesting, ignores shorthand humans read easily. The better "how hard to understand" signal. Per function. higher = worse
Maintainability index (MI) radon's 0–100 composite (≥20 = A/good, 10–19 = B, <10 = C). Per module. Kept as the familiar number. lower = worse
SLOC Source lines of code (excludes blanks/comments). — (used for tile size)

Cyclomatic complexity comes from mccabe (so the numbers match Ruff), cognitive from cognitive_complexity, MI + SLOC from radon, and circular imports from a static ast import graph (no code is executed).

Configuration

Optional [tool.codaviz] table in the analyzed project's pyproject.toml:

[tool.codaviz]
exclude = ["generated/*.py", "vendor/**"]  # extra glob patterns to skip
max-complexity = 15                         # cyclomatic threshold for hints
max-cognitive = 15                          # cognitive threshold for hints
treemap-depth = 2                           # initial treemap depth (0 = all levels)
include-tests = false                       # set true to analyze test files too

Known limitations

  • Nested defs: closures and methods of function-local classes are folded into their enclosing function's score rather than listed separately — matching how Ruff/mccabe report the outer function.
  • Circular imports: resolution favors false negatives over false positives. src/ layouts, implicit namespace packages, and relative imports resolve correctly (names are computed relative to the detected source root); dynamic or conditional imports are not tracked.
  • Color scale: the badness ramp is green→amber→red with a "better → worse" legend and a numeric table as non-color channels; a fully colorblind-safe palette is a planned option.

Development

make test     # uv run pytest
make lint     # ruff check + format check + type checks
make format   # ruff format + autofix

The test suite spans unit / integration / end-to-end tiers, including in-browser execution of the report's JavaScript via Node.

Status

0.6.0. Stable and usable: hotspots, treemap (with package-level aggregates and tunable depth), drill-down, cyclomatic + cognitive complexity, maintainability index, circular imports, threshold hints, src/-layout and multi-root/workspace analysis, and HTML/JSON/CSV output. Planned next (in rough order): churn-weighted hotspots (complexity × git change-frequency), coupling metrics (afferent/efferent, instability), and trends over time. See notes/ for the vision, spec, and implementation plan, and CHANGES.md for the changelog.

Non-goals

Security scanning (use Bandit), runtime profiling (use cProfile/scalene), and test coverage (use pytest-cov) are out of scope — codaviz focuses on structural complexity.

License

Apache License 2.0 — see LICENSE.

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

codaviz-0.6.0.tar.gz (367.6 kB view details)

Uploaded Source

Built Distribution

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

codaviz-0.6.0-py3-none-any.whl (374.9 kB view details)

Uploaded Python 3

File details

Details for the file codaviz-0.6.0.tar.gz.

File metadata

  • Download URL: codaviz-0.6.0.tar.gz
  • Upload date:
  • Size: 367.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","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 codaviz-0.6.0.tar.gz
Algorithm Hash digest
SHA256 7d70d5b5bd32d20897ecc071b857a74d05bb41baacd68c9ab57ab6774a698579
MD5 b17c2edef9f03c9744aaf3fa82853529
BLAKE2b-256 7ea1adb7093c59a31198c6374d7f82d6b5d59890a6796219ef1a2684aa79a571

See more details on using hashes here.

File details

Details for the file codaviz-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: codaviz-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 374.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","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 codaviz-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cabc18ab1f77a79c5ae6173924d5c1fe2a28c32b2a3b06eb7b661a94449be6d0
MD5 ccf05bb4dfde9b60808a27321e311fad
BLAKE2b-256 c144d946e4807536c912e362d709ae1353d7b966548a381c3ee8085e53d77143

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