Skip to main content

PyDependencyCheck

Dependency intelligence and supply-chain security for Python projects. A Rust core (dependency parsing, graph algorithms, OSV vulnerability scanning) wrapped in a Python CLI: scan dependencies, see who introduced them and why, find unused packages, check license compliance, generate signed SBOMs, and gate CI builds on a real health score.

PyPI Python 3.8+ License: Proprietary CI

What it does

  • Scan: auto-detect and parse requirements.txt, pyproject.toml (PEP 621 and Poetry), and constraints.txt, handling every PEP 508 version operator and extras.
  • Why / trace: git-blame-based provenance (who added a dependency, in which commit) and full chronological history across the project's git log.
  • Health: a real, computed 0-100 score combining live OSV.dev vulnerability data, PyPI release staleness, AST-detected dead dependencies, and dependency-graph complexity.
  • SBOM export: CycloneDX 1.4 and SPDX 2.3 JSON, with optional RSA-SHA256 signing and verification.
  • License compliance: fetches real PyPI license metadata, classifies permissive/copyleft/restricted, and checks compatibility against your project's own license.
  • CI gating: gate computes the same health score and exits non-zero on failure, with GitHub Actions ::error/::warning/::notice annotations when run inside a GitHub Actions job.
  • Drift & history: SQLite-backed snapshots so you can diff what changed since a baseline.
  • OpenTelemetry: optional tracing/metrics via --otel, defaulting to a console exporter (no collector required) or OTLP/Jaeger/Prometheus if configured.

Installation

pip install pydependencycheck

For SBOM signing (needs cryptography) or OpenTelemetry export:

pip install "pydependencycheck[sbom,otel]"

Requires Python 3.8+. Prebuilt wheels are published for Linux, macOS (Intel/Apple Silicon), and Windows; see .github/INSTALL.md if you need to build from source.

Quick start

# Scan the current project (--path defaults to ".")
pydependencycheck scan

# Why is this package installed, and who added it?
pydependencycheck why requests

# Full git history for a dependency (added/upgraded/downgraded over time)
pydependencycheck trace requests

# Real health score: live vulnerabilities, staleness, dead deps, complexity
pydependencycheck health

# License compliance report, checked against your project's license
pydependencycheck licenses --project-license MIT

# Export a signed CycloneDX SBOM
pydependencycheck export --format cyclonedx --output sbom.json

# Gate a CI build: exits non-zero if health/vulnerabilities/dead-deps fail thresholds
pydependencycheck gate --min-health 50

Commands

Command What it does
scan Parse dependency files, report direct/transitive counts (table, JSON, HTML, or Markdown)
list Table of all detected dependencies
why PACKAGE Git-blame provenance: who added it, in which commit
trace PACKAGE Current status plus full git history for that dependency
health Computed health score (vulnerabilities, staleness, dead deps, complexity)
licenses License classification + compatibility check per dependency
export SBOM export (CycloneDX or SPDX), optionally signed
gate CI gate: real exit code based on health/vulnerability/dead-dep thresholds
remediate Patch vulnerable dependencies to their OSV fix_version, optionally as a real git branch/commit + GitHub PR
snapshot Save or inspect a dependency snapshot
history Timeline of saved snapshots
drift Diff the current scan against a saved baseline

Run pydependencycheck COMMAND --help for the full option list on any command (most support --path, and scan/export/licenses/health/gate support --offline/--path variants where relevant).

Health scoring

health (and gate) combine four real, independently-computed factors:

pydependencycheck health
Dependency Health Score: 87/100 (Excellent)
               Health Score Breakdown
┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
┃ Factor          ┃ Score   ┃ Status               ┃
┡━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩
│ Overall Health  │ 87/100  │ ████████░░ Excellent │
│ Vulnerabilities │ 100/100 │ ██████████ Excellent │
│ Maintenance     │ 100/100 │ ██████████ Excellent │
│ Quality         │ 40/100  │ ████░░░░░░ Poor      │
│ Complexity      │ 95/100  │ █████████░ Excellent │
└─────────────────┴─────────┴──────────────────────┘

Vulnerabilities and staleness require live network calls (OSV.dev and PyPI's JSON API); pass --offline to skip them and get a deterministic score from local data only (dead-dependency detection and graph complexity).

Automated remediation

remediate turns an OSV.dev vulnerability finding into an actual patch -- not just a report:

# Dry run: prints a unified diff for every affected file, changes nothing
pydependencycheck remediate

# Write the fixed versions to requirements.txt/pyproject.toml for real
pydependencycheck remediate --apply

# Create a real git branch + commit for the fix, push it, and open a GitHub
# PR via the `gh` CLI (if installed and authenticated)
pydependencycheck remediate --pr
2 fixable vulnerable package(s):
  requests: 2.25.0 -> 2.33.0  [GHSA-9hjg-9r4m-mvj7, PYSEC-2023-74, ...]
  flask: 2.0.0 -> 2.3.2  [GHSA-m2qf-hxjv-5gpq]

--- requirements.txt ---
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,2 @@
-requests==2.25.0
-flask==2.0.0
+requests==2.33.0
+flask==2.3.2

Only exact == pins in requirements.txt/constraints.txt/pyproject.toml are patched (a range like >=2.0,<3.0 doesn't name one concrete version to bump). With --pr but no gh CLI available, the branch is still created and pushed for real -- open the PR manually.

SBOM export and signing

# Generate keys once
python3 -c "from pydependencycheck.sbom import SBOMSigner; SBOMSigner().generate_keys('signing-key.pem')"

# Export a signed SBOM
pydependencycheck export --format cyclonedx --sign --key signing-key.pem --output sbom.json

The SBOM carries a SHA-256 integrity hash and (when --sign is used) an RSA-SHA256 signature over the document, verifiable with SBOMSigner.verify_sbom().

CI gating with GitHub Actions

name: Dependency Check
on: [push, pull_request]

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v4
        with:
          python-version: '3.11'

      - run: pip install pydependencycheck
      - run: pydependencycheck scan --save-snapshot
      - run: pydependencycheck gate --min-health 50
      - run: pydependencycheck export --format cyclonedx --output sbom.json

      - uses: actions/upload-artifact@v3
        with:
          name: sbom
          path: sbom.json

gate prints ::error/::warning/::notice GitHub Actions annotations automatically when GITHUB_ACTIONS is set, and always sets the process exit code (1 on failure), so it works as a real CI gate on any CI system, not just GitHub Actions.

OpenTelemetry

pydependencycheck health --otel

Defaults to a console exporter backed by the real OpenTelemetry SDK (ConsoleSpanExporter/ConsoleMetricExporter) -- genuine spans and metrics printed to stdout, no collector required. Pass --otel-exporter otlp|jaeger|prometheus to ship to real infrastructure if you have it configured; if the corresponding exporter package isn't installed, it falls back to console rather than silently doing nothing.

Architecture

Rust workspace (crates/) does the heavy lifting, exposed to Python via PyO3:

  • pydep-parser -- PEP 508 requirements/pyproject.toml parsing (extras, markers, every version operator)
  • pydep-graph -- dependency graph construction, cycle detection, topological sort (petgraph)
  • pydep-ast -- import extraction and dead-dependency detection
  • pydep-security -- OSV.dev vulnerability queries and risk scoring
  • pydep-py -- PyO3 bindings tying it together as pydependencycheck._pydependencycheck

The Python package (python/pydependencycheck/) is the CLI, plus SBOM generation, license analysis, git integration, SQLite-backed snapshot storage, and OpenTelemetry instrumentation.

Testing: 45 Rust unit tests (cargo test --workspace) across all four crates, plus 126 Python tests (pytest tests/) covering the CLI end-to-end, the XSS fix, SBOM signing/verification, license classification, health scoring, and the SQLite storage layer.

Requirements

Python 3.8+ on Linux (x86_64), macOS (Intel/ARM), or Windows (x86_64).

License

Proprietary License - free to use with explicit attribution. See LICENSE for details.

When using PyDependencyCheck, include this attribution:

Powered by PyDependencyCheck (https://github.com/Mullassery/PyDependencyCheck)

Known issues

  • setup.py/setup.cfg-only projects (no requirements.txt or pyproject.toml) are not parsed yet — AST parsing of setup.py and INI parsing of setup.cfg are unimplemented (crates/pydep-parser/src/setup.rs, python/pydependencycheck/scanner.py), and are consequently also not covered by remediate.
  • The health-score "Quality" factor is a single metric today; aggregating multiple quality signals is tracked as future work (python/pydependencycheck/scanner.py).
  • Fixed in this pass: check_vulnerabilities() was passing the full PEP 508 specifier (e.g. "==2.25.0") to OSV.dev instead of the bare version -- Version::parse("==2.25.0") fails as invalid semver, so OSV's range matching silently fell back to exact-string matching against nothing, meaning health/gate reported zero vulnerabilities for essentially every exactly-pinned dependency. Also fixed: fix_version could come back as a raw git commit hash instead of a PyPI version when an advisory's affected[].ranges listed a GIT-type range before its ECOSYSTEM range (both in crates/pydep-security/src/osv.rs; see fix_version_ignores_git_range_and_uses_ecosystem_range for the regression test).
  • No open GitHub issues at the time of this writing.

Support

Release files for pydependencycheck 1.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pydependencycheck 1.4.0
File Size Uploaded
pydependencycheck-1.4.0.tar.gz 117.9 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for pydependencycheck 1.4.0
File
pydependencycheck-1.4.0-cp311-cp311-win_amd64.whl CPython 3.11 CPython 3.11 Windows x86-64 Details
pydependencycheck-1.4.0-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details
pydependencycheck-1.4.0-cp311-cp311-macosx_10_12_x86_64.whl CPython 3.11 CPython 3.11 macOS 10.12+ x86-64 Details
pydependencycheck-1.4.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.8 abi3 Linux glibc 2.17+ x86-64 Details
pydependencycheck-1.4.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.8 abi3 Linux glibc 2.17+ ARM64 Details
pydependencycheck-1.4.0-cp38-abi3-macosx_11_0_arm64.whl CPython 3.8 abi3 macOS 11.0+ ARM64 Details
pydependencycheck-1.4.0-cp38-abi3-macosx_10_12_x86_64.whl CPython 3.8 abi3 macOS 10.12+ x86-64 Details

Total release size: 11.9 MB

Release files / pydependencycheck-1.4.0.tar.gz

Download URL pydependencycheck-1.4.0.tar.gz
Size 117.9 kB
Tags Source
SHA-256 checksum
How to use checksums
49452f6fad009a7939ba30ebe1d7fc126fc22efbc777c549257be5c3b5a55c33
BLAKE2b-256 checksum
How to use checksums
31a9a3fa8875fe4baa0210af94581f8d0f453622c621b0941dc84f011aa61be4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / pydependencycheck-1.4.0-cp311-cp311-win_amd64.whl

Download URL pydependencycheck-1.4.0-cp311-cp311-win_amd64.whl
Size 1.4 MB
Tags CPython 3.11 Windows x86-64
SHA-256 checksum
How to use checksums
d26741e98473894c97c5cc21db4df0b4b3c0cc3b544b5cf8b89d5dbff7828ec3
BLAKE2b-256 checksum
How to use checksums
d538c7f3ebd9099e3cf8f3f35481c37c34215925ec016ff091bb00d14fe78727
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / pydependencycheck-1.4.0-cp311-cp311-macosx_11_0_arm64.whl

Download URL pydependencycheck-1.4.0-cp311-cp311-macosx_11_0_arm64.whl
Size 1.5 MB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
30bd89dd56419ba869bd8a88539f6429404ce5399b5b200614ddba93767745a3
BLAKE2b-256 checksum
How to use checksums
3d258a7974a218030fdcab36941b09470566c522b26c9ba6a8fcef45bfd2a8bd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / pydependencycheck-1.4.0-cp311-cp311-macosx_10_12_x86_64.whl

Download URL pydependencycheck-1.4.0-cp311-cp311-macosx_10_12_x86_64.whl
Size 1.5 MB
Tags CPython 3.11 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
6c023a9d0d52a517744cda63622ea83d43946ddc87a9ec963a28ec8890ba72a9
BLAKE2b-256 checksum
How to use checksums
e6a2d3ad46428b78095a62c19a927ed07f26fb885247d3d4340aed05a4323e97
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / pydependencycheck-1.4.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL pydependencycheck-1.4.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 2.2 MB
Tags CPython 3.8 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
daec9b9b90e4dbbb4c4a09a8140aca56dc8775b2b41ee694a1bf86a203c6eb8d
BLAKE2b-256 checksum
How to use checksums
cb973b04b84c3bd4503e97718e67b1a5ecaaabdb79feaa4970207376242d14ad
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / pydependencycheck-1.4.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL pydependencycheck-1.4.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 2.1 MB
Tags CPython 3.8 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
147a787ffc7dc17c5393242b32f4a2ca9f17564b5300bbfb33ca9e3b3237955b
BLAKE2b-256 checksum
How to use checksums
60c18b50a81415402400e0f41125384a4c4ab3a007135ac082bd5c0cd858de5e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / pydependencycheck-1.4.0-cp38-abi3-macosx_11_0_arm64.whl

Download URL pydependencycheck-1.4.0-cp38-abi3-macosx_11_0_arm64.whl
Size 1.5 MB
Tags CPython 3.8 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
1b432ccb5ab277871c9bf5d26de8e0cff758714d900d660a6b20840eed69a350
BLAKE2b-256 checksum
How to use checksums
98cd2ccad3dd4027d8a52b14f1e5129c5177c2d4e76d55de15925610af9054da
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / pydependencycheck-1.4.0-cp38-abi3-macosx_10_12_x86_64.whl

Download URL pydependencycheck-1.4.0-cp38-abi3-macosx_10_12_x86_64.whl
Size 1.5 MB
Tags CPython 3.8 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
d0cfd762d3079283763626f64ca3338496b40a8750e3d0ff14a89b46b22e8437
BLAKE2b-256 checksum
How to use checksums
43aaa3e0a0c78a0aa7fd0b01d832cd648d944194e2f8eb52d9d0086ab57cf334
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release history Release notifications | RSS feed

This release

1.4.0 This release

8 release files

1.3.0

2 release files

1.2.0

1 release file

1.1.0

1 release file

1.0.0

1 release file

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page