pip & virtual environments
Create venvs, install packages with pip, requirements.txt, the externally-managed error, pipx and uv.
Python's standard library is big, but the real superpower is PyPI, the Python Package Index, with over half a million packages: requests for HTTP, pandas for data, Flask and FastAPI for web apps, pytest for testing. You install them with pip — and you install them into a virtual environment, so each project gets its own isolated set of packages. Every professional Python developer does this daily.
The problem virtual environments solve#
Without isolation, every package you install lands in one global location:
- Project A needs
Django 4.2, project B needsDjango 5.1— only one can be installed. - Upgrading a package for one project silently breaks another.
- On Linux, installing into the system Python can break operating-system tools that depend on it.
A virtual environment ("venv") is just a folder containing a link to a Python interpreter plus its own private site-packages directory. Activate it and python and pip refer to that environment; deactivate it and you're back to normal.
Creating and activating a venv#
From your project folder:
This creates a .venv folder (the leading dot keeps it tidy; .venv is also what most editors look for). On Debian/Ubuntu, if you get "ensurepip is not available", install the venv module first with sudo apt install python3-venv. Fedora includes it by default.
Activate it:
Your prompt gains a (.venv) prefix, and python now points inside the folder:
Inside an activated venv you can type plain python and pip — they're guaranteed to be the environment's versions. Leave it with deactivate.
You don't strictly need to activate: running .venv/bin/python script.py or .venv/bin/pip install ... uses the environment directly, which is handy in scripts and cron jobs.
Installing packages with pip#
Always quote version specifiers so your shell doesn't interpret > and < as redirections.
Inspecting what's installed:
Notice that installing requests also pulled in its dependencies (urllib3, certifi and friends). pip resolves and installs them automatically.
Once installed, a package is imported like any module:
Tip: the name you
pip installisn't always the name youimport.pip install beautifulsoup4→import bs4;pip install python-dotenv→import dotenv;pip install Pillow→import PIL. Check the package's documentation.
Recording dependencies: requirements.txt#
Your venv folder should never be committed to git or copied between machines — it contains machine-specific paths. Instead, record what is installed and recreate it anywhere:
A teammate (or your deployment server) then runs:
…and gets exactly the same versions. Add .venv/ to your .gitignore.
Many teams keep a short hand-written list of direct dependencies (requests, flask>=3) and generate the fully pinned list with a tool, or declare dependencies in pyproject.toml — you'll see that in the packaging lesson.
The "externally-managed-environment" error#
On Ubuntu 23.04+, Debian 12+, Fedora 38+ and recent Homebrew, running pip install against the system Python gives:
This is a safety feature (PEP 668), not a bug. Your options, in order of preference:
- Use a virtual environment — this is the answer 99% of the time.
- For command-line tools you want everywhere (like
black,httpie,ruff), use pipx:sudo apt install pipx(orsudo dnf install pipx), thenpipx install ruff. Each tool gets its own hidden venv. - For system-wide libraries, use the distro package:
sudo apt install python3-requests.
Never "fix" it with sudo pip install or --break-system-packages on your main machine.
Always use python -m pip#
If you have several Pythons installed, pip might belong to a different one than python. Running pip through the interpreter removes the ambiguity:
Inside an activated venv, plain pip is fine — but python -m pip is a good habit, and it's what the official docs recommend.
Checking which environment you're in#
From Python itself:
If imports fail with ModuleNotFoundError even though you "installed it", 9 times out of 10 you installed into one environment and ran another. Compare which python with pip --version — both should point inside your .venv. In VS Code, use Python: Select Interpreter and pick the .venv one.
Modern alternative: uv#
uv is a very fast, increasingly popular tool that replaces pip, venv, pip-tools and even installs Python versions. The concepts are the same:
Poetry, PDM and Hatch are other project managers you'll meet in the wild. Learn venv + pip first — every other tool builds on the same ideas.
A typical project workflow#
Then write code, git commit your source plus requirements.txt, and anyone can rebuild the environment in seconds.
Common mistakes#
- Committing
.venvto git — commitrequirements.txtinstead. - Installing with
sudo pip— never needed with venvs, and it can damage the system. - Forgetting to activate the venv in a new terminal, then wondering where your packages went.
- Moving or renaming a venv folder — venvs contain absolute paths. Delete it and recreate from
requirements.txtinstead. - Naming the venv after a package or putting your code inside
.venv— keep code next to it, not in it.
What's next#
With packages and environments sorted, let's work with data that outlives your program: files and context managers.
Check your understanding
Quick quiz
1.Why should every project have its own virtual environment?
2.On Ubuntu 24.04,
pip install requests(outside a venv) fails withexternally-managed-environment. What's the right fix?3.What does
pip freeze > requirements.txtdo?
Finished reading?
Mark this lesson complete to track your progress.