By the end of this guide you will know exactly which Python interpreter is running your script, why the package you installed is invisible to it, and which single command puts them back in agreement. The whole repair usually takes under three minutes once you can read the evidence, and the same reasoning fixes every future ModuleNotFoundError, not just this one.
This is one guide in Debugging Python AI Errors, the section that walks through the failures beginners hit in their first weeks of calling AI APIs.
Prerequisites
You need Python 3.10 or newer already on your machine. If it is missing, start with How to Install Python for AI on Windows, How to Install Python for AI Projects on Mac or How to Install Python for AI on Linux, then come back.
Everything below runs from a terminal opened in your project folder. Install the two packages this guide uses, always through python -m pip for the reason the whole page is about:
python -m pip install "openai>=1.40" "python-dotenv>=1.0"
The final smoke test calls the API, so keep your key in a .env file beside your script:
OPENAI_API_KEY=sk-your-key-here
Then add that file to .gitignore before you commit anything, because a key in a public repository is a key strangers can spend:
echo ".env" >> .gitignore
Step 1 — Make the script name its own interpreter
Start by reading the error itself, because it is more precise than it looks:
Traceback (most recent call last):
File "/home/you/projects/ai-scripts/app.py", line 3, in <module>
from openai import OpenAI
ModuleNotFoundError: No module named 'openai'
ModuleNotFoundError has one narrow meaning: Python searched every folder on its import path and found nothing called openai. It is not saying the package is broken, that your key is wrong, or that the network failed. It is saying "I looked, and it was not there." So the only useful question is where it looked.
An interpreter is the actual python program that reads and executes your file. Most computers have several: one that shipped with the operating system, one you installed yourself, one inside every virtual environment you have ever created, and sometimes one belonging to an editor or a notebook kernel. Each keeps its own private library folder, called site-packages. A package installed into one is completely invisible to the others.
sys.executable is the absolute path of the interpreter currently running your code. Put these two lines at the very top of the file that fails, above every other import:
import sys
print("Interpreter:", sys.executable)
print("Version: ", sys.version.split()[0])
print("Looking for packages in:")
for path in sys.path:
if path.endswith("site-packages"):
print(" ", path)
Run the file exactly the way you normally run it — same terminal, same button, same notebook. Then run this in your terminal to see where pip is pointing:
python -m pip --version
The output ends with the interpreter pip belongs to, something like (python 3.12) preceded by its library path. If that path and the path from sys.executable are not the same, you have found your bug. Nothing is broken, corrupted or missing — you simply installed into one Python and ran under another.
Step 2 — Reinstall with python -m pip
The command pip install openai runs a standalone program called pip that your shell finds by scanning the folders listed in PATH and taking the first match. On a machine with three Pythons, that first match is a coin toss you did not know you were flipping.
The -m flag removes the guesswork. It means "run this module using the interpreter I just named", so python -m pip is always the pip belonging to that exact python. Whatever it installs lands where that interpreter will look:
python -m pip install openai
If you have several versions installed and want to be even more explicit, name the version directly. This is the safest form of the command on macOS and Linux, where python3 and python can differ:
python3.12 -m pip install openai
Watch the last line of the install output too. Pip finishes with either Successfully installed openai-1.x.x or Requirement already satisfied. That second message trips people up: it does not mean your script can import the package, only that this particular interpreter already has it. If you keep seeing "already satisfied" while your script keeps failing, you are still installing into the wrong Python and Step 3 is where you go next.
Make python -m pip your permanent habit. It costs six extra keystrokes and removes an entire category of error from your life.
Step 3 — Activate the virtual environment first
A virtual environment is a private folder holding one interpreter and its own site-packages, so each project keeps its own package versions. Activating it rewires your shell so that plain python and plain pip both point inside that folder. Forget to activate and you are back to the system Python without any warning on screen.
Create and activate one in your project folder:
python -m venv .venv
source .venv/bin/activate
On Windows PowerShell the last line is different:
.venv\Scripts\Activate.ps1
The difference an activation makes is visible in one command. Before, your shell resolves python to the system copy; after, it resolves to the environment's copy, and the prompt gains a (.venv) prefix:
$ which python
/usr/bin/python3
$ source .venv/bin/activate
(.venv) $ which python
/home/you/projects/ai-scripts/.venv/bin/python
On Windows, use where python instead of which python. If your prompt has no (.venv) marker, the environment is not active, and every install you run is going somewhere else. Activation lasts only for that terminal window — open a new tab and you must activate again. That single fact explains most "it worked yesterday" reports. For the full walkthrough, including how to add the environment to .gitignore, read Create a Python Virtual Environment for AI.
Step 4 — Confirm the fix in two commands
Do not rerun your whole script to test a package install. Check the package first, then the import, so a failure tells you precisely which half is wrong.
pip show prints where a package actually lives:
python -m pip show openai
Read the Location: line it prints. That path must contain your .venv folder if you are working in a virtual environment. If it points at a system folder, your shell is still unactivated.
Now test the import on its own, with nothing else in the way:
python -c "import openai; print(openai.__version__)"
A version number means the problem is solved. Any traceback here is still an interpreter problem, not a code problem. Once both commands pass, run a real call to confirm the package works end to end:
import os
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv() # reads .env, which is listed in .gitignore
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Reply with the single word: ready"}],
)
print(response.choices[0].message.content)
If that script prints a word, your environment is healthy. If it prints an authentication complaint instead, the import is fine and you have moved on to a key problem — see Fix the 401 Unauthorized Error in OpenAI Python.
While the environment is working, record what is in it. A requirements.txt file lists every package and version you currently have, so you can rebuild the same environment on another machine, or after you delete a broken .venv and start over:
python -m pip freeze > requirements.txt
Rebuilding later is then two commands — create an environment, then python -m pip install -r requirements.txt — rather than a memory test.
Step 5 — Fix the editor and notebook cases
Editors and notebooks each hold their own interpreter setting, which is why the same folder can work in a terminal and fail behind a Run button.
In VS Code, open the command palette and choose the "Python: Select Interpreter" command, then pick the entry whose path ends in .venv/bin/python (or .venv\Scripts\python.exe on Windows). In PyCharm, the same setting lives under the project interpreter preferences, where you add an existing environment and browse to the same file. Both editors show the selected interpreter in the status bar; if it reads a bare version number with no project name, it is on the global Python. Choose a Code Editor for Python AI Work covers the setting in each editor in more detail.
In Jupyter, JupyterLab or Colab, the notebook runs under a kernel, and the kernel is its own interpreter. Installing from a terminal frequently misses it. Install from inside a cell instead, using the %pip magic command, which targets the running kernel by design:
%pip install openai
Restarting the kernel afterwards matters. A running kernel caches the list of modules it has already tried to import, so a package installed mid-session can stay invisible until the kernel starts fresh. Use the restart button in the toolbar, then rerun your cells from the top and confirm exactly as you did in the terminal:
import sys
print(sys.executable)
import openai
print(openai.__version__)
Quick reference: symptom to wrong interpreter
Match what you observed on the left to the interpreter that is out of step, then apply the fix.
| What you see | Interpreter at fault | Fix |
|---|---|---|
| Fails in the terminal right after a successful install | The pip your shell chose from PATH | python -m pip install openai |
| Works in the terminal, fails on the editor's Run button | The editor's configured interpreter | Select the .venv interpreter in the editor |
| Works in the terminal, fails in a notebook cell | The notebook kernel | %pip install openai in a cell, then restart |
| Worked yesterday, fails in a new terminal | The system Python, environment not activated | source .venv/bin/activate |
Troubleshooting
ModuleNotFoundError: No module named 'openai' in a file you named openai.py. Python searches your current folder before its libraries, so your own file shadows the real package and the import returns your empty file. Rename the file to something like chat_test.py and delete any __pycache__ folder next to it.
AttributeError: module 'openai' has no attribute 'OpenAI'. The import worked, but an old 0.x release of the library is installed and it has no OpenAI client class. Upgrade in place with python -m pip install --upgrade "openai>=1.40".
bash: pip: command not found. No standalone pip executable exists on your PATH, which is common on fresh macOS and Linux installs. This is the error python -m pip was designed for — use it and the problem disappears.
error: externally-managed-environment. Your operating system protects its own Python from stray installs, mostly on recent Linux distributions and Homebrew Python. Do not force it with --break-system-packages; create a virtual environment as in Step 3 and install there instead.
If the traceback you are staring at looks nothing like these, Read a Python Traceback in Five Minutes shows you how to find the one line that names the real cause.
When to use this vs. alternatives
- Use a virtual environment per project for anything you will run more than once. It costs one command, keeps each project's package versions apart, and makes
ModuleNotFoundErrorrare because there is only ever one interpreter in play. - Install into the global Python only for a genuinely throwaway experiment, and expect to hit version conflicts the moment a second project wants a different release of the same library. On systems that raise
externally-managed-environment, this option is closed to you anyway. - Use conda or a similar manager when your work needs heavy scientific packages that ship compiled code. It solves a different problem — binary dependencies — but it adds yet another interpreter to your machine, so keep applying the
python -m piphabit inside a conda environment too.
The lasting lesson is smaller than the error message suggests. Python does not have one library folder; it has one per interpreter, and every install command silently chooses which folder it writes to. Print sys.executable, install with python -m pip, activate before you install, and the most common beginner error in Python stops happening to you. Back to Debugging Python AI Errors.
Related guides
- Create a Python Virtual Environment for AI — set up the per-project environment that prevents this error entirely.
- Read a Python Traceback in Five Minutes — learn to find the meaningful line in any error, not just this one.
- Fix SSL: CERTIFICATE_VERIFY_FAILED in Python — the next wall you may hit once the import finally works.
- Fix Connection and Timeout Errors with AI APIs — handle the network failures that arrive after a successful install.
- Choose a Code Editor for Python AI Work — pick an editor and point it at the right interpreter from day one.