Part of Python for Beginners

Virtual Environments & pip (Create, Activate, Freeze, Requirements) - Python Tutorial #27

Sandy LaneSandy Lane

Video: Virtual Environments & pip (Create, Activate, Freeze, Requirements) - Python Tutorial #27 by Taught by Celeste AI - AI Coding Coach

Take the quiz on the full lesson page
Test what you've read · interactive walkthrough

Python Virtual Environments and pip

python -m venv .venv creates an isolated Python. source .venv/bin/activate activates it. pip install package adds dependencies. pip freeze > requirements.txt records them. pip install -r requirements.txt reinstalls. The standard project workflow.

The minute you start using third-party libraries, you need to manage them per-project. Virtual environments are how Python does that.

Why virtual environments?

Without a venv, pip install puts packages into your system Python. Problems:

  • Project A wants requests==2.20, project B wants 2.30 — conflict.
  • A package upgrade silently breaks an old project.
  • Removing a package from one project removes it from all.
  • You can't pip install system-wide on macOS or recent Linux without sudo or --break-system-packages.

A virtual environment is a per-project Python with its own site-packages. Each project has its own dependencies, isolated.

Creating a venv

python -m venv .venv

This creates a .venv/ directory with:

  • bin/ (Linux/Mac) or Scripts/ (Windows) — python, pip, etc.
  • lib/ — installed packages.
  • pyvenv.cfg — config.

The convention: name it .venv (hidden, single per project) or venv.

Activating the venv

# Linux/macOS
source .venv/bin/activate

# Windows (cmd)
.venv\Scripts\activate.bat

# Windows (PowerShell)
.venv\Scripts\Activate.ps1

After activation:

  • python and pip point to the venv's copies.
  • New packages install into the venv only.
  • Your prompt usually shows (.venv) to remind you.

To leave:

deactivate

Or skip activation: python -m

You can run venv-installed tools without activating:

.venv/bin/python script.py
.venv/bin/pip install requests

Or let the OS find them via the activated PATH. Either works; activation is just a shortcut.

Installing packages

pip install requests
pip install requests==2.32.5      # specific version
pip install "requests>=2.30,<3"   # version range
pip install -U requests           # upgrade
pip install -e .                  # install local project in editable mode

After install, you can use it:

import requests

r = requests.get("https://jsonplaceholder.typicode.com/users")
print(r.json())

Listing what's installed

pip list                # all installed
pip show requests       # details about a package
pip freeze              # one line per package, with exact versions

pip freeze is what you use for requirements.txt.

requirements.txt

pip freeze > requirements.txt

Output:

certifi==2026.1.4
charset-normalizer==3.4.4
idna==3.11
requests==2.32.5
urllib3==2.6.3

This file pins exact versions of every package (including transitive dependencies). Commit it to git.

To reinstall on another machine:

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Identical environment, reproducibly.

Direct vs transitive dependencies

pip freeze mixes them. For cleaner tracking:

  • List only what you directly import in requirements.txt.
  • Leave transitive dependencies to be resolved.

For more rigor, use pip-tools:

pip install pip-tools
# Edit requirements.in (direct deps only)
pip-compile requirements.in     # generates requirements.txt with pins
pip-sync                        # match the venv exactly to the pinned file

Removing packages

pip uninstall requests

Note: this only removes requests, not its dependencies. To clean up orphaned dependencies, use pip-autoremove or rebuild the venv.

Modern alternatives

The venv + pip + requirements.txt workflow is the standard, but newer tools have advantages:

  • uv — by Astral. Drop-in replacement for venv + pip; much faster (Rust). Recommended for new projects.
  • Poetry — full project manager: pyproject.toml, lockfile, build, publish. Heavier but integrated.
  • Hatch — similar to Poetry; PEP-compliant.
  • conda — popular in data science; manages non-Python deps too.

For most beginners: stick with venv + pip until you hit its limits.

pyproject.toml (preview)

Modern Python projects use pyproject.toml instead of requirements.txt:

[project]
name = "myproject"
version = "0.1.0"
dependencies = [
  "requests>=2.30",
  "click>=8.0",
]

[project.optional-dependencies]
dev = ["pytest", "ruff"]
pip install -e .         # install your project
pip install -e ".[dev]"  # plus dev tools

Lesson 40 covers this in depth.

A typical project layout

myproject/
  .venv/                # virtual env (gitignored)
  .gitignore            # includes .venv
  README.md
  requirements.txt      # pinned dependencies
  src/
    myproject/
      __init__.py
      app.py
  tests/
    test_app.py

.gitignore:

.venv/
__pycache__/
*.pyc

Rebuilding from scratch

When in doubt, rebuild:

rm -rf .venv
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

A fresh venv is cheap (seconds), and it eliminates "works on my machine" mysteries.

VS Code / PyCharm integration

Both detect .venv in your project folder automatically. Open the project, and the IDE selects the venv's interpreter. New terminals open with the venv activated.

If autodetection misses, manually pick the interpreter at <project>/.venv/bin/python.

Multiple Python versions

python3.11 -m venv .venv
python3.12 -m venv .venv-312

Each venv pins the Python version it was created with. Useful when testing across versions.

For managing multiple Pythons, tools like pyenv (Linux/Mac) or the python.org installers (Windows) install side-by-side versions.

Common stumbles

Installing into system Python. pip install outside a venv. Always activate first; the prompt shows (.venv) when you have.

Forgetting to activate. Imports fail with ModuleNotFoundError. Activate the venv (or use the venv's python/pip directly).

Different Python in venv vs system. The venv is locked to whatever Python created it. To upgrade Python, recreate.

Committing .venv/. Huge directory, OS-specific binaries. Add to .gitignore.

Stale requirements.txt. After installing new packages, pip freeze > requirements.txt again. Otherwise teammates get an out-of-date environment.

Activating a venv from one shell, expecting it everywhere. Activation is per-shell. Each new terminal needs source .venv/bin/activate.

Rebuilding when you should troubleshoot. Sometimes a bad install really needs investigation. But for "weird import errors with no other clues," rm -rf .venv && python -m venv .venv is fast and often fixes it.

What's next

Lesson 28: unittest. Writing tests with the standard library's testing framework.

Recap

python -m venv .venv creates an isolated Python; source .venv/bin/activate activates it. pip install package installs into the venv only. pip freeze > requirements.txt records dependencies; pip install -r requirements.txt reinstalls. Commit requirements.txt, gitignore .venv/. For new projects, consider uv for speed or Poetry for full project management. Recreate the venv when in doubt.

Next lesson: unittest.

Ready? Take the quiz on the full lesson page →
Test what you've learned. Watch the lesson and try the interactive quiz on the same page.