Tkinter GUI for visualizing and cleaning Python package dependencies.
Project description
PyPackagePruner
A Tkinter GUI for reviewing installed Python packages as a dependency tree and marking packages to keep or uninstall.
Install
After publishing to PyPI:
pip install py-package-pruner
py-package-pruner
Launch modes:
py-package-pruner --root
py-package-pruner .
py-package-pruner . inspects the current directory. If that directory contains a
.venv, the app manages packages from that virtual environment.
py-package-pruner --root opens from your home directory context.
For local development from this repository:
python -m pip install -e .
py-package-pruner
The app uses pipdeptree --json for discovery. pipdeptree is installed as a
package dependency.
On Linux, Tkinter may be packaged separately from Python. If the app fails with
No module named tkinter, install your distro's Tkinter package first, for
example:
sudo dnf install python3-tkinter
sudo apt install python3-tk
Features
- Builds a dependency graph from
pipdeptree --json. - Shows top-level packages in green, dependencies in blue, and orphan packages in orange.
- Displays package versions and reverse dependencies.
- Uses clickable checkbox markers to keep or mark packages for deletion.
- Warns before marking packages that other packages depend on.
- Uninstalls marked packages with
python -m pip uninstall -y. - Scans directories for virtual environments (
pyprune --root). - Inspects any venv without requiring pipdeptree to be installed in it.
Project Structure
pyprune/
├── __init__.py # Public API re-exports
├── __main__.py # python -m pyprune entrypoint
├── cli.py # Argument parsing & main()
├── models.py # PackageInfo and PackageGraph data models
├── subprocess_runner.py # Subprocess calls with timeouts & validation
├── scanner.py # Virtual environment discovery
└── ui/
├── __init__.py
├── app.py # Main application window (orchestrator)
├── toolbar.py # Toolbar and legend widgets
├── tree_view.py # Package tree widget
└── detail_panel.py # Package details panel
| Module | Responsibility |
|---|---|
models.py |
Pure data — PackageInfo dataclass and PackageGraph dependency graph. No UI or subprocess dependencies. |
subprocess_runner.py |
All external process calls (pipdeptree, pip list, pip uninstall). Adds timeouts, path validation, and package name sanitization. |
scanner.py |
Filesystem scanning to find .venv/venv directories. Includes path-traversal protection via symlink resolution. |
cli.py |
CLI argument parsing (--root, path positional) and the main() entrypoint. |
ui/app.py |
PackageCleanerApp(tk.Tk) — composes the UI widgets, manages application state, and coordinates background threads. |
ui/toolbar.py |
ToolbarFrame (buttons, search) and LegendFrame (colour-coded role labels). Callback-driven, no parent coupling. |
ui/tree_view.py |
PackageTreeView — Treeview with scrollbars, package insertion, filtering, checkbox toggling, and scan display. |
ui/detail_panel.py |
DetailPanel — side panel showing package metadata, dependencies, and venv info. |
Security
- Subprocess timeouts — all subprocess calls have a 60-second timeout to prevent hangs from broken interpreters or network issues.
- Path validation — Python executable paths are verified to exist and be
regular files before being passed to
subprocess.run. - Package name sanitization — names are validated against
^[A-Za-z0-9._-]+$before being passed topip uninstall. - Path-traversal protection — venv scanning resolves symlinks and ensures traversed paths stay within the original scan root.
- No shell execution — all subprocess calls use
shell=False.
Publish
Install build tools:
python -m pip install --upgrade build twine
Build the distribution:
python -m build
Check the artifacts:
python -m twine check dist/*
Upload to TestPyPI first:
python -m twine upload --repository testpypi dist/*
Then upload to PyPI:
python -m twine upload dist/*
Before uploading, confirm that the package name py-package-pruner is available
on PyPI. If it is taken, change project.name in pyproject.toml.
Notes
pipdeptree does not reliably expose whether a package was explicitly installed
by the user in every environment. This app classifies packages with no reverse
dependencies as top-level roots, and packages with no reverse dependencies and no
dependencies of their own as orphan packages.
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 py_package_pruner-0.1.0.tar.gz.
File metadata
- Download URL: py_package_pruner-0.1.0.tar.gz
- Upload date:
- Size: 23.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d16fb02686dbffcb87f611f2ca729410596ae767c501a4244d04e84fa685f2d0
|
|
| MD5 |
ae1ad8a04208a014bb44d86ba372f011
|
|
| BLAKE2b-256 |
8e7e3aac077b73619c81fe6939ce9919e2f081ab0a6b34680641f4fc597aed62
|
File details
Details for the file py_package_pruner-0.1.0-py3-none-any.whl.
File metadata
- Download URL: py_package_pruner-0.1.0-py3-none-any.whl
- Upload date:
- Size: 26.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
740a8b5293dbcd71d969772e75b6255ada168f021cea9ace6c4360b419e18ad7
|
|
| MD5 |
e262329f43113ee8a2e77e7ab46fee99
|
|
| BLAKE2b-256 |
700dc34d55317abd973b65b08a9f8556ae563afe21e0ec9145e8f09717343b6f
|