Search Topics

Search across all FastAPI topics

GitHub

Python Setup

Fundamentals

You just installed FastAPI. So why can't Python find it? Let's fix that — and make sure it never happens again.

You install FastAPI, run uvicorn main:app, and get: ModuleNotFoundError. You literally just installed it. What went wrong?

terminal
$ uvicorn main:app --reload
Traceback (most recent call last):
  File "main.py", line 1
    from fastapi import FastAPI
ModuleNotFoundError: No module named 'fastapi'

Question

You ran pip install fastapi and it said "Successfully installed." So where did it go? The answer: it went to the wrong Python. And that's exactly the problem virtual environments solve.

The Two Paths: Global vs. Isolated

Without a virtual environment, every project shares the same pile of packages. With one, each project gets its own sandbox. Here's the difference at a glance:

The wrong way:

System Python

Shared by everything

pip install

System packages

Version conflicts!

The right way:

Venv Python

Project-specific

pip install

Isolated packages

No conflicts!

Why venvs exist

What you just learned

ModuleNotFoundError usually means you installed to the wrong Python

Without a venv, packages go to the global system Python

Virtual environments give each project its own isolated set of packages

Why Virtual Environments?

Without virtual environments, every Python project on your machine shares the same global packages. This leads to version conflicts: Project A needs FastAPI 0.100, but Project B needs 0.115. Update one, break the other.

Virtual environments solve this by giving each project its own isolated sandbox of packages. Each project gets exactly the versions it needs, with zero interference.

Visualize: Package Isolation

See what happens when two projects share global packages versus using isolated virtual environments.

Creating a Virtual Environment

Python ships with venv built in — no extra installs needed. Create it, activate it, and you'll see the environment name in your terminal prompt. That's how you know it's working.

terminal
# Create virtual environment
python -m venv .venv

# Activate it
# Windows:
.venv\Scripts\activate
# Mac / Linux:
source .venv/bin/activate

# You'll see (.venv) in your prompt — that means it's active!
# When you're done:
deactivate

Watch out

If you don't see (.venv) in your terminal prompt, the environment isn't active. Any pip install you run will go to your system Python instead. Always check the prompt before installing anything.

Installing Packages

With your venv activated, use pip to install packages. They'll only exist inside this environment — other projects won't even know they're there.

terminal
# Install FastAPI and Uvicorn (the server)
pip install fastapi uvicorn

# Pin to a specific version if you need to
pip install fastapi==0.115.0

# See everything that's installed
pip list

# Save your packages to a file (do this after every install!)
pip freeze > requirements.txt

requirements.txt: Your Project's Recipe

This file is the standard way to share your project's dependencies. It lists every package with its exact version — so anyone can recreate your environment perfectly.

requirements.txt
fastapi==0.115.0
uvicorn==0.32.0
pydantic==2.10.0
python-dotenv==1.0.1

Your teammate clones the repo and runs one command:

terminal
# Recreate the exact same environment
pip install -r requirements.txt

Setup workflow

What you just learned

Always create and activate a venv before installing packages

pip install puts packages in whatever Python is currently active

pip freeze > requirements.txt saves exact versions for reproducibility

pip install -r requirements.txt recreates an environment from scratch

The 'I just installed it!' problem

You open a new terminal, forget to activate the venv, and install a package. It goes to your system Python. Then you activate the venv and the package isn't there.

Broken code
terminal
# Terminal 1 — you forgot to activate the venv
pip install httpx
# Installing to system Python...

# Terminal 2 — venv is active
source .venv/bin/activate
python -c "import httpx"
# ModuleNotFoundError: No module named 'httpx'

Think about it...

You have Python 3.11 and 3.12 installed. You create a venv with 3.11 but pip install from the global terminal. Which Python gets the package?

Hint: What happens when the venv isn't activated?

Key Points

Always Use Venvs

Isolate each project to avoid dependency conflicts between projects

pip Installs Packages

Use pip install to add packages to your active virtual environment

pip freeze Saves Deps

Snapshot your installed packages with exact versions to a file

requirements.txt Shares Deps

Anyone can recreate your environment with pip install -r requirements.txt

These are the patterns that trip up developers most often. Switch between Wrong and Fixed to compare the code side by side.

1
Installing packages globally
Not activating a virtual environment before pip install
Don't do this
terminal
# No virtual environment active!
pip install fastapi uvicorn
# Packages installed globally — conflicts with other projects
Without an active virtual environment, pip installs packages globally. This causes version conflicts between projects and makes it impossible to reproduce your exact setup.
2
Forgetting to freeze dependencies
Not saving installed packages to requirements.txt
Don't do this
terminal
pip install fastapi uvicorn httpx
# Works on your machine...
# But your teammate clones the repo and has no idea
# what packages to install!
Without requirements.txt, no one else can reproduce your environment. Always run pip freeze after installing new packages to keep the file up to date.