cheat sheet

pip

Complete pip reference covering installation, package management, requirements files, private registries, caching, offline installs, and reproducible builds.

pip

What it is

pip is the standard package installer for Python. It has shipped bundled with Python since version 3.4 and installs packages from PyPI (the Python Package Index) by default. pip understands version specifiers (==, >=, ~=, !=), extras (package[extra]), editable installs (-e), and requirements files, making it the lowest-common-denominator tool that every Python environment supports.

pip resolves dependencies, downloads wheels or source distributions, builds them if necessary, and places the results on sys.path. For reproducible, fast installs on modern projects, see uv or poetry.

Install / upgrade pip

pip is included with Python 3.4+. To ensure you have the latest version:

bash
# Upgrade pip inside a virtual environment (recommended)
python -m pip install --upgrade pip

# Or use the ensurepip bootstrapper (useful when pip is missing)
python -m ensurepip --upgrade

Output:

text
Requirement already satisfied: pip in ./.venv/lib/python3.12/site-packages (24.0)
Collecting pip
  Using cached pip-24.1-py3-none-any.whl (1.8 MB)
Installing collected packages: pip
  Attempting uninstall: pip
    Found existing installation: pip 24.0
    Uninstalling pip-24.0:
      Successfully uninstalled pip-24.0
Successfully installed pip-24.1

Always upgrade pip inside an activated virtual environment. Running sudo pip install or upgrading the system pip can break OS-level Python tooling on Linux and macOS.

Install packages

Single package

bash
pip install requests

Output:

text
Collecting requests
  Downloading requests-2.32.3-py3-none-any.whl (64 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 64.9/64.9 kB 3.2 MB/s eta 0:00:00
Collecting charset-normalizer<4,>=2
  Downloading charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.whl (140 kB)
Collecting idna<4,>=2.5
  Downloading idna-3.7-py3-none-any.whl (66 kB)
Collecting certifi>=2017.4.17
  Downloading certifi-2024.2.2-py3-none-any.whl (163 kB)
Collecting urllib3<3,>=1.21.1
  Downloading urllib3-2.2.1-py3-none-any.whl (121 kB)
Installing collected packages: certifi, idna, charset-normalizer, urllib3, requests
Successfully installed certifi-2024.2.2 charset-normalizer-3.3.2 idna-3.7 requests-2.32.3 urllib3-2.2.1

Multiple packages

bash
pip install requests pandas numpy

Output: (none — exits 0 on success)

From a requirements file

bash
pip install -r requirements.txt

Output: (none — exits 0 on success)

Extras

Some packages expose optional dependency groups called extras:

bash
pip install "uvicorn[standard]"
pip install "fastapi[all]"
pip install "requests[security,socks]"

Output: (none — exits 0 on success)

Editable install (development mode)

An editable install links the package source directory directly into the environment so changes take effect without reinstalling:

bash
pip install -e .
pip install -e ./path/to/my-package

Output:

text
Obtaining file:///home/user/myproject
  Installing build dependencies ... done
  Checking if build backend supports build_editable ... done
  Getting requirements to build editable ... done
  Installing backend dependencies ... done
  Preparing editable metadata (pyproject.toml) ... done
Building wheels for collected packages: myproject
  Building editable for myproject (pyproject.toml) ... done
  Created wheel for myproject: filename=myproject-0.1.0-py3-none-any.whl
Successfully installed myproject-0.1.0

User install (no virtual environment)

bash
pip install --user requests

Output: (none — exits 0 on success)

This installs to ~/.local/lib/pythonX.Y/site-packages instead of the system directory. Prefer using a virtual environment instead.

Version specifiers

bash
pip install "requests==2.32.3"    # exact version
pip install "requests>=2.28"      # at least
pip install "requests~=2.28"      # compatible release (>=2.28, <3)
pip install "requests!=2.30.0"    # exclude a broken release
pip install "requests>=2.28,<3"   # range

Output: (none — exits 0 on success)

Uninstall

bash
pip uninstall requests
pip uninstall requests pandas numpy   # multiple at once
pip uninstall -r requirements.txt     # everything listed in a file
pip uninstall -y requests             # skip confirmation prompt

Output:

text
Found existing installation: requests 2.32.3
Uninstalling requests-2.32.3:
  Would remove:
    /home/user/.venv/lib/python3.12/site-packages/requests-2.32.3.dist-info/*
    /home/user/.venv/lib/python3.12/site-packages/requests/*
Proceed (Y/n)? Y
  Successfully uninstalled requests-2.32.3

pip uninstall removes only the named package, not its dependencies. Use pip-autoremove (a separate package) if you need orphan dependency removal.

List installed packages

bash
pip list

Output:

text
Package            Version
------------------ ---------
certifi            2024.2.2
charset-normalizer 3.3.2
idna               3.7
pip                24.1
requests           2.32.3
setuptools         70.0.0
urllib3            2.2.1
bash
pip list --outdated

Output:

text
Package    Version Latest Type
---------- ------- ------ -----
requests   2.28.0  2.32.3 wheel
urllib3    1.26.18 2.2.1  wheel
bash
pip list --format=json        # machine-readable output
pip list --not-required       # packages not depended on by anything else

Output: (none — exits 0 on success)

Show package info

bash
pip show requests

Output:

text
Name: requests
Version: 2.32.3
Summary: Python HTTP for Humans.
Home-page: https://requests.readthedocs.io
Author: Alice Dev
Author-email: alice@example.com
License: Apache 2.0
Location: /home/user/.venv/lib/python3.12/site-packages
Requires: certifi, charset-normalizer, idna, urllib3
Required-by: httpx
bash
pip show --verbose requests   # includes classifiers and more metadata
pip show requests urllib3     # show multiple packages at once

Output: (none — exits 0 on success)

Freeze / requirements.txt

pip freeze writes the exact installed versions to stdout, suitable for pinning a working environment:

bash
pip freeze > requirements.txt

Output (requirements.txt):

text
certifi==2024.2.2
charset-normalizer==3.3.2
idna==3.7
requests==2.32.3
urllib3==2.2.1

Restore that exact environment elsewhere:

bash
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Output: (none — exits 0 on success)

pip freeze includes every package, even transitive dependencies. For a curated requirements file that only lists your direct dependencies, use pip-tools (pip-compile) or uv pip compile. See Reproducible builds below.

Check for conflicts

bash
pip check

Output (no problems):

text
No broken requirements found.

Output (conflict detected):

text
sphinx 7.1.2 has requirement docutils<0.21,>=0.18.1, but you have docutils 0.21.

Run pip check in CI after installing dependencies to catch version conflicts that pip's resolver sometimes misses with older lockfile approaches.

requirements.txt vs constraints.txt

FilePurposeCommand
requirements.txtLists packages to install (with optional version pins)pip install -r requirements.txt
constraints.txtLimits versions of any package, including transitive deps, without installing thempip install -c constraints.txt -r requirements.txt

A constraints file lets you say "if anything installs urllib3, it must be <2" without adding urllib3 as an explicit dependency:

text
# constraints.txt
urllib3<2
certifi>=2023.1
bash
pip install -c constraints.txt -r requirements.txt

Output: (none — exits 0 on success)

Index URLs and private registries

Change the package index

bash
# Use a different index entirely
pip install requests --index-url https://pypi.mycompany.com/simple/

# Add a secondary index (PyPI is still tried first)
pip install requests --extra-index-url https://pypi.mycompany.com/simple/

Output: (none — exits 0 on success)

Persistent configuration

Linux / macOS~/.pip/pip.conf or ~/.config/pip/pip.conf:

ini
[global]
index-url = https://pypi.mycompany.com/simple/
extra-index-url = https://pypi.org/simple/
trusted-host = pypi.mycompany.com

Windows%APPDATA%\pip\pip.ini:

ini
[global]
index-url = https://pypi.mycompany.com/simple/
trusted-host = pypi.mycompany.com

Per-projectpip.conf in the project root (add to .gitignore if it contains credentials):

bash
pip config set global.index-url https://pypi.mycompany.com/simple/
pip config list   # show current effective config

Output: (none — exits 0 on success)

Never hardcode credentials in pip.conf. Use the NETRC file (~/.netrc) or environment variables (PIP_INDEX_URL, PIP_EXTRA_INDEX_URL) injected from a secrets manager in CI.

Cache

pip caches downloaded wheels to avoid re-downloading on future installs.

bash
pip cache dir          # show the cache directory path
pip cache list         # list cached wheels
pip cache info         # summary of cache size and location
pip cache purge        # delete all cached files
pip cache remove requests   # remove cache entries for a specific package

Output:

text
$ pip cache dir
/home/user/.cache/pip

$ pip cache info
Location: /home/user/.cache/pip
Size: 1.2 GB
Number of packages: 347

$ pip cache purge
Files removed: 347

Disable the cache entirely (useful in Docker layers where caching wastes image space):

bash
pip install --no-cache-dir -r requirements.txt

Output: (none — exits 0 on success)

Reproducible builds

Hash-checking mode

Generate hashes for your pinned requirements:

bash
pip hash dist/requests-2.32.3-py3-none-any.whl

Output:

text
requests-2.32.3-py3-none-any.whl:
--hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfed9b0832567fce85db745

In a requirements file, add the hashes:

text
requests==2.32.3 \
    --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfed9b0832567fce85db745 \
    --hash=sha256:58cd2187423d1a4600d4ae17b3ab5db0c7cf88ae81dbe6c3e7b5d65813b52d0c

Install with hash verification:

bash
pip install --require-hashes -r requirements.txt

Output: (none — exits 0 on success)

pip-compile (pip-tools)

pip-compile takes a high-level requirements.in and produces a fully pinned requirements.txt with hashes:

bash
pip install pip-tools

# requirements.in
requests>=2.28
fastapi[all]

Output: (none — exits 0 on success)

bash
pip-compile --generate-hashes requirements.in

Output:

text
#
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
#    pip-compile --generate-hashes requirements.in
#
certifi==2024.2.2 \
    --hash=sha256:ab06db6... \
    ...
requests==2.32.3 \
    --hash=sha256:70761cf... \
    ...

Offline installs

Download wheels for later

bash
# Download a package and all its dependencies into a local directory
pip download requests -d ./wheels

# Download for a specific platform (e.g., build on Linux, deploy on Linux)
pip download requests --platform manylinux2014_x86_64 --only-binary=:all: -d ./wheels

Output:

text
Collecting requests
  Downloading requests-2.32.3-py3-none-any.whl (64 kB)
Collecting certifi>=2017.4.17
  Downloading certifi-2024.2.2-py3-none-any.whl (163 kB)
...
Saved ./wheels/requests-2.32.3-py3-none-any.whl
Saved ./wheels/certifi-2024.2.2-py3-none-any.whl
Saved ./wheels/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.whl
Saved ./wheels/idna-3.7-py3-none-any.whl
Saved ./wheels/urllib3-2.2.1-py3-none-any.whl

Install from the local directory (no network)

bash
pip install --no-index --find-links ./wheels requests
pip install --no-index --find-links ./wheels -r requirements.txt

Output:

text
Looking in links: ./wheels
Collecting requests
  File was already downloaded /home/user/wheels/requests-2.32.3-py3-none-any.whl
Installing collected packages: certifi, idna, charset-normalizer, urllib3, requests
Successfully installed certifi-2024.2.2 charset-normalizer-3.3.2 idna-3.7 requests-2.32.3 urllib3-2.2.1

This pattern is common in air-gapped environments, Docker multi-stage builds, and corporate networks that block PyPI.

Comparison: pip vs uv vs poetry

Featurepipuvpoetry
Ships with Python❌ (separate install)❌ (separate install)
Install speedSlowFast (Rust, 10–100×)Slow
Dependency resolverBasicFull SAT solverFull SAT solver
Lockfile❌ (use pip-tools)✅ (uv.lock)✅ (poetry.lock)
Virtual env management❌ (use venv)
Python version management
pyproject.toml supportPartial
Private registry support
Hash-checking mode
Offline installsPartial
Drop-in CLI compatibility✅ (uv pip …)

When to use pip: legacy projects, environments where you can't install extra tools, scripting contexts where you need zero dependencies.

When to use uv: new projects, CI pipelines where speed matters, anywhere you'd use pip + pip-tools + virtualenv together.

When to use poetry: projects that prefer a pyproject.toml-first workflow and want a single tool for building, publishing, and dependency management.

Common errors

ErrorCauseFix
ERROR: Could not find a version that satisfies the requirement <pkg>Package name typo, wrong index, or no wheel for your Python/platformCheck the name on PyPI; add --extra-index-url; try --pre for pre-releases
ERROR: pip's dependency resolver does not currently take into account all the packages that are installedConflict between existing packages and the new installCreate a fresh virtual environment; use uv for better resolution
Permission denied when installingInstalling into system Python without sudo, or inside a read-only venvActivate your virtual environment first; never use sudo pip
No module named pippip was removed or never installedRun python -m ensurepip --upgrade
SSL: CERTIFICATE_VERIFY_FAILEDMissing or outdated CA certificatesUpgrade certifi; use --trusted-host for private registries with self-signed certs
ERROR: Failed building wheel for <pkg>Missing C compiler or system headers needed to build a source distributionInstall build tools (build-essential on Debian/Ubuntu, Xcode CLT on macOS); prefer wheels with --only-binary=:all:
WARNING: The scripts <cmd> are installed in '~/.local/bin' which is not on PATH--user install destination not on PATHAdd ~/.local/bin to your PATH in ~/.bashrc or ~/.zshrc
pkg_resources.DistributionNotFoundPackage installed in a different environment than the one running PythonConfirm the correct venv is active; run pip show <pkg> to check location