DEV Community

Cover image for Python Virtual Environments: venv, pip, and requirements.txt from Scratch
German Yamil
German Yamil

Posted on

Python Virtual Environments: venv, pip, and requirements.txt from Scratch

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
Enter fullscreen mode Exit fullscreen mode

That single command creates a .venv folder. Inside it you will find:

  • bin/ (macOS/Linux) or Scripts/ (Windows) โ€” copies of python and pip pointing 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/
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Windows (Command Prompt):

.venv\Scripts\activate
Enter fullscreen mode Exit fullscreen mode

Windows (PowerShell):

.venv\Scripts\Activate.ps1
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Installing Packages with pip

With the environment active, install packages exactly as you normally would:

pip install requests pillow
Enter fullscreen mode Exit fullscreen mode

pip downloads and installs those packages into .venv/lib/, not into your system Python. Run pip list to confirm what is installed:

pip list
Enter fullscreen mode Exit fullscreen mode

To inspect a specific package:

pip show requests
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

requirements.txt: Locking Your Dependencies

Once you have the packages you need, freeze the exact versions to a file:

pip freeze > requirements.txt
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

On Windows:

.venv\Scripts\python.exe script.py
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 .
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

To rebuild the environment on a new machine or after cloning:

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode

For cron jobs and automated tasks, skip activation and call the Python binary directly:

.venv/bin/python pipeline/run_daily.py
Enter fullscreen mode Exit fullscreen mode

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:

  1. python3 -m venv .venv to create the environment
  2. Activate it while developing
  3. pip install what you need
  4. pip freeze > requirements.txt to lock the versions
  5. Add .venv/ to .gitignore
  6. Use .venv/bin/python directly 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.


Further Reading

Top comments (0)