Every Python project has its own set of dependencies. Virtual environments prevent version conflicts between projects and make your setup reproducible for teammates and production.

Why Virtual Environments?

Without isolation, installing django==4.2 for one project can break another that requires django==3.2. A virtual environment gives each project its own Python interpreter and site-packages directory.

Creating a Virtual Environment with venv

venv is built into Python 3.3+ and is the recommended tool.

  # Create a virtual environment in a folder called .venv
python3 -m venv .venv

# Activate (macOS / Linux)
source .venv/bin/activate

# Activate (Windows)
.venv\Scripts\activate

# Deactivate when done
deactivate
  

Once activated, python and pip point to the virtual environment:

  which python   # → /path/to/project/.venv/bin/python
pip install requests
  

Managing Dependencies with pip

Installing Packages

  pip install requests          # latest version
pip install "django>=4.2,<5"  # version constraint
pip install -r requirements.txt  # from a file
  

Freezing Dependencies

Capture exact versions so others can reproduce your environment:

  pip freeze > requirements.txt
  

A typical requirements.txt:

  requests==2.31.0
django==4.2.7
pytest==7.4.3
  

Installing from requirements.txt

  pip install -r requirements.txt
  

Using Poetry (Modern Alternative)

Poetry combines dependency resolution, virtual environment management, and packaging in one tool.

  # Install Poetry
curl -sSL https://install.python-poetry.org | python3 -

# Create a new project
poetry new myproject
cd myproject

# Add a dependency
poetry add fastapi

# Add a dev dependency
poetry add --group dev pytest

# Run commands inside the venv
poetry run python main.py
poetry run pytest
  

Poetry stores dependencies in pyproject.toml:

  [tool.poetry.dependencies]
python = "^3.11"
fastapi = "^0.104.0"

[tool.poetry.group.dev.dependencies]
pytest = "^7.4.0"
  

Best Practices

  1. Always use a virtual environment — never install project packages globally.
  2. Commit lock filesrequirements.txt or poetry.lock ensures reproducible builds.
  3. Pin major versions — use package>=1.0,<2.0 to avoid surprise breaking changes.
  4. Add .venv/ to .gitignore — the virtual environment itself should not be committed.
  5. Use pip-tools or Poetry for complex dependency trees instead of manually editing requirements.txt.

pip-tools — Pin Dependencies Reliably

For projects using requirements.in as the source of truth:

  pip install pip-tools

# requirements.in (human-edited, loose versions)
# django>=4.2
# requests

pip-compile requirements.in   # generates requirements.txt with all transitive pins
pip-sync requirements.txt     # install exactly what's pinned
  

uv — Fast Modern Package Manager

uv is a fast alternative to pip + venv:

  curl -LsSf https://astral.sh/uv/install.sh | sh

uv venv                        # create .venv
uv pip install django pytest   # install packages
uv pip compile requirements.in -o requirements.txt
uv pip sync requirements.txt
  

.gitignore Template

Never commit virtual environments or local secrets:

  .venv/
venv/
__pycache__/
*.pyc
.env
*.egg-info/
dist/
build/
.poetry/
  

Troubleshooting

Problem Cause Fix
command not found: pip venv not activated source .venv/bin/activate
Wrong package version installed Global vs venv pip which pip — should be inside .venv
externally-managed-environment System Python on newer Linux Use python3 -m venv .venv
Dependency conflicts Incompatible version ranges Use Poetry or pip-tools to resolve
ModuleNotFoundError after install Installed to wrong Python python -m pip install package

Reproducible Environments in Teams

Standard workflow:

  1. Create venv: python -m venv .venv
  2. Activate and install: pip install -r requirements.txt
  3. Commit lock file (requirements.txt or poetry.lock) — not .venv/
  4. Document Python version in README.md or .python-version (for pyenv)

See also Packaging for publishing your own packages.

Task Command
Create venv python3 -m venv .venv
Activate (Unix) source .venv/bin/activate
Install package pip install package_name
Save dependencies pip freeze > requirements.txt
Install from file pip install -r requirements.txt
Upgrade pip pip install --upgrade pip