Practical Guide to Python Virtual Environments (venv)

Python virtual environments (venv) provide an isolated workspace that lets you clone a project, install its dependencies, and run it without interfering with your system or other projects.

This write-up covers what virtual environments are, why they matter, and the exact commands and patterns you’ll use day-to-day on macOS/Linux and Windows. It also includes reproducibility tips, IDE setup, CI/Docker notes, and common pitfalls.


1) What is a virtual environment?

A virtual environment is an isolated Python installation (interpreter + site-packages) living inside your project folder. It lets each project have its own dependency versions without conflicting with other projects or your system Python.

Key properties:

  • A python and pip that point to the environment’s interpreter.
  • Packages installed into the environment’s site-packages directory only.
  • Fully removable by deleting the environment folder.

2) Prerequisites: verify your Python

Check what Python you’ll use to create the venv:

python3 --version        # macOS/Linux (often `python3`)
python --version         # Windows (often `python`)

If you have multiple Pythons installed (e.g., 3.10, 3.11), choose explicitly:

python3.11 --version

Tip: Tools like pyenv (macOS/Linux) or pyenv-win can manage multiple Python versions. Use them when you need per-project runtimes.


3) Create the environment

Inside your project root:

macOS / Linux

# Create (Python 3.11 shown as example)
python3.11 -m venv .venv

# Recommended: name it `.venv` and keep it in the project root
# (This is widely recognized by IDEs and easy to gitignore.)

Windows (PowerShell or CMD)

REM Create
py -3.11 -m venv .venv

Why .venv? It’s conventional, IDE-friendly, and keeps the environment close to the code.


4) Activate / Deactivate

Activation puts the venv’s python and pip first on your PATH.

macOS / Linux (bash/zsh/fish)

# Bash/Zsh:
source .venv/bin/activate

# Fish:
source .venv/bin/activate.fish

Windows

.\.venv\Scripts\activate

Deactivate anytime

deactivate

You can skip activation by calling the interpreter directly: ./.venv/bin/python -m pip install ... (macOS/Linux) or .venv\Scripts\python -m pip ... (Windows). This is handy in CI.


5) Upgrade tooling & install packages

Right after activation:

python -m pip install --upgrade pip setuptools wheel

Install packages:

pip install requests fastapi uvicorn

Verify isolation:

python -c "import sys,site;print(sys.executable);print(site.getsitepackages())"

6) Capture and pin dependencies

Option A: requirements.txt (simple & ubiquitous)

Save what’s currently installed:

pip freeze > requirements.txt

Recreate elsewhere:

python -m venv .venv
source .venv/bin/activate         # or Windows activate
pip install -r requirements.txt

Pros: dead simple.
Cons: pip freeze includes all transitive deps and exact versions, which can drift between platforms unless curated.

Option B: Constraints for tighter control

Keep a human-curated requirements.in, compile to pinned requirements.txt with a resolver (e.g., pip-tools):

pip install pip-tools
pip-compile requirements.in    # produces a fully pinned requirements.txt
pip-sync                       # installs exactly what’s pinned

Pros: deterministic builds; easy updates via pip-compile --upgrade.
Cons: adds a tool, but it’s worth it for teams/CI.

Option C: pyproject.toml (modern packaging)

If you’re publishing a package or want project metadata:

  • Put your dependencies under project.dependencies in pyproject.toml.
  • Use pip install . or a builder (e.g., build) to install.

If you’re not publishing, requirements.txt or pip-tools is often simpler.


7) Recommended project layout

your-project/
├─ .venv/                # your venv (not checked in)
├─ src/                  # your package code (optional but clean)
│  └─ your_package/
├─ tests/
├─ requirements.in       # optional, if using pip-tools
├─ requirements.txt
├─ pyproject.toml        # optional (metadata, build-system)
├─ .gitignore
└─ README.md

.gitignore snippet:

.venv/
__pycache__/
*.pyc
*.egg-info/

8) Using venv with common tools

VS Code

  • Open the project folder.
  • VS Code usually auto-detects .venv. If not:
    Cmd/Ctrl+Shift+P → Python: Select Interpreter → choose ./.venv/bin/python (macOS/Linux) or .venv\Scripts\python.exe (Windows).

PyCharm

  • Settings → Project → Python Interpreter → Add → Existing environment and point to the .venv interpreter.

Pre-commit (quality gates)

pip install pre-commit
pre-commit install
# .pre-commit-config.yaml controls hooks like black, isort, flake8, mypy

9) Reproducible workflows (Makefile examples)

.PHONY: venv install lock test clean

venv:
	python3.11 -m venv .venv
	./.venv/bin/python -m pip install --upgrade pip

install:
	./.venv/bin/pip install -r requirements.txt

lock:
	./.venv/bin/pip install pip-tools
	./.venv/bin/pip-compile requirements.in
	./.venv/bin/pip-sync

test:
	./.venv/bin/python -m pytest -q

clean:
	rm -rf .venv __pycache__ .pytest_cache

On Windows, replace path separators accordingly or use powershell scripts.


10) CI and Docker

CI (GitHub Actions gist)

- uses: actions/setup-python@v5
  with:
    python-version: '3.11'
- run: python -m venv .venv
- run: . .venv/bin/activate && pip install -r requirements.txt && pytest -q
  shell: bash

Docker interplay

You generally don’t need venv inside containers because the container is already isolated. Two patterns:

  • No venv (common):
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "-m", "your_package"]
  • With venv (optional; keeps global Python clean in the image):
FROM python:3.11-slim
WORKDIR /app
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "-m", "your_package"]

11) Common pitfalls & fixes

  1. Using system pip by accident
    • Symptom: installs “work” but code can’t import in venv.
    • Fix: ensure activation; verify with which python (Unix) or where python (Windows). Or call ./.venv/bin/python -m pip ... explicitly.
  2. “pip not found” after creating venv
    • Fix: python -m ensurepip --upgrade or upgrade pip inside the venv.
  3. Wrong Python version in venv
    • Fix: create the venv with the exact interpreter you want (e.g., python3.11 -m venv .venv).
  4. Mixing global and local installs
    • Fix: never use sudo pip or pip --user while in a venv.
  5. Cross-platform line endings or path issues
    • Fix: prefer invoking via python -m where possible; keep scripts simple.
  6. Forgetting to pin
    • Fix: maintain requirements.txt (or pip-tools) and re-lock periodically.

12) Handy commands cheat-sheet

Create:

python -m venv .venv

Activate:

# macOS/Linux
source .venv/bin/activate

# Windows
.\.venv\Scripts\activate

Initial deps:

pip install -r requirements.txt

Freeze:

pip freeze > requirements.txt

Exact interpreter invocation (no activate required):

./.venv/bin/python -m pip install rich        # macOS/Linux
.\.venv\Scripts\python -m pip install rich    # Windows

Remove the environment:

rm -rf .venv        # macOS/Linux
rmdir /s /q .venv   # Windows (PowerShell: Remove-Item -Recurse -Force .venv)

13) FAQ

Q: Do I need one venv per project?
A: Yes—treat it as project state. Delete/recreate freely.

Q: Should I commit .venv to git?
A: No. Commit a lock file (e.g., requirements.txt) instead.

Q: Can I share the same venv across multiple projects?
A: Avoid that. It defeats isolation and causes version conflicts.

Q: Is conda the same as venv?
A: Different toolchain. conda manages both Python and native packages. venv is standard library, lightweight, great for pure-Python or pip-installable projects.


This shows the exact steps from cloning the repo to running it inside a virtual environment with its dependencies installed.

Step-by-Step Walkthrough

1. Clone the repository

First, clone the GitHub project to your machine:

git clone https://github.com/ArgeliusLabs/Chasing-Your-Tail-NG.git

Move into the project folder:

cd Chasing-Your-Tail-NG

2. Create a virtual environment

Inside the repo directory, create a virtual environment. Conventionally, call it .venv:

python3 -m venv .venv

This creates a .venv/ folder containing a Python interpreter and isolated site-packages.


3. Activate the virtual environment

Activate it so the local Python and pip are used:

macOS/Linux:

source .venv/bin/activate

Windows (PowerShell):

.\.venv\Scripts\Activate

You should see (.venv) in your shell prompt.


4. Install dependencies

Most Python repos list dependencies in a requirements.txt file. From a quick glance at this project’s GitHub repo, it does include one.

Run:

pip install --upgrade pip
pip install -r requirements.txt

This installs everything the project needs inside the .venv.


5. Verify installation

Check installed packages:

pip list

Confirm Python executable is from .venv:

which python   # macOS/Linux
where python   # Windows

It should point to .../Chasing-Your-Tail-NG/.venv/....


6. Run or explore the project

The project readme should contain run instructions. If it uses an entry script, you’d run it like:

python main.py

or for a package layout:

python -m chasingyourtail

Clean Exit

When done, deactivate the venv:

deactivate

That’s the typical flow:

  1. git clone
  2. cd into repo
  3. python -m venv .venv
  4. source .venv/bin/activate
  5. pip install -r requirements.txt
  6. Run the project

Stay In Touch.

Let's Get Creative.