Python - pip Install and Package Management

• pip is Python's package installer that manages dependencies from PyPI and other sources, with virtual environments being essential for isolating project dependencies and avoiding conflicts

Key Insights

• pip is Python’s package installer that manages dependencies from PyPI and other sources, with virtual environments being essential for isolating project dependencies and avoiding conflicts • Understanding pip’s installation modes (user vs system), version constraints, and requirements files enables reproducible builds and consistent development environments across teams • Advanced pip features like editable installs, constraint files, and dependency resolution strategies solve real-world problems in complex Python projects

Installing pip

Modern Python distributions (3.4+) include pip by default. Verify your installation:

python --version
pip --version

If pip is missing, install it using the official bootstrap script:

curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py

For system-wide upgrades:

python -m pip install --upgrade pip

Always use python -m pip instead of calling pip directly. This ensures you’re using the pip associated with your specific Python interpreter, preventing version mismatches.

Basic Package Installation

Install packages from PyPI:

pip install requests
pip install numpy==1.24.3
pip install "django>=4.0,<5.0"

Install multiple packages:

pip install requests pandas matplotlib

Install from a Git repository:

pip install git+https://github.com/user/repo.git
pip install git+https://github.com/user/repo.git@branch_name
pip install git+https://github.com/user/repo.git@v1.0.0

Install from a local directory:

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

User vs System Installation

System-wide installation (requires sudo/admin):

sudo pip install package_name

User installation (recommended for non-virtual environments):

pip install --user package_name

User installs go to ~/.local/ on Unix or %APPDATA%\Python on Windows. This avoids permission issues and system package conflicts.

Check installation location:

pip show package_name

Virtual Environments

Virtual environments are non-negotiable for Python development. They isolate dependencies per project.

Create and activate a virtual environment:

# Create
python -m venv myproject_env

# Activate on Linux/Mac
source myproject_env/bin/activate

# Activate on Windows
myproject_env\Scripts\activate

# Deactivate
deactivate

Your prompt changes to show the active environment. Now pip installs only affect this environment:

(myproject_env) $ pip install flask
(myproject_env) $ pip list

Requirements Files

Requirements files define project dependencies for reproducible installations.

Basic requirements.txt:

requests==2.31.0
flask>=2.3.0,<3.0.0
pandas~=2.0.0
pytest

Version specifiers:

  • ==2.31.0 - exact version
  • >=2.3.0,<3.0.0 - version range
  • ~=2.0.0 - compatible release (>=2.0.0, <2.1.0)
  • No specifier - latest version

Install from requirements file:

pip install -r requirements.txt

Generate requirements from current environment:

pip freeze > requirements.txt

The freeze output includes exact versions of all installed packages and their dependencies. This ensures identical environments across deployments.

Constraint Files

Constraint files limit package versions without directly installing them. Useful for managing transitive dependencies.

constraints.txt:

urllib3<2.0.0
certifi>=2023.0.0

Install with constraints:

pip install -c constraints.txt requests

This installs requests but ensures its dependencies respect the constraints.

Development Dependencies

Separate production and development dependencies:

requirements.txt:

flask==2.3.0
sqlalchemy==2.0.0

requirements-dev.txt:

-r requirements.txt
pytest==7.4.0
black==23.7.0
mypy==1.4.0

Install development environment:

pip install -r requirements-dev.txt

Editable Installs

Install packages in development mode, where code changes reflect immediately without reinstallation:

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

This creates a link to your source code. Essential when developing libraries or working with local packages.

Project structure:

mypackage/
├── setup.py
├── mypackage/
│   ├── __init__.py
│   └── module.py

setup.py:

from setuptools import setup, find_packages

setup(
    name="mypackage",
    version="0.1.0",
    packages=find_packages(),
    install_requires=[
        "requests>=2.31.0",
    ],
)

Install in editable mode:

pip install -e .

Now modify mypackage/module.py and changes are immediately available.

Uninstalling and Upgrading

Uninstall packages:

pip uninstall package_name
pip uninstall -r requirements.txt

Upgrade packages:

pip install --upgrade package_name
pip install -U package_name

Upgrade all packages (use cautiously):

pip list --outdated
pip install --upgrade package1 package2 package3

Listing and Inspecting Packages

List installed packages:

pip list
pip list --outdated
pip list --format=json

Show package details:

pip show requests

Output includes version, location, dependencies, and required-by information.

Check dependencies:

pip show requests | grep Requires

Dependency Resolution

pip 20.3+ uses a new dependency resolver that backtracks to find compatible versions.

Force specific resolution strategy:

pip install --use-deprecated=legacy-resolver package_name

See dependency tree with pipdeptree:

pip install pipdeptree
pipdeptree

Output:

flask==2.3.0
├── click>=8.1.3
├── itsdangerous>=2.1.2
├── jinja2>=3.1.2
│   └── markupsafe>=2.0
└── werkzeug>=2.3.0

Handling Conflicts

When dependencies conflict, pip reports resolution errors. Strategies:

  1. Pin compatible versions explicitly:
package-a==1.0.0
package-b==2.0.0
shared-dependency==1.5.0
  1. Use constraint files to limit transitive dependencies

  2. Check compatibility with pip check:

pip check
  1. Isolate incompatible packages in separate virtual environments

Configuration Files

pip reads configuration from multiple locations:

  • Global: /etc/pip.conf (Unix) or %APPDATA%\pip\pip.ini (Windows)
  • User: ~/.config/pip/pip.conf (Unix) or %APPDATA%\pip\pip.ini (Windows)
  • Virtual environment: $VIRTUAL_ENV/pip.conf

Example pip.conf:

[global]
timeout = 60
index-url = https://pypi.org/simple

[install]
trusted-host = pypi.org
               pypi.python.org

Override with environment variables:

export PIP_INDEX_URL=https://custom-pypi.org/simple
pip install package_name

Private Package Indexes

Configure private PyPI servers:

pip install --index-url https://pypi.company.com/simple package_name

Use extra indexes alongside PyPI:

pip install --extra-index-url https://pypi.company.com/simple package_name

In requirements.txt:

--index-url https://pypi.company.com/simple
--extra-index-url https://pypi.org/simple

company-package==1.0.0
requests==2.31.0

Security and Best Practices

  1. Always use virtual environments - Never install packages system-wide for projects
  2. Pin exact versions in production requirements files
  3. Audit dependencies for vulnerabilities:
pip install safety
safety check
  1. Use hash-checking mode for security-critical deployments:
pip freeze --all > requirements.txt
pip hash requests==2.31.0 >> requirements.txt
pip install --require-hashes -r requirements.txt
  1. Keep pip updated - New versions include security fixes and dependency resolution improvements

  2. Review dependencies before installing - Check package popularity, maintenance status, and license compatibility

Managing Python packages effectively requires understanding pip’s features beyond basic installation. Virtual environments prevent conflicts, requirements files ensure reproducibility, and proper dependency management keeps projects maintainable as they scale.

Liked this? There's more.

Every week: one practical technique, explained simply, with code you can use immediately.