Python Virtual Environments: venv, pip, and requirements.txt from Scratch
๐ Free: AI Publishing Checklist โ 7 steps in Python ยท Full pipeline: germy5.gumroad.com/l/xhxkzz (pay what you want, min $9.99)
The Global Python Mess Problem
Picture this: you install requests 2.28 for Project A. Six months later you start Project B and run pip install requests โ now you have requests 2.31. You go back to Project A and it breaks because the library changed a behaviour you relied on.
That is the global Python mess. Every pip install without a virtual environment dumps packages into one shared bucket. Projects step on each other, versions conflict, and "but it worked on my machine" becomes your daily mantra.
Virtual environments solve this completely. Each project gets its own isolated Python installation with its own packages. What you install for Project A is invisible to Project B. They can even use different versions of the same library without any conflict.
The good news: venv ships with Python 3.3+. No extra install required.
Creating a Virtual Environment
Navigate to your project folder and run:
python3 -m venv .venv
That single command creates a .venv folder. Inside it you will find:
-
bin/(macOS/Linux) orScripts/(Windows) โ copies ofpythonandpippointing to this isolated environment -
lib/โ where installed packages land, completely separate from your system Python -
pyvenv.cfgโ a small config file recording which Python version was used
The dot prefix (.venv) is a convention. It keeps the folder hidden in file explorers, signals to other developers what it is, and is widely recognised by tools like VS Code.
Always add .venv to .gitignore โ you never commit the environment itself, only the list of packages needed to recreate it:
# .gitignore
.venv/
Activating the Environment
Activation makes your shell use the environment's python and pip instead of the system ones.
macOS / Linux:
source .venv/bin/activate
Windows (Command Prompt):
.venv\Scripts\activate
Windows (PowerShell):
.venv\Scripts\Activate.ps1
After activation your prompt changes โ you will see (.venv) at the start. Every python and pip command now runs inside the environment.
To deactivate when you are done:
deactivate
Installing Packages with pip
With the environment active, install packages exactly as you normally would:
pip install requests pillow
pip downloads and installs those packages into .venv/lib/, not into your system Python. Run pip list to confirm what is installed:
pip list
To inspect a specific package:
pip show requests
This prints the version, author, dependencies, and install location โ handy when you need to verify exactly what you have.
To upgrade a package:
pip install --upgrade requests
requirements.txt: Locking Your Dependencies
Once you have the packages you need, freeze the exact versions to a file:
pip freeze > requirements.txt
The resulting file looks like this:
certifi==2024.2.2
charset-normalizer==3.3.2
idna==3.6
pillow==10.2.0
requests==2.31.0
urllib3==2.2.1
Every package and sub-dependency is pinned to an exact version. Anyone who clones your project can recreate the same environment with one command:
pip install -r requirements.txt
This is how you ship reproducible setups. The environment itself stays out of git; the recipe for rebuilding it goes in.
Using the venv Python Without Activating
Activation is convenient when working interactively, but it is not always available โ cron jobs and system services do not have a shell environment to activate.
The solution is to call the environment's Python binary directly by its full path:
.venv/bin/python script.py
On Windows:
.venv\Scripts\python.exe script.py
This is one of the most useful patterns for automation. If you have a cron job running a script every night, you point it at .venv/bin/python explicitly and forget about activation entirely:
0 2 * * * /home/user/myproject/.venv/bin/python /home/user/myproject/run_pipeline.py
The script uses the correct packages every time, with zero setup required at runtime.
Installing Local Packages in Editable Mode
If you are building a Python package inside your project โ a folder with a setup.py or pyproject.toml โ you can install it in editable mode so changes take effect immediately without reinstalling:
pip install -e .
This is useful when your project is both a runnable application and an importable library.
Complete Example: Setting Up a Publishing Pipeline Environment
Here is the full workflow from an empty folder to a running environment, using a publishing automation project as the example:
# 1. Create the project folder and move into it
mkdir publishing-pipeline
cd publishing-pipeline
# 2. Create the virtual environment
python3 -m venv .venv
# 3. Activate it
source .venv/bin/activate # macOS/Linux
# .venv\Scripts\activate # Windows
# 4. Install the project's dependencies
pip install requests pillow openai python-dotenv
# 5. Develop and test your scripts...
# 6. Lock the dependencies when ready to share or deploy
pip freeze > requirements.txt
# 7. Add the environment to .gitignore
echo ".venv/" >> .gitignore
# 8. Commit requirements.txt (not .venv)
git add requirements.txt .gitignore
git commit -m "Add project dependencies"
To rebuild the environment on a new machine or after cloning:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
For cron jobs and automated tasks, skip activation and call the Python binary directly:
.venv/bin/python pipeline/run_daily.py
Quick Reference Table
| Task | Command |
|---|---|
| Create environment | python3 -m venv .venv |
| Activate (macOS/Linux) | source .venv/bin/activate |
| Activate (Windows CMD) | .venv\Scripts\activate |
| Deactivate | deactivate |
| Install a package | pip install <package> |
| Install from file | pip install -r requirements.txt |
| Upgrade a package | pip install --upgrade <package> |
| List installed packages | pip list |
| Show package details | pip show <package> |
| Freeze to requirements | pip freeze > requirements.txt |
| Install local package (editable) | pip install -e . |
| Run script without activating | .venv/bin/python script.py |
Summary
Virtual environments are not optional โ they are the baseline for any Python project that you want to work reliably across machines and time. The workflow is always the same:
-
python3 -m venv .venvto create the environment - Activate it while developing
-
pip installwhat you need -
pip freeze > requirements.txtto lock the versions - Add
.venv/to.gitignore - Use
.venv/bin/pythondirectly in automated scripts
Two files matter: requirements.txt goes into version control; .venv/ does not.
Closing
The pipeline uses a dedicated venv so cron can call .venv/bin/python directly without activating: germy5.gumroad.com/l/xhxkzz โ pay what you want, min $9.99.
Top comments (0)