By Seth Black Updated September 27, 2024
If you want to start a solid argument among computer programmers tell them that your way is the best way to setup a new environment, dev machine, or project. Bonus points if you throw in how your favorite programming language is the only way to solve any given problem. With that I mind, I present to you the best way - practically the only way - to setup your Python environment.
Just kidding! There's plenty of acceptable ways to get sh*t done. Who am I to say mine is the best? Instead, let's talk about how I generally setup my Python environments when I'm starting a new or picking up an existing project.
Before embarking on any journey I like to do a little research - read the map if you will. Most, if not all, popular open source projects keep their documentation fairly well up-to-date; and the Python ecosystem is no exception. It's also super embarrassing to get something wrong that's clearly stated in the documentation, had you just taken the time to read it.
I can't thank of any reason why you'd need to start a new project in Python 2. If you're starting a new project, use Python 3. If you're picking up an existing project, use the version of Python that the project is currently using. If you're not sure, check the project's documentation. If you're starting something fresh, please use the latest stable version of Python.
Don't worry about having multiple versions of Python installed on the same computer. For well over a decade now Python for Windows has come with pylauncher built-in, and pyenv has you covered if you're on Mac or Linux.
For the sake of this article, let's install Python version 3.12.1.
I like to keep my code neatly quarantined under a single directory, typically something like ~/Programming or C:\Users\seth\Programming. I don't think it really matters what you call your directory - just as long as you're consistent. Within this Programming directory you will find all of the projects I'm currently hacking on, neatly organized by GitHub repo name or domain name.
Here's what my current Programming directory looks like in Windows.
PS C:\Users\seth\Programming> ls
Directory: C:\Users\seth\Programming
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 9/24/2023 8:49 PM findmenoms.com
d---- 12/19/2023 1:17 PM fiscus.io
d---- 11/23/2023 8:00 PM gift-exchange-2023
d---- 12/29/2023 2:13 PM kdramabookclub.com
d---- 9/20/2023 4:29 PM llama
d---- 12/20/2023 5:53 PM mindyourink
d---- 1/5/2024 11:27 AM quimbyapp.com
d---- 12/13/2023 7:58 PM sethserver.com
I'm definitely a purist when it comes to virtual environments in Python. I'm also very, very strict about not installing unnecessary packages in my root Python environment. This results in every project under my Programming directory having a virtual environment contained within.
Getting a virtual environment setup is fairly straight forward. I'm in the habit of naming my environments env, but you do whatever works best for you. I'll create a new folder called venvexample, create a virtual environment in that folder then activate the virtual environment.
PS C:\Users\seth\Programming> mkdir venvexample
Directory: C:\Users\seth\Programming
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 1/8/2024 12:01 PM venvexample
PS C:\Users\seth\Programming> cd .\venvexample\
PS C:\Users\seth\Programming\venvexample> py -m venv env
PS C:\Users\seth\Programming\venvexample> ls
Directory: C:\Users\seth\Programming\venvexample
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 1/8/2024 12:01 PM env
PS C:\Users\seth\Programming\venvexample> .\env\Scripts\activate
(env) PS C:\Users\seth\Programming\venvexample>
In Python, dependencies are managed by pip by default. There are other options, but I've never had too many compelling reasons to use anything else.
Let's install a package (my favorite web framework Flask) and see what happens.
(env) PS C:\Users\seth\Programming\venvexample> pip install flask
Collecting flask
Using cached flask-3.0.0-py3-none-any.whl (99 kB)
Collecting Werkzeug>=3.0.0
Using cached werkzeug-3.0.1-py3-none-any.whl (226 kB)
Collecting Jinja2>=3.1.2
Using cached Jinja2-3.1.2-py3-none-any.whl (133 kB)
Collecting click>=8.1.3
Using cached click-8.1.7-py3-none-any.whl (97 kB)
Collecting itsdangerous>=2.1.2
Using cached itsdangerous-2.1.2-py3-none-any.whl (15 kB)
Collecting blinker>=1.6.2
Using cached blinker-1.7.0-py3-none-any.whl (13 kB)
Collecting colorama
Using cached colorama-0.4.6-py2.py3-none-any.whl (25 kB)
Collecting MarkupSafe>=2.0
Using cached MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl (17 kB)
Installing collected packages: MarkupSafe, itsdangerous, colorama, blinker, Werkzeug, Jinja2, click, 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
Now that we have some dependencies installed, let's save them to a file so we can easily install them again later. This is stored in a file called requirements.txt in the root of the project. This file can be created using pip pip.
(env) PS C:\Users\seth\Programming\venvexample> pip freeze > requirements.txt
Now, if you ever need to install these exact dependencies again you can! How convenient! You'll also notice that most Python projects have requirements.txt in the root of the directory.
Let's take a look at what we've done.
Hope this helps give you a more solid foundation when you're working on a Python project.
Good luck and happy Pythoning!
-Sethers
P.S. If your Python environment ever breaks you can check out this overview of how to fix a broken Python environment.