Programmers love to argue about "best practices" like movie nerds argue about director's cuts. Everyone's convinced their version is the only sane one. Mine isn't the best. It just keeps me from throwing my laptop out a window at 2am when pip decides to install the wrong version of everything.
This is my opinionated, practical guide for Python environments and dependencies. Works for new projects. Works for jumping into someone else's repo. Keeps you from breaking your global Python install and questioning your life choices.
Step 0: Read the docs (yes, really)
I still waste hours before realizing the answer was in the README the whole time. You skim, you assume, you waste an hour debugging. Then you read the README: "Use Python 3.10." Oh. Right.
If you're joining a project? Check these first:
README.mdpyproject.toml/requirements.txt- CI config (GitHub Actions, etc.)
- Whatever the team pinned in Docker
Step 1: Pick the right Python version
Here's what I do:
- Never start new work in Python 2. It's over.
- New project? Use the latest stable Python.
- Existing project? Match what it already uses. Don't "upgrade it real quick" as your first commit.
You can have multiple Python versions on one machine. That's how it's supposed to work.
Windows: use the Python Launcher (py).
Mac/Linux: I use pyenv.
I'm using Python 3.12.1 for these examples.
Check what you've got:
py -0p
py -3.12 --version
Step 2: Keep your projects in one place
I'm boring about this, but it matters. Everything goes under one directory. Mine is:
C:\Users\seth\Programming
Inside that, I name folders by repo or domain. Consistency beats cleverness.
Example:
C:\Users\seth\Programming
├── findmenoms.com
├── fiscus.io
├── gift-exchange-2023
├── kdramabookclub.com
├── llama
├── mindyourink
├── quimbyapp.com
└── sethserver.com
This matters more than it should. Half the time someone says "my Python is broken," they're just in the wrong directory with three different venvs activated somehow.
Step 3: Make a virtual environment (every time)
I'm strict about this.
Never install project packages into your root Python.
Every project gets its own venv. No exceptions.
Break this rule once and you'll spend three hours figuring out why requests is version 2.18 and you have no idea when you installed it.
Create the project and venv:
mkdir venvexample
cd venvexample
py -m venv env
Activate it:
.\env\Scripts\activate
Your prompt should change:
(env) PS C:\Users\seth\Programming\venvexample>
No (env) in your prompt? Stop. Don't keep going.
Otherwise you're installing into global Python and tomorrow you'll be confused why Flask works in one project but not another.
Step 4: Install dependencies with pip
There are other tools. Poetry, pipenv, whatever. I keep using pip because it's simple and it works.
Let's install Flask:
pip install flask
You'll see something like this:
Collecting flask
Downloading flask-3.0.0-py3-none-any.whl
Collecting Werkzeug>=3.0.0
Collecting Jinja2>=3.1.2
Collecting click>=8.1.3
Collecting itsdangerous>=2.1.2
Collecting blinker>=1.6.2
Collecting colorama
Collecting MarkupSafe>=2.0
Installing collected packages: MarkupSafe, colorama, itsdangerous, click, blinker, Werkzeug, Jinja2, flask
Successfully installed Jinja2-3.1.2 MarkupSafe-2.1.3 Werkzeug-3.0.1 blinker-1.7.0 click-8.1.7 colorama-0.4.6 flask-3.0.0 itsdangerous-2.1.2
That dependency list is why you need venvs. Your app is never "just Flask." It's Flask plus eight other libraries. Keep that mess inside the project.
Step 5: Freeze dependencies to requirements.txt
This is how you save your setup.
pip freeze > requirements.txt
Now someone else (or you in three months when you forgot everything) can run:
pip install -r requirements.txt
...and get the exact same setup.
Step 6: When your venv breaks, just delete it
Venv acting weird? Delete it and make a new one. Seriously.
Virtual environments are meant to be disposable. That's the whole point.
- Delete
env/ - Re-run
py -m venv env - Activate
pip install -r requirements.txt
If your whole Python install is cursed, I wrote about that too: Fixing a Broken Python Environment (P.S. yes, the URL is real, and yes, I've had to fix broken Python installs more times than I want to admit).
-Sethers