Find Python Dependencies: Understand What Your Project Really Needs

Introduction

In this chapter, you will learn how to find and audit Python dependencies in a project. Dependency visibility is crucial for reproducibility, security, debugging, and deployment reliability. Once you know how to discover dependency relationships, you can manage project risk much more confidently.

Prerequisites

  • Basic Python packaging knowledge (pip, requirements.txt, or pyproject.toml)
  • Basic command-line usage
  • Understanding of virtual environments

Why Dependency Discovery Matters

Dependency discovery helps you:

  • reproduce environments reliably
  • debug version conflicts
  • reduce unnecessary packages
  • identify security and maintenance risks

Without dependency clarity, projects often become fragile.

1) Check Installed Direct Dependencies

List installed packages:

bash
pip list

Export pinned dependencies:

bash
pip freeze > requirements.txt

This captures current environment state.

2) Identify Dependency Trees

Use tools like pipdeptree to inspect dependency relationships.

Install tool:

bash
pip install pipdeptree

Show full tree:

bash
pipdeptree

Show reverse dependencies:

bash
pipdeptree --reverse --packages requests

This helps answer: "Why is this package installed?"

3) Find Unused Direct Dependencies

Projects often keep outdated or unused packages.

A common approach:

  • inspect imports in source code
  • compare against declared dependencies
  • remove packages not used by code or tooling

You can use tools like pip-check-reqs (optional) to assist, then verify manually.

4) Check for Vulnerabilities and Outdated Packages

Security and maintenance checks are part of dependency management.

Outdated packages:

bash
pip list --outdated

Security check example tools:

  • pip-audit
  • safety (workflow-dependent)

Example:

bash
pip install pip-audit
pip-audit

Tip

Safe Upgrade Strategy

Upgrade in small batches, run tests after each batch, and avoid upgrading everything blindly.

5) Read Dependency Files Correctly

Common files:

  • requirements.txt: pinned runtime dependencies
  • requirements-dev.txt: tooling/test dependencies
  • pyproject.toml: modern project metadata and dependencies
  • lockfiles: exact resolution state

Understand which file is source-of-truth in your project.

6) Real Mini Example: Dependency Audit Workflow

Imagine a project with unknown dependency state.

Suggested audit steps:

  1. activate project environment
  2. run pip list and pip freeze
  3. inspect tree with pipdeptree
  4. identify outdated packages with pip list --outdated
  5. run vulnerability scan (pip-audit)
  6. remove unused direct dependencies
  7. run tests to verify behavior

This process is practical for both local maintenance and CI pipelines.

7) Keep Dependencies Clean Over Time

Recommended habits:

  • pin important versions
  • review dependency changes in PRs
  • avoid unnecessary "just in case" packages
  • schedule regular dependency health checks

Warning

Do not uninstall packages blindly from environment snapshots.
First confirm whether they are transitive dependencies or used by tools/tests.

Common Beginner Mistakes

Mistake 1: Treating pip freeze as Curated Dependency Design

pip freeze captures everything installed, including accidental packages.

Mistake 2: Ignoring Transitive Dependencies

Many runtime risks come from indirect packages, not just direct ones.

Mistake 3: Upgrading Without Tests

Version upgrades can introduce breaking changes.

Surprise Practice Challenge

Run a dependency health check for one project:

  1. export current dependencies
  2. inspect dependency tree
  3. list outdated packages
  4. scan vulnerabilities
  5. propose a safe upgrade plan with priorities (critical -> optional)

If you finish this, you can perform practical dependency governance like an engineering team member.

FAQ

What is the difference between direct and transitive dependency?

Direct dependencies are declared by your project; transitive dependencies are required by those direct packages.

Should I pin every package version?

For applications, pinning is usually recommended for reproducibility. For libraries, strategy can vary.

Why does removing one package break others?

Because other packages may depend on it indirectly.

Can dependency discovery be automated in CI?

Yes. You can run tree, outdated, and vulnerability checks as pipeline steps.