3.2 · pip, virtual environments (venv) & dependency management

Level 3 · Intermediate Python

3.2pip, virtual environments (venv) & dependency management

Goal: isolate projects with virtual environments (venv), install via pip and manage requirements.txt (freeze / install -r) — the professional method, reproducible on any machine.
Estimated time: 14 min · self-paced reading · If you only have 5 min: read “The essentials in 30s” + the diagram.

The essentials in 30 seconds

  • Global mixes everything: two projects requiring two versions of the same package are impossible together — each project deserves its isolated environment.
  • The venv + pip ritual: python -m venv .venv, activate, pip install, pip freeze > requirements.txt — the interpreter and pip then point to the venv.
  • The .venv is never committed, requirements always is: pinned versions, rebuild proven by pip install -r — the project is portable.

Running mini-case — Nabil escapes version hell

Nabil, junior data analyst in Algiers, installs everything globally: his sales analysis requires a recent version of a library, but a colleague's reporting breaks as soon as he upgrades. He creates one venv per project (python -m venv .venv), activates, installs, pins with pip freeze > requirements.txt, adds .venv to .gitignore. Deleted then rebuilt via pip install -r, each project recovers exactly its versions.

This same case returns in the lesson, the diagram, the script and the 48h challenge.

1. Global chaos and the venv bubble

Python's strength is its PyPI catalogue, installed via pip (pip install pandas). But installing everything globally mixes the dependencies of all projects: project A requires one version, B another — impossible together, that is dependency hell. From the second project on, isolation is non-negotiable.

The solution is the virtual environment (venv): an isolated folder with its own Python and packages, untouched by other projects. Create it (python -m venv .venv), activate it (Windows: .venv\Scripts\activate; macOS/Linux: source .venv/bin/activate) — the prompt changes, python and pip then point to the venv. Nabil creates one venv for sales analysis, another for reporting: each lives its own life.

2. Pin, share, rebuild: requirements.txt

A venv alone is not enough: you need the contract of versions. pip freeze > requirements.txt exports dependencies and pinned versions; pip install -r requirements.txt reinstalls them identically elsewhere. The .venv folder is NEVER committed (bulky, machine-specific, via .gitignore); requirements.txt ALWAYS is (light, shareable).

Nabil's truth test: delete the .venv and rebuild it with one command — if the analysis runs, the project is portable. Check with pip list that the library is indeed in THIS venv, and select the .venv interpreter in the editor. After each addition, re-pin to keep the contract up to date.

Common misinterpretation: “Everything global is simpler, and committing the .venv makes sharing safer.” No. Global guarantees conflicts from two projects on, and a committed .venv pollutes the repo with machine-specific megabytes. One venv per project + pinned requirements + ignored .venv: that trio is what makes the project reproducible.
Isolated, reproducible dependencies Isolate, pin, rebuild: portable everywhere venv (isolate) One activatedenvironment per projectfreeze (pin) requirements.txt,pinned versionsrebuild (prove) Delete,recreate, install -r
Isolate, pin, rebuild: portable everywhere
Text version of the diagram (SEO / screen readers / translation): 1) Isolate: Nabil creates one .venv per project and activates it before any pip install — no more global conflicts. 2) Pin: pip freeze exports the exact versions into requirements.txt, versioned. 3) Prove: he deletes the .venv and rebuilds via pip install -r — same versions, same behaviour. Lesson: requirements is the contract, the venv its execution.

🔎 Concrete example — Full ritual of the isolated project

Nabil isolates his sales analysis, then rebuilds it elsewhere.

python -m venv .venv
.venv\Scripts\activate
pip install requests
pip freeze > requirements.txt
deactivate

Reading: create, activate, install, pin — requirements becomes the contract.

Lesson: elsewhere, recreate the venv then pip install -r requirements.txt restores identically.

Section vocabulary

pip
Python's package manager: pip install name downloads and installs a library from PyPI into the active environment.

Simple example: Nabil's pip install requests in his analysis venv.

What it is not: downloading a ZIP and placing it by hand.

Reflex: always check the active venv before pip install.

PyPI
Central repository of third-party Python libraries: hundreds of thousands of installable packages.

Simple example: The catalogue where Nabil finds requests and pandas.

What it is not: the standard library shipped by default.

Reflex: standard first, PyPI next.

Virtual environment (venv)
Isolated folder with its own Python and packages, specific to one project, not interfering with others.

Simple example: Nabil's .venv sales analysis, separate from reporting.

What it is not: a global install shared by all projects.

Reflex: one venv per project, from the start.

Activation
Making a venv active in the terminal so python and pip point to it (modified prompt).

Simple example: Nabil's activate before each analysis session.

What it is not: working while forgetting to activate, hence in global.

Reflex: activate first, install next.

requirements.txt
List of dependencies and versions: pip freeze exports it, pip install -r reinstalls it identically.

Simple example: The versioned contract Nabil shares in Algiers.

What it is not: the .venv folder committed to Git.

Reflex: pin after each addition, rebuild to prove.

In practice — Isolate a project with venv and pip

  1. Create a venv (python -m venv .venv) then activate it; check that the terminal prompt has changed.
  2. Install a library (pip install requests) and check with pip list that it is in THIS venv, not global.
  3. Pin with pip freeze > requirements.txt; open the file and observe the pinned versions.
  4. Deactivate (deactivate), delete the venv, recreate it and reinstall via pip install -r requirements.txt.
You isolate each project in its venv and manage requirements.txt: professional, reproducible method.

Ready-to-say script — presenting your environment (30 s)

“Each project has its venv: created with python -m venv .venv, activated before any install, dependencies pinned with pip freeze into a versioned requirements.txt, .venv ignored by Git. Tested by deleting then pip install -r: identical rebuild.”

Say in review; show the activated prompt and the requirements.

Copy-paste template — venv + requirements ritual

python -m venv .venv
.venv\Scripts\activate
pip install requests
pip list
pip freeze > requirements.txt
deactivate
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt

Independent

One venv + one pinned requirements is enough to share the analysis friction-free.

SME in Algiers

Nabil duplicates the ritual: one sales venv, one reporting venv, zero conflicts.

Product team

Enforce ignored .venv + versioned requirements for identical installs everywhere.

Beginner

This week: one venv, one install, one freeze, one rebuild.

Caution: Dependencies — NEVER commit the .venv folder (bulky, machine-specific): exclude it via .gitignore and share only requirements.txt with pinned versions. Install only inside an activated venv, re-pin after each addition, and rebuild to prove portability before sharing.

✓ Best practices

  • Create one venv per project from the first pip install.
  • Pin after each addition (freeze) and keep requirements versioned.
  • Rebuild (delete + install -r) to prove reproducibility.

✗ Common pitfalls

  • Installing everything globally (guaranteed version conflicts).
  • Committing the .venv (useless megabytes, machine-specific).
  • Sharing requirements with no pinned versions (silent drift).

Key takeaways

  • pip INSTALLS from PyPI into the ACTIVE environment — check activation first.
  • One VENV isolates dependencies PER PROJECT: no more version conflicts.
  • requirements.txt (freeze / install -r) makes the project REPRODUCIBLE everywhere.
  • .venv NEVER committed (.gitignore); requirements ALWAYS versioned, rebuilt as proof.

48h challenge — apply tomorrow

Create 1 venv, install 1 package, pin the requirements, then rebuild via install -r.

Section exit checklist
  • Each project has its venv activated before install.
  • My requirements pins the exact versions.
  • My .venv is ignored, my rebuild works.
Self-rating 1-5: can I rebuild identically with one command?is one global package still lying around?

Frequently asked questions

Why not install everything globally, it is simpler?

Because two projects will soon require incompatible versions of the same library: that is dependency hell. One venv per project gives each exactly what it needs and makes the project shareable identically via requirements.txt.

Should the .venv folder be committed to Git?

No, never: bulky and machine-specific. Exclude it via .gitignore and share only requirements.txt — each teammate recreates their venv with pip install -r.

Check your understanding

What do you share in Git to reproduce the environment?

Additional resources (optional, to go further)

Level 3 examFresh, harder questions to test what you've learned