C.W.K.
Stream
Lesson 04 of 05 · published

Virtual Environments, requirements.txt, Editable Installs

~11 min · pip, concepts, venv

Level 0Newbie
0 XP0/55 lessons0/16 achievements
0/80 XP to next level80 XP to go0% complete

Four concepts carry most of pip-based Python development. Knowing each one cleanly distinguishes you from someone who 'just runs pip install' and hopes.

Virtual environments (venv). A directory containing its own Python interpreter copy and its own site-packages. Activating it adjusts your shell's PATH so python and pip resolve inside the venv. Deactivating restores PATH. Each project gets its own venv; nothing leaks between them. The .venv directory should be gitignored (always recreatable).

requirements.txt. A flat text file listing packages, optionally with version constraints (requests==2.31.0, flask>=3.0). pip reads it with pip install -r requirements.txt. Crucially, requirements.txt is not a true lockfile — it doesn't capture transitive dep versions or content hashes. For real reproducibility you need pip-tools (which generates a fully-pinned requirements.txt from a smaller requirements.in) or you switch to uv's uv.lock.

Editable installs (pip install -e .). When developing a Python package, you want changes to source code to take effect immediately — no reinstall on every save. pip install -e . installs the package as a symlink-equivalent into the venv's site-packages. This is how every Python library is developed.

Limitations. Three pip limitations that bite real projects: no Python version management (you need pyenv to install multiple Python versions); slow installs (pip resolves and downloads serially; uv parallelizes); dirty uninstalls (uninstall a package, its deps stay — they accumulate over time). pip's design just doesn't address these.

Code

requirements.txt — not a true lockfile·text
# A typical hand-edited requirements.txt
requests>=2.31.0
flask>=3.0
sqlalchemy[asyncio]>=2.0

# pip-tools-generated (the closer-to-lockfile version)
# Generated by: pip-compile requirements.in
requests==2.31.0 \
    --hash=sha256:abcd... \
    --hash=sha256:efgh...
flask==3.0.3 \
    --hash=sha256:...
# ... and every transitive dep, pinned with hashes
venv layout on disk·bash
ls .venv/
# bin/         — python, pip, console scripts of installed packages
# lib/         — site-packages (where everything installs)
# include/     — C headers (for packages with C extensions)
# pyvenv.cfg   — config: which Python version this venv uses

ls .venv/bin/
# python   python3   python3.13   pip   pip3   pip3.13   activate   ...

External links

Exercise

Install pip-tools in your venv ('pip install pip-tools'), create a requirements.in with two packages ('echo "requests\nflask" > requirements.in'), then 'pip-compile requirements.in'. Read the generated requirements.txt — note every transitive dep is now pinned with a hash. THIS is a real lockfile.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.