Topic 14 / 15
pip, Virtual Environments & Project Layout
The Problem Virtual Environments Solve
Project A needs Django 4.2; project B needs Django 5.1. Installed globally, they fight. A virtual environment gives each project its own private package directory and Python launcher.
python3 -m venv venv
source venv/bin/activate # Linux/macOS (Windows: venv\Scripts\activate)
which python # now points inside venv/
deactivate # leave the environmentRules of thumb: one venv per project, named venv or .venv, always in .gitignore, never edited by hand.
pip Essentials
pip install requests # latest version
pip install "django>=5.0,<6.0" # constrained range
pip install -U requests # upgrade
pip uninstall requests
pip list # what's installed
pip show requests # details about one packagerequirements.txt — Reproducible Installs
pip freeze > requirements.txt # snapshot exact versions
pip install -r requirements.txt # recreate anywhereCommit requirements.txt; never commit venv/. Your teammate (and your server) runs two commands and has an identical environment.
pyproject.toml — the Modern Standard
New projects declare metadata and dependencies in one file:
[project]
name = "ci-shop"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"django>=5.0",
"requests",
]
[project.optional-dependencies]
dev = ["pytest", "ruff"]pip install -e ".[dev]" # install the project + dev tools, editableWorth knowing: uv is the new ultra-fast drop-in replacement for pip/venv that many teams have adopted — same concepts, 10–100× faster.
A Sane Project Layout
ci-shop/
├── pyproject.toml
├── README.md
├── .gitignore # venv/, __pycache__/, .env
├── src/
│ └── ci_shop/
│ ├── __init__.py
│ ├── cart.py
│ └── payments.py
└── tests/
└── test_cart.pySecrets (API keys, DB passwords) go in environment variables or a git-ignored .env file — never in code. Read them with os.environ.