Other people's code
Python comes with a large standard library: json, os, random, datetime and a few hundred more. Those need no installing:
import random
print(random.choice(["heads", "tails"]))Everything else lives on PyPI, a public archive of packages anyone can publish to, and you fetch it with pip. requests for HTTP. pandas for tables. openai or anthropic for AI APIs.
Why not just install everything system-wide
Two reasons, and they are not theoretical.
First, your operating system uses Python for its own work. On many Linux systems, parts of the package manager and desktop are written in it. Installing or upgrading packages into that Python can break things that have nothing to do with your project.
Second, and more common: two of your projects will eventually need different versions of the same package. Project A was written against version 1 and breaks on version 2. Project B needs version 2. There is one system Python and one slot per package, so one of them loses.
A virtual environment is the fix. It is an ordinary folder containing its own python and its own place to put packages. Install into it and nothing outside is touched. Delete the folder and the install is undone completely. Every project gets its own.
Making one
cd my-project
python3 -m venv .venvThat creates a folder called .venv. Now activate it, which means "for this terminal session, python and pip mean the ones inside .venv":
source .venv/bin/activate # macOS or Linux
.venv\Scripts\activate # Windows PowerShellYour prompt changes to show (.venv). Now install:
python -m pip install requestsWhen you are finished, deactivate puts the terminal back to normal. Add .venv/ to .gitignore; it is rebuildable and large, and it never belongs in a repository.
Use python -m pip install rather than bare pip install. It guarantees the pip you run belongs to the python you are running, which removes the most common cause of the next section.
The error that will happen to you
ModuleNotFoundError: No module named 'requests'This almost never means the install failed. It means the Python running your script is not the Python you installed into. Diagnose it from inside the program, not by guessing:
import sys
print(sys.executable)If that prints a system path like /usr/bin/python3 and you installed into .venv, there is your answer. Common causes: you opened a new terminal and forgot to activate, since activation only applies to one shell session; or your editor is configured to run a different interpreter than your terminal uses.
A related message you may see on Debian, Ubuntu or a Raspberry Pi:
error: externally-managed-environmentThat is not a bug. The system is refusing to let you install into the Python it depends on, and telling you to make a virtual environment. Make one.
Recording what a project needs
python -m pip freeze > requirements.txtThat writes every installed package and its exact version into a file. Someone else, or you on another machine, can then reproduce your setup:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txtCommit requirements.txt. It is small, it is text, and it is the difference between "works on my machine" and "works".
Import, once installed
import requests
print(requests.__version__)
from datetime import date
print(date.today())Installing and importing are separate steps. pip install puts the code on your disk, once. import loads it into a running program, and belongs at the top of every file that uses it.
One honest caution about PyPI: anyone can publish there, and names close to popular packages are sometimes registered by people hoping you will mistype. Check the spelling of a package before you install it, and prefer the name given in the official documentation over one you half-remember.
Try this now
Make a folder, create a venv, activate it, install requests, then run a file containing import sys, requests and print(sys.executable). Then open a brand new terminal, do not activate, and run the same file. Read the error you get, and check it against what you now know.
Before you move on