Skip to content

amandadiasdev/py-pip-man

Repository files navigation

PyPipMan Logo

PyPipMan

A Python dependency analysis tool that detects ghost dependencies, zombie dependencies, and outdated packages in your projects.


Table of Contents


Overview

Python projects accumulate dependencies over time. Libraries go stale, get abandoned, or stop being used — but they stay in your config files. PyPipMan analyzes your project and tells you exactly what's happening with your dependencies.

Given a Python project directory (or a single dependency/source file), PyPipMan:

  1. Parses dependency configuration files (pyproject.toml, requirements.txt, uv.lock, poetry.lock).
  2. Parses all .py source files using Python's AST (Abstract Syntax Tree).
  3. Crosses declared dependencies against actual imports found in the code.
  4. Queries the PyPI REST API at https://pypi.org/pypi/{package}/json (where {package} is the package name) to check for newer versions.
  5. Reports everything in a graphical dashboard, terminal output, or exported files.

Features

Feature Description
👻 Ghost dependencies Names used in code with no backing import (e.g. requests.get(...) without import requests)
🧟 Zombie dependencies Imports that exist in the source but are never referenced anywhere
📦 Total dependencies Full list of dependencies found in config files
❌ Missing dependencies Modules imported but absent from any config file
🗑️ Unused dependencies Declared packages not referenced anywhere in the source code
🕰️ Outdated dependencies Packages with a newer version available on PyPI
🖥️ GUI Dashboard Interactive Tkinter dashboard with charts, filters, and light/dark themes
⌨️ CLI Click-based command line with analyze, check, and graph commands
📟 TUI Arrow-key-navigable terminal menu built with rich and prompt_toolkit
📄 PDF Report Full PDF report with summary and dependency table
📊 CSV Export Flat CSV export for tracking dependencies over time
🔗 Dependency Graph NetworkX graph of file → module relationships

Architecture Overview

PyPipMan is organized in layers. Each layer has a single responsibility and communicates with adjacent layers through well-defined interfaces.

Architecture

Entry Points

File Description
__main__.py Enables python -m py_pip_man execution
__init__.py Package metadata (__version__, __author__)

CLI Layer

Located in cli/.

File Description
base.py Click command group. Defines analyze, check, graph, menu, and gui commands
tui.py Terminal User Interface built with rich and prompt_toolkit. Interactive arrow-key navigation
utils.py Formatting helpers: colored output, graph plotting with matplotlib, result rendering

Commands available:

py_pip_man analyze <path>     # Analyze a single .py or dependency file
py_pip_man check   <path>     # Full project analysis (directory)
py_pip_man graph   <path>     # Build and display the dependency graph
py_pip_man menu               # Launch the interactive TUI menu
py_pip_man gui                # Launch the graphical dashboard

Core — Analyzers

Located in core/analyzers/.

The coordinator (coordinator.py) is the central orchestrator. It calls parsers, merges observations, runs all analyzers, and assembles the final result dictionary.

Analyzers are split into three sub-packages:

Sub-package Analyzer Description
import_analyzers/ ghost_analyzer.py Detects names used in code with no backing import
import_analyzers/ zombie_analyzer.py Detects imports that are declared but never referenced
usage_analyzers/ ghost_analyzer.py Same ghost logic, scoped to a specific file context
usage_analyzers/ zombie_analyzer.py Same zombie logic, applied to merged project-wide observations
package_analyzers/ outdated_analyzer.py Queries PyPI and compares declared vs. latest versions

Ghost dependency — a name used in the code that has no import statement behind it. Example: calling requests.get(...) without import requests.

Zombie dependency — an import that exists in the source but is never called or referenced anywhere. Example: import os at the top of a file where os is never used.

Core — Parsers

Located in core/parsers/.

Split into two sub-packages:

source_code/ — Parses .py files using Python's built-in ast module.

File Description
py_parser.py Entry point. Opens a .py file, builds the AST, walks it, and returns an observations dict
program_structure.py Converts the AST into a NetworkX DiGraph for topological traversal
handlers.py AST node handlers (one per node type). Uses a DISPATCH table to map node types to handler functions
utils.py Token validation, graph node helpers, AST argument and target collectors

The observations dict returned by the source parser contains:

{
    "modules":        set,   # top-level module names from import statements
    "bindings":       dict,  # local_name -> (module, kind)
    "symbols":        dict,  # name -> metadata (file, line, version, ...)
    "imported_items": set,   # names imported via `from X import Y`
    "aliases":        dict,  # alias -> original module
    "locals":         set,   # locally assigned variable names
    "functions":      set,   # function names defined in the file
    "classes":        set,   # class names defined in the file
    "usages":         set,   # all Name nodes loaded (used) in the file
}

dependencies/ — Parses dependency configuration files.

File Description
factory.py Dispatch table mapping filenames to parsers. Adding a new format only requires adding one entry here
requirements_parser.py Parses requirements.txt line by line using regex
toml_parser.py Parses pyproject.toml (PEP 621 and Poetry styles) using pytoml
lock_parser.py Parses uv.lock and poetry.lock files (TOML [[package]] blocks)

All dependency parsers return the same observations dict structure, populating modules and symbols with the package names and versions found.

Core — API Wrapper

Located in core/api_wrapper.py.

Thin wrapper around the PyPI REST API at https://pypi.org/pypi/{package}/json.

Function Description
make_api_request(url) Sends HTTP GET/POST and returns JSON as dict. Returns {} on any failure
get_info(package_name, version?) Fetches full package info from PyPI
get_latest_version(package_name) Returns the latest version string for a package
get_attribute(data, attribute) Extracts a named field from a PyPI response using PYPI_ATTRIBUTE_MAP

No hard dependencies beyond requests. Returns empty results gracefully on network failures.

Core — Output

Located in core/output/output_manager.py.

Function Description
save_json_report(results, filepath) Saves the full analysis result as JSON
save_csv_report(results, filepath) Flattens all sections into a single CSV
save_multiple_csv_reports(results, filepath) One CSV file per section (ghost, zombie, etc.)
export_results(results, filepath, format_type) Dispatcher: calls JSON or CSV saver based on format_type

GUI

Located in gui/. The GUI is split into focused modules so that layout, styling, state, and side-effect actions each live in their own file.

File Description
dashboard.py Entry point. Initializes the Tkinter root window and starts the main loop
components.py Layout builders for the header, upload card, metric cards, filter tabs, and table
constants.py Colors, fonts, and theme definitions (dark and light, selected via PYPIPMAN_THEME)
state.py Centralized state dict holding references to widgets and current analysis data
ttk_style.py Styling for ttk widgets (Treeview heading, scrollbar)
services.py Data shaping: turns analysis results into table rows and counters
file_utils.py Cross-platform helpers to open files with the system default application
report_pdf.py ReportLab PDF generator with header, summary counters, table, and graph info
actions/ Side-effect functions triggered by buttons (analysis, filtering, exports, charts)

The actions/ sub-package contains:

File Description
analysis_actions.py analyze_file_action, analyze_project_action, run_analysis, process_analysis_result
view_actions.py update_metrics, update_filter_labels, fill_table, apply_filter, update_path_label
chart_actions.py update_chart — renders a matplotlib horizontal bar chart inside the dashboard
export_actions.py export_csv, export_report (PDF) — open save dialogs and write to disk

The dashboard uses a centralized state dict pattern. All UI components read from and write to state, which avoids passing widget references between functions.

Key entry points:

Function Location Description
start_gui() dashboard.py Initializes and runs the Tkinter main loop
run_analysis() actions/analysis_actions.py Calls analyze_file or analyze_project and feeds results into the UI
process_analysis_result(...) actions/analysis_actions.py Updates state, metrics, table rows, and labels after analysis
apply_filter(key) actions/view_actions.py Switches between dependency categories (all, ghost, zombie, etc.)
export_csv() actions/export_actions.py Opens a save dialog and writes the current rows to CSV
export_report() actions/export_actions.py Opens a save dialog and generates a PDF via report_pdf.py
update_chart() actions/chart_actions.py Renders a matplotlib horizontal bar chart inside the dashboard

Getting Started

Prerequisites

  • Python 3.12 or higher
  • uv (recommended) or pip

Installation

1. Clone the repository:

git clone https://gitlab.unipampa.edu.br/<your-group>/py_pip_man.git
cd py_pip_man

2. Create a virtual environment and install dependencies:

Using uv (recommended):

uv sync

Using pip:

python -m venv .venv
source .venv/bin/activate      # Linux/macOS
.venv\Scripts\activate         # Windows

pip install -e .

3. Verify the installation:

python -m py_pip_man --version

You should see py_pip_man, version 0.1.0.


Usage

Graphical Interface (GUI)

Launch the full graphical dashboard:

python -m py_pip_man gui

# Light theme
PYPIPMAN_THEME=light python -m py_pip_man gui

# Dark theme (default)
PYPIPMAN_THEME=dark python -m py_pip_man gui

Steps inside the GUI:

  1. Click Analyze File to select a single .py, requirements.txt, or pyproject.toml file.
    Or click Analyze Project to select a project directory.
  2. Click ▶ Analyze to run the analysis.
  3. Use the filter buttons (All, Ghost, Zombie, Missing, Unused, Outdated, Charts) to explore results.
  4. Click Export CSV to save the dependency list as a CSV file.
  5. Click Export Report to save a PDF report with full details.

Command Line Interface (CLI)

Analyze a single file:

# Analyze a Python file
python -m py_pip_man analyze path/to/script.py

# Analyze a requirements file
python -m py_pip_man analyze path/to/requirements.txt

# Save output as JSON
python -m py_pip_man analyze path/to/script.py --output result.json

# Save output as CSV
python -m py_pip_man analyze path/to/script.py --output result.csv

# Show the dependency graph in a matplotlib window
python -m py_pip_man analyze path/to/script.py --graph

Analyze a full project directory:

# Full project analysis
python -m py_pip_man check path/to/my_project/ --ignore .venv --ignore tests/

# Save results
python -m py_pip_man check path/to/my_project/ --output report.json

# Show graph summary
python -m py_pip_man check path/to/my_project/ --graph

The check command exits with code 1 if ghost, zombie, or missing dependencies are found. This makes it suitable for use in CI/CD pipelines.

Build and inspect the dependency graph:

# Summary only
python -m py_pip_man graph path/to/my_project/

# Show all nodes
python -m py_pip_man graph path/to/my_project/ --nodes

# Show all edges
python -m py_pip_man graph path/to/my_project/ --edges

# Open matplotlib visualization
python -m py_pip_man graph path/to/my_project/ --graph

Example output of check:

Checking project: /home/user/my_project

──────────────────────────────
  👻  Ghost Dependencies
──────────────────────────────
  (none)

──────────────────────────────
  🧟  Zombie Dependencies
──────────────────────────────
  • numpy
    at: src/utils.py:3

──────────────────────────────
  📦  Total Dependencies
──────────────────────────────
  • requests
  • numpy
  • pandas

──────────────────────────────
  🕰️  Status Dependencies
──────────────────────────────
  • requests
    Installed: 2.28.0 | Latest: 2.32.3 -> Status: ❌ outdated
  • numpy
    Installed: 1.24.0 | Latest: 1.24.0 -> Status: ✅ up to date

Interactive Menu (TUI)

Launch the arrow-key-navigable terminal menu:

python -m py_pip_man menu

Navigate with ↑ ↓, confirm with Enter, and go back with Escape.

Options available:

  • Import directory — analyze a full project
  • Import file — analyze a single file
  • Settings — configure ignored directories and default output format
  • Exit

Supported File Formats

File Parser Notes
requirements.txt requirements_parser.py Parses package names and version specifiers
pyproject.toml toml_parser.py Supports PEP 621 ([project]) and Poetry ([tool.poetry.dependencies])
uv.lock lock_parser.py Skips editable (project-self) entries
poetry.lock lock_parser.py Skips dev category packages

When analyzing a project directory, PyPipMan reads all supported files it finds. If multiple files are present, they are processed in priority order: pyproject.tomlrequirements.txtpoetry.lockuv.lock.


Output Formats

Format Flag / Function Description
Terminal Default Colored, sectioned output in the terminal
JSON --output result.json Full structured result as JSON
CSV --output result.csv Flat table with type, name, and metadata columns
PDF GUI → Export Report Formatted PDF report with logo, summary, and table

Testing

The test suite uses pytest and pytest-mock. Tests are organized into:

  • tests/ — unit tests for parsers, analyzers, and the API wrapper.
  • tests/acceptance/cli/ — acceptance tests mapped to user stories (US01–US08).

Run the full suite:

pytest tests/

Run a specific module:

pytest tests/test_outdated_analyzer.py -v

Run only acceptance tests:

pytest tests/acceptance/

Generate the acceptance metrics report:

python tests/acceptance/run_metrics.py

This regenerates tests/acceptance/acceptance_metrics_report.md with execution time and peak memory per user story.

Project Structure

py_pip_man/
├── __init__.py                         # Package metadata
├── __main__.py                         # python -m py_pip_man entry point
├── config.py                           # Global constants (ignored dirs, supported files)
├── utils.py                            # ZIP extraction and project root helpers
│
├── cli/
│   ├── base.py                         # Click command group and all CLI commands
│   ├── tui.py                          # Interactive terminal menu
│   └── utils.py                        # Output formatting and graph plotting helpers
│
├── core/
│   ├── api_wrapper.py                  # PyPI REST API client
│   │
│   ├── analyzers/
│   │   ├── coordinator.py              # Central orchestrator for all analysis
│   │   ├── import_analyzers/
│   │   │   ├── ghost_analyzer.py       # Ghost detection (import level)
│   │   │   └── zombie_analyzer.py      # Zombie detection (import level)
│   │   ├── usage_analyzers/
│   │   │   ├── ghost_analyzer.py       # Ghost detection (usage/file level)
│   │   │   └── zombie_analyzer.py      # Zombie detection (usage/file level)
│   │   └── package_analyzers/
│   │       └── outdated_analyzer.py    # PyPI version comparison
│   │
│   ├── output/
│   │   └── output_manager.py           # JSON and CSV export
│   │
│   └── parsers/
│       ├── dependencies/
│       │   ├── factory.py              # Filename → parser dispatch table
│       │   ├── requirements_parser.py  # requirements.txt parser
│       │   ├── toml_parser.py          # pyproject.toml parser
│       │   └── lock_parser.py          # uv.lock / poetry.lock parser
│       └── source_code/
│           ├── py_parser.py            # .py file AST parser
│           ├── program_structure.py    # AST → NetworkX graph bridge
│           ├── handlers.py             # AST node handlers and DISPATCH table
│           └── utils.py                # Token validation and AST helpers
│
└── gui/
    ├── dashboard.py                    # Tkinter entry point (start_gui)
    ├── components.py                   # Layout builders
    ├── constants.py                    # Theme constants (dark/light)
    ├── state.py                        # Centralized UI state dict
    ├── ttk_style.py                    # ttk widget styling
    ├── services.py                     # Result-to-rows data shaping
    ├── file_utils.py                   # Cross-platform file-open helpers
    ├── report_pdf.py                   # ReportLab PDF report generator
    ├── logo.png                        # Application logo
    └── actions/
        ├── analysis_actions.py         # File/project analysis triggers
        ├── view_actions.py             # Metrics, labels, table filling
        ├── chart_actions.py            # Matplotlib bar chart rendering
        └── export_actions.py           # CSV and PDF export dialogs

Collaborators

PyPipMan — Developed as part of the RP-III course (AL0337) at Universidade Federal do Pampa (Unipampa), 2026/1.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages