venv, pip, and Project Layout
What You'll Learn
How to create isolated environments for every project, use pip effectively, and lay out a project so it's easy to run, test, and share.
The Problem: Global Python Is Fragile
Without virtual environments, all packages go into the system Python:
System Python
├── requests==2.28 ← project A needs this
├── requests==2.31 ← project B needs this (conflict!)
├── numpy==1.24
└── flask==2.0
When projects need different versions, they break each other.
Solution: each project gets its own isolated environment.
Creating a Virtual Environment
# Create venv (Python 3.3+, no install needed)
python3 -m venv venv
# Activate
source venv/bin/activate # Linux / macOS
# venv\Scripts\activate # Windows
# Your prompt changes: (venv) $
# Deactivate when done
deactivate
Where packages go:
venv/
├── bin/
│ ├── python3 ← venv's Python
│ └── pip ← venv's pip
└── lib/
└── python3.11/
└── site-packages/ ← all installed packages
Always activate before working on a project:
cd my-project
source venv/bin/activate
python3 --version # confirms you're using venv's Python
which python3 # should show path inside venv/
pip — Package Management
# Install a package
pip install requests
# Install a specific version
pip install requests==2.31.0
# Install minimum version
pip install "requests>=2.28"
# Install from a requirements file
pip install -r requirements.txt
# Upgrade a package
pip install --upgrade requests
# Uninstall
pip uninstall requests
# List installed packages
pip list
# Show package details and dependencies
pip show requests
# Check for outdated packages
pip list --outdated
requirements.txt
The simplest way to save and restore dependencies:
# Save current environment
pip freeze > requirements.txt
# Restore on another machine
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
requirements.txt (pinned versions for reproducibility):
certifi==2024.2.2
charset-normalizer==3.3.2
idna==3.6
requests==2.31.0
urllib3==2.2.1
For development vs production, use separate files:
requirements.txt # production dependencies
requirements-dev.txt # dev + production
requirements-dev.txt:
-r requirements.txt # include production deps
pytest==8.1.0
ruff==0.3.0
mypy==1.9.0
Standard Project Layout
Small Script
task.py
requirements.txt
.gitignore
README.md
Medium Project
my-project/
├── venv/ ← not committed to git
├── src/
│ ├── main.py
│ ├── utils.py
│ └── config.py
├── tests/
│ ├── conftest.py
│ └── test_main.py
├── requirements.txt
├── requirements-dev.txt
├── .gitignore
└── README.md
Package (Installable)
my-package/
├── venv/
├── src/
│ └── mypackage/
│ ├── __init__.py
│ ├── core.py
│ └── utils.py
├── tests/
│ └── test_core.py
├── pyproject.toml ← package metadata
├── .gitignore
└── README.md
.gitignore for Python
# Virtual environment
venv/
.venv/
env/
# Python cache
__pycache__/
*.py[cod]
*.pyo
# Distribution
dist/
build/
*.egg-info/
# Testing
.pytest_cache/
.coverage
htmlcov/
# Type checking
.mypy_cache/
# IDEs
.vscode/
.idea/
*.swp
# Secrets
.env
.env.local
Useful pip Patterns
Install without version pinning (flexible)
pip install "requests>=2.28,<3.0" # major version constraint
Install from git
pip install git+https://github.com/user/repo.git
pip install git+https://github.com/user/repo.git@v1.2.3
Install local package in editable mode
pip install -e . # installs from current directory, links source
Show dependency tree
pip install pipdeptree
pipdeptree
Checking Your Environment
# What Python are you using?
which python3
python3 --version
# Are you in a venv?
echo $VIRTUAL_ENV # empty if not in venv
# What's installed?
pip list
pip freeze
# Is the right package available?
python3 -c "import requests; print(requests.__version__)"
Common Mistakes
| Mistake | Fix |
|---|---|
| Installing without a venv | Always create and activate venv first |
Committing venv/ to git | Add to .gitignore |
No requirements.txt | Run pip freeze > requirements.txt |
Using pip install as root | Use venv instead |
| Forgetting to activate venv | Check which python3 |
Quick Reference
# Create venv
python3 -m venv venv
source venv/bin/activate
deactivate
# pip
pip install package
pip install package==1.2.3
pip install -r requirements.txt
pip freeze > requirements.txt
pip list --outdated
pip uninstall package
# Check env
which python3
python3 --version
echo $VIRTUAL_ENV