Static Python project analyzer with CLI summaries, graphs, and JSON output.
Project description
analyze_project
analyze_project is a single-file Python utility for statically inspecting a Python codebase and exporting:
- A terminal summary of modules, classes, functions, leaves, entry points, hotspots, warnings, and resolved vs unresolved calls
- A module dependency graph as
project_analysis.png - A cross-module call graph as
project_call_graph.png - A hotspot chart as
project_hotspots.png - A machine-readable report as
project_analysis.json
It is designed for quick structural analysis without modifying the target repository.
Requirements
- Python 3.9+
- Runtime dependencies are installed automatically from package metadata
Installation
pip install analyze-project
For isolated CLI installs, pipx is a good fit:
pipx install analyze-project
For a local checkout before publishing to PyPI:
python3 -m venv .venv
source .venv/bin/activate
pip install -e .[dev]
Usage
Analyze the current working directory:
analyze-project
Analyze a specific project:
analyze-project /path/to/python-project
Only generate JSON:
analyze-project /path/to/python-project --json-only
Only print the terminal summary:
analyze-project /path/to/python-project --summary-only
Show unresolved call examples:
analyze-project /path/to/python-project --show-unresolved
Filter scanned files:
analyze-project /path/to/python-project --include-glob "pkg/*.py" --exclude-dir generated
Module execution is also supported:
python -m analyze_project /path/to/python-project
CLI
analyze-project [target] [--output-dir PATH] [--depth N] [--max-branches N] [--max-entry-trees N] [--hotspots N] [--non-recursive] [--include-glob PATTERN] [--exclude-dir NAME] [--show-unresolved] [--summary-only | --json-only]
target: Directory to analyze. Defaults to the current working directory.--output-dir PATH: Output directory for generated artifacts. Defaults to./analysis_output/<project_name>/.--depth N: Maximum call tree depth in the terminal summary.--max-branches N: Maximum number of call branches shown per tree node.--max-entry-trees N: Maximum number of entry-point call trees printed.--hotspots N: Number of most-called callables to include.--non-recursive: Only analyze Python files in the top-level target directory.--include-glob PATTERN: Repeatable relative-path glob filter for.pyfiles.--exclude-dir NAME: Repeatable directory name to exclude in addition to the built-in skip list.--show-unresolved: Print unresolved call examples in the terminal summary.--summary-only: Do not write JSON or image artifacts.--json-only: Only writeproject_analysis.json; skip image generation.
Output files
Default runs generate:
project_analysis.pngproject_call_graph.pngproject_hotspots.pngproject_analysis.json
When --json-only is used, only project_analysis.json is written. When --summary-only is used, no artifacts are written.
JSON report
project_analysis.json keeps the original top-level analysis sections and adds structured metadata for downstream tooling.
New top-level fields:
schema_versionwarningsstatsunresolved_calls
The stats object currently includes:
files_scannedfiles_skippedsyntax_error_filesresolved_callsunresolved_callscross_module_edges
Resolution behavior
The analyzer now handles these common local patterns more accurately:
from pkg import submodulefrom pkg.module import symbol- aliased imports
- nested relative imports
- package directories with
__init__.py - simple instance tracking such as
svc = Service(); svc.work() - simple module-backed instance tracking such as
obj = module.Factory(); obj.method()
Known limitations
- The analysis is static and AST-based; dynamic imports, monkey-patching, and runtime dispatch cannot always be resolved.
- Deep data-flow and alias tracking are intentionally shallow; only simple same-scope constructor assignments are followed.
- Re-export-heavy package APIs and
from x import *cannot be resolved with full precision. - Unknown object calls may appear in
unresolved_callseven when they are valid at runtime. - The cross-module call graph and hotspot chart are skipped when the analyzed project does not contain the required edges.
Development
Install development dependencies and run checks:
pip install -e .[dev]
python -m py_compile analyze_project.py tests/test_cli.py
ruff check .
pytest
python -m build
python -m twine check dist/*
Publishing
Once the package name has been created on PyPI, the intended install command is:
pip install analyze-project
This repository includes a GitHub Actions publishing workflow that is ready for PyPI Trusted Publishing. Configure the PyPI project to trust this GitHub repository, then publish from GitHub Releases or a manual workflow run.
License
MIT. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file analyze_project-0.1.0.tar.gz.
File metadata
- Download URL: analyze_project-0.1.0.tar.gz
- Upload date:
- Size: 20.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5c84f21fa4640af2376ef6ee57e896773b97246a5654c6d2259c0b5a15c61378
|
|
| MD5 |
a65738f69dde6f4c9b79cd85c312aa7f
|
|
| BLAKE2b-256 |
95d73f2bb772d109296aa65dad333a6c595d8c7623591fc2ac0891cc183cd29c
|
File details
Details for the file analyze_project-0.1.0-py3-none-any.whl.
File metadata
- Download URL: analyze_project-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6ef928d9cf491f55c246e7c2d91eaf9e764b6f40a9fb3cfb64ef370db1a7db35
|
|
| MD5 |
8b1f1ab97271d09ed416f936cd3d5266
|
|
| BLAKE2b-256 |
bbfdcd82a16798b34559a60e3d00b4ca87a86458b0b402dea6c84894980bce6c
|