Skip to main content

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

MistakeFix
Installing without a venvAlways create and activate venv first
Committing venv/ to gitAdd to .gitignore
No requirements.txtRun pip freeze > requirements.txt
Using pip install as rootUse venv instead
Forgetting to activate venvCheck 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

What's Next

Lesson 2: Dependencies, Locking, and Updates