Static analysis CLI for Python import graphs and dependency summaries
Project description
NetImport: Python Project Architecture Analyzer via Import Graphs
NetImport is a static analysis CLI for Python projects. It scans source files, parses import statements, resolves those imports into project, standard-library, external, or unresolved dependencies, and then presents the result as either a dependency graph or a deterministic console summary.
It is intended for architecture inspection, refactoring support, and CI-friendly dependency review. The current release is positioned as a beta-stage developer tool: the core workflows are implemented and tested, while known static-analysis limitations are documented explicitly.
Quick Start
Install NetImport and run it against a project directory:
pip install netimport
netimport example --show-console-summary
If you are working from this repository locally:
poetry install
poetry run netimport example --show-console-summary --no-show-graph
Remove --no-show-graph if you want to open the graph visualization instead of running in summary-only mode.
Core Features
- Import Analysis: Recursively scans the specified project directory for Python files and parses their
importstatements. - Dependency Graph Construction: Creates a directed graph where nodes represent project modules/packages, as well as external and standard libraries. Edges depict the imports between them.
- Graph Visualization: Supports an interactive Bokeh view with a constrained layout tuned for dependency graphs.
- Console Summary: Prints a deterministic text report with project-level counts and coupling tables.
- Configuration via CLI and TOML files: Supports CLI overrides plus config from
[tool.netimport]inpyproject.toml,.netimport.toml, or an explicit--configTOML file. - Dependency Type Identification: Distinguishes imports of internal project modules, Python standard libraries, and external third-party dependencies.
Why Use NetImport?
- Understand Project Structure: Gain a clear visual overview of how different parts of your application are interconnected. This is especially useful for new team members or when working with legacy code.
- Assess Coupling: Identify modules that are highly dependent on each other. High coupling can make code harder to change, test, and reuse.
- Gauge Cohesion (Indirectly): While directly calculating cohesion from imports alone is difficult, the graph can provide insights into how logically grouped functionalities are within a module by observing its dependencies.
- Aid Refactoring: Use the graph as a map during refactoring to understand which parts of the system will be affected by changes.
- Architectural Oversight: Helps in maintaining a clean and understandable architecture by making dependencies explicit.
Current Support Contract
NetImport currently supports:
- Static analysis of Python source trees based on AST-parsed
importstatements. - Deterministic console summaries for headless runs and CI-oriented inspection.
- Interactive Bokeh visualization with the supported constrained layout documented in the CLI and README.
- Configuration from
[tool.netimport]inpyproject.toml,.netimport.toml, explicit--configfiles, and CLI overrides.
Installation
pip install netimport
or
poetry add netimport
Usage
NetImport can be used from the command line and is suitable for integration into CI/CD pipelines.
Command Line Interface
netimport [OPTIONS] <PROJECT_PATH>
Current CLI Options
PROJECT_PATH
Path to the root directory of the Python project to analyze.
--layout [constrained]
Choose a layout name for the selected graph backend. If omitted, NetImport uses the backend default.
--config FILE
Load an explicit TOML config file and apply it after project config has been loaded from the analyzed project. The file may either contain top-level NetImport keys or a [tool.netimport] section.
--show-graph [bokeh]
Select the visualization backend. Current default is bokeh.
Supported backend/layout combinations:
bokeh:constrained(default)
Unsupported combinations are rejected with a clear CLI error instead of silently falling back.
--no-show-graph
Disable graph visualization even if a graph backend is configured. This is useful for CI, terminals, or summary-only runs.
--show-console-summary
Print a textual dependency report with tables for:
- overall graph counts
- project coupling metrics
- most/least coupled project files
- most depended-on project files
- most dependent project files
- external dependencies
- unresolved imports
--summary-format [text|json]
Choose the output format for --show-console-summary.
--fail-on-violation
Exit with code 1 when configured policy violations are found. This is intended
for CI usage together with summary output.
textkeeps the current human-readable table outputjsonemits a deterministic machine-readable report for CI and automation
--ignored-dir TEXT
Ignore a directory name during project file discovery. Can be passed multiple times.
--ignored-file TEXT
Ignore a file name during project file discovery. Can be passed multiple times.
--ignored-node TEXT
Ignore a graph node by label or id. Can be passed multiple times.
--ignore-stdlib / --include-stdlib
Override whether standard library modules should be excluded.
--ignore-external-lib / --include-external-lib
Override whether external libraries should be excluded.
Examples
Below are the supported launch modes with a short explanation of what each mode is for.
Default interactive mode
Use this when you want the standard interactive graph view with folder grouping and node dragging.
poetry run netimport example
This is equivalent to --show-graph bokeh --layout constrained.
Explicit interactive mode
Use this when you want to call the default interactive mode explicitly in scripts, docs, or manual checks.
poetry run netimport example --show-graph bokeh --layout constrained
This opens the Bokeh visualizer with the constrained layout.
Graph plus console summary
Use this when you want both the graph visualization and the textual dependency report in the same run.
poetry run netimport example --show-console-summary
Summary-only mode
Use this in CI, SSH sessions, terminals without GUI support, or when you only need the textual report.
poetry run netimport example --show-console-summary --no-show-graph
JSON summary mode
Use this in CI or scripts when you want a stable machine-readable dependency report.
poetry run netimport example --show-console-summary --summary-format json --no-show-graph
Explicit config file
Use this when you want to keep a reusable analysis profile outside the analyzed project root, or when CI should point NetImport at a dedicated config file.
poetry run netimport example --config ci/netimport.toml --show-console-summary --no-show-graph
Example summary output:
(This report summarizes the project's import graph so a reader can spot hotspots, risky dependencies, isolated files, and missing links.)
(Incoming degree shows how many project files depend on a file; outgoing degree shows how many dependencies a file pulls in. Higher values usually mean higher impact or complexity.)
Dependency Graph Summary
========================
(High-level graph totals. Use this table to quickly size the project and see how much of the graph is project code, stdlib, external libraries, or unresolved imports.)
+--------------------------+-------+
| Metric | Value |
+--------------------------+-------+
| Nodes | 14 |
| Edges | 18 |
| Project files | 11 |
| Standard library modules | 3 |
| External libraries | 0 |
| Unresolved imports | 0 |
+--------------------------+-------+
Project Coupling Metrics
========================
(Aggregate coupling across all project files. Avg and Median describe a typical file, while Min and Max highlight the spread and the biggest extremes.)
+------------------------+------+--------+-----+-----+
| Metric | Avg | Median | Min | Max |
+------------------------+------+--------+-----+-----+
| Project files analyzed | 11 | - | - | - |
| Incoming degree | 0.91 | 1.00 | 0 | 3 |
| Outgoing degree | 1.64 | 1.00 | 0 | 5 |
| Total degree | 2.55 | 2.00 | 0 | 5 |
+------------------------+------+--------+-----+-----+
Configuration
NetImport reads configuration from the analyzed project directory, not from the caller's current working directory.
Supported config files:
[tool.netimport]inpyproject.toml.netimport.toml- explicit TOML file passed via
--config
Precedence:
- built-in defaults
pyproject.toml.netimport.toml- explicit
--configfile - CLI options
For collection options (ignored_dirs, ignored_files, ignored_nodes), later file-based config replaces earlier file-based values, and CLI values are added on top at the final step. For boolean options (ignore_stdlib, ignore_external_lib), later config sources replace earlier ones, and explicit CLI flags override file config values.
Supported keys:
ignored_dirsignored_filesignore_stdlibignore_external_libignored_nodesfail_on_unresolved_importsforbidden_external_libs
pyproject.toml example:
[tool.netimport]
ignored_dirs = ["venv", ".venv", "tests", "docs", "__pycache__", "node_modules", "migrations"]
ignored_files = ["setup.py", "manage.py"]
ignore_stdlib = true
ignore_external_lib = true
ignored_nodes = []
fail_on_unresolved_imports = true
forbidden_external_libs = ["requests"]
.netimport.toml example:
ignored_dirs = ["venv", ".venv"]
ignored_files = ["setup.py"]
ignore_stdlib = false
ignore_external_lib = false
ignored_nodes = []
fail_on_unresolved_imports = false
forbidden_external_libs = []
Explicit --config example using top-level keys:
ignored_dirs = ["generated"]
ignored_files = ["bootstrap.py"]
ignore_stdlib = true
ignore_external_lib = false
ignored_nodes = ["requests"]
fail_on_unresolved_imports = true
forbidden_external_libs = ["requests"]
Explicit --config can also point to a pyproject.toml-style file:
[tool.netimport]
ignored_dirs = ["generated"]
ignore_stdlib = true
Current Limitations
NetImport is intentionally conservative about unsupported cases. Today that means:
- It is a static analyzer, so runtime imports, plugin loading, and
sys.pathmutations are not modeled. - Namespace packages are not part of the supported resolver contract.
from ... import *is handled conservatively and may remain partial when exports are dynamic.- Visualization support is limited to the documented backend/layout combinations instead of silently guessing unsupported modes.
Roadmap
The items below are future enhancements, not part of the current support contract.
- Architectural Metrics Calculation:
- Count of incoming/outgoing dependencies for each module (Afferent/Efferent Couplings).
- Calculation of Instability (I) metric.
- (Further research needed for A) Calculation of Abstractness (A) and Distance from Main Sequence (D) metrics, potentially with user-assisted annotation for abstract components.
- Defining Layers and Rule Checking: Ability to define architectural layers and validate rules between them (e.g., via a configuration file).
- Advanced Visualization:
- Interactive HTML reports (e.g., using pyvis or bokeh).
- Highlighting specific nodes or paths on the graph.
- Grouping nodes by package or defined layer.
- Plugin for popular IDEs (VSCode, PyCharm).
- CI/CD Integration: Output results in CI-friendly formats (e.g., JUnit XML), allow setting metric thresholds.
- Improved Import Resolution:
- Better handling of all for more accurate analysis of from ... import *.
- More precise import resolution considering sys.path modifications and namespace packages.
Contributing
Contributions are welcome to make NetImport better! If you'd like to help, please check out CONTRIBUTING.md for instructions on setting up your development environment, code style, and the process for submitting Pull Requests.
Key areas for contribution:
- Implementing new features from the Roadmap.
- Improving the existing codebase (refactoring, optimization).
- Writing tests.
- Enhancing documentation.
- Bug fixing.
Feel free to open Issues to discuss new ideas or problems.
License
This project is licensed under the MIT License. See LICENSE.txt for the full text.
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
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 netimport-0.1.2.tar.gz.
File metadata
- Download URL: netimport-0.1.2.tar.gz
- Upload date:
- Size: 34.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.3.1 CPython/3.13.7 Darwin/24.6.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
588919aaa3f3999c8af1cf6daef2300a4fb7857a4bdb03f954f073a979bf8b3d
|
|
| MD5 |
ad86e3d81d2f858ba010095ce9bc0c71
|
|
| BLAKE2b-256 |
eab26849d7c25935b44bcbbdfb2ad99f41b60c904873a9bc51a158204df09c8d
|
File details
Details for the file netimport-0.1.2-py3-none-any.whl.
File metadata
- Download URL: netimport-0.1.2-py3-none-any.whl
- Upload date:
- Size: 34.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.3.1 CPython/3.13.7 Darwin/24.6.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
52373263e870138637017a68e596da7c354c35d7c1df72b88cbc18445ac66f4d
|
|
| MD5 |
b555f57117d6c2d2d1f9601211f6188d
|
|
| BLAKE2b-256 |
ffa44ddf120fc12b2ba8025aaace0ee326615d600b774f2187b217e388e25f17
|