Python venv Environments¶
This page covers Python's standard-library venv module.
Applied Project¶
Project Setup¶
The applied project is a small utility library called PyGuard Project. It blocks suspicious web requests before they reach application handlers without any runtime dependencies beyond the Python standard library. This makes it a good fit for venv because a pure-Python library shows clearly how one project-local environment can isolate build and development tools while keeping the installed package itself lightweight.
For a hands-on introduction to the environment itself, see The Isolation Awakens and its setup instructions.
Run the Project¶
Application, lint, build, and shell-exit commands are documented in the section README.
venv Environment Model¶
venv has shipped with Python since Python 3.3 in 2012, when it was introduced to give Python a standard built-in tool for project-level isolation. It creates a project-local directory with a private interpreter, pip, a package directory, console scripts, and a pyvenv.cfg file, while activation is mostly a PATH change so the environment-local interpreter resolves first even though the standard library still comes from the base Python installation. Treat that .venv/ directory as disposable rather than movable: virtual environments often record absolute paths, so rebuilding from dependency files is safer than relocating the environment directory byte-for-byte.
When to Use venv?¶
Because it is built in, lightweight, and close to standard Python packaging, venv is a good default for small web services, command-line tools, tutorials, libraries, and scripts whose dependencies come cleanly from PyPI. It is also a good fit when you want to inspect Python's environment mechanics directly.
Tradeoffs¶
Pros¶
- ✅ Bundled with Python
- ✅ Familiar to most Python users.
- ✅ Lightweight folder-based environment that is easy to inspect and remove.
- ✅ Clear
PATHandsys.pathbehavior once the environment is activated.
Cons¶
- ⚠️ Does not manage Python versions by itself.
- ⚠️ Cannot install non-Python system libraries (e.g. compiler toolchains, etc.)
- ⚠️ Does not manage dependencies or reproducible installs by itself
- ⚠️ Zero portability once created (paths are hardcoded)
Install venv¶
venv is bundled with Python, so there is no separate PyPI package to install.
If venv support is absent, install the distribution-supported package with apt:
If Python is not installed yet, follow Install Python.
If Python is not installed yet, follow Install Python.
Environment Layout¶
Environment Definition¶
The project declares its package metadata and development dependencies in its
pyproject.toml. The file is the source of truth for the package name, supported
Python versions, build backend, runtime dependencies, and development dependency
group. Creating .venv/ supplies the isolated interpreter, while pip or uv
reads this file when the project is installed.
[project]
name = "pyguard"
requires-python = ">=3.9"
dependencies = []
[dependency-groups]
dev = ["karva>=0.0.1a5", "ruff>=0.15.12"]
Key Directories and Files¶
The exact directory names vary by operating system, but each venv still contains an environment-local interpreter, console scripts, a package directory, headers, and pyvenv.cfg.
-
Executable directory: on Linux and macOS,
.venv/bin/contains the virtual environment's Python executables,pip, and shell activation scripts. On Windows, the equivalent directory is.venv\Scripts\, which holdspython.exe,pip.exe, and activation scripts such asActivate.ps1andactivate.bat. On Linux, a freshvenvcommonly uses symlinks for the Python executables, so the environment-localpython3can still point back to the base interpreter while the surrounding environment changes where packages and scripts are installed.Inspect the executable directory:
A shortened output focused on the executable entries looks like this:
-rwxr-xr-x 1 user user 253 May 9 05:46 pip -rwxr-xr-x 1 user user 253 May 9 05:46 pip3 -rwxr-xr-x 1 user user 253 May 9 05:46 pip3.12 lrwxrwxrwx 1 user user 7 May 9 05:46 python -> python3 lrwxrwxrwx 1 user user 16 May 9 05:46 python3 -> /usr/bin/python3 lrwxrwxrwx 1 user user 7 May 9 05:46 python3.12 -> python3The arrows show the redirect chain.
pythonpoints topython3,python3.12points topython3, andpython3points to the base interpreter at/usr/bin/python3. -
Header directory: Linux and macOS store headers under
.venv/include/python3.x/, while Windows uses.venv\Include\. These headers are used when native extensions compile against the interpreter inside the virtual environment. -
Package directory: Linux and macOS store installed packages under
.venv/lib/python3.x/site-packages/, while Windows uses.venv\Lib\site-packages\. A fresh Python 3.xvenvtypically containspip/and its.dist-infometadata and no project dependencies yet. -
lib64/: is a platform-specific library alias that appears on some Linux systems. -
pyvenv.cfg: stores the base interpreter reference and flags such as whether system site-packages are visible. When you run the environment-localpython3, CPython reads this file early during startup. Thehomekey points back to the base Python installation that owns the standard library, whilesys.prefixandsys.exec_prefixare redirected to the local.venv/directory. Thecommandentry can also record the path used when the environment was created, which is one reason a copied or renamed.venv/can keep pointing at the original project location.A fresh
pyvenv.cfglooks like this:
Activation and Import Path¶
-
Environment-local interpreter: activation puts the virtual environment's executable directory at the front of
PATH. On Linux and macOS that means.venv/bin/; on Windows it means.venv\Scripts\. It does not change Python itself; it changes which executable the shell finds first when you runpython,python3,py, orpip. -
Environment-local packages: installed packages land under the environment-local
site-packagesdirectory, such as.venv/lib/python3.x/site-packages/on Linux or macOS and.venv\Lib\site-packages\on Windows. This keeps project dependencies separate from the base interpreter. A virtual environment does not replace the base standard library; it uses the base Python's standard library and puts the environment-local package directory ahead of any inherited package directories. -
System package visibility: with the default
include-system-site-packages = falsesetting inpyvenv.cfg, system-wide package directories are normally omitted. That is why avenvfeels isolated even though it still relies on the base standard library. -
Prefix inspection:
sys.prefixpoints at the virtual environment, whilesys.base_prefixstill points at the underlying system Python.
Development Workflow¶
The Dockerfile.devEnv image uses Ubuntu 24.04 with Python 3.12, python3-venv, unzip,
uv, and cloudsmith-cli, then copies the project into /app. Choose the workflow that
matches the state of the local mpe/proj1_pyguard image:
From the repository's projects/ directory, use build.sh to build and
open the dedicated PyGuard development container. The script mounts the
project at /app and its .build/ directory at /build for build
artifacts:
Create the Environment¶
Create the project environment from the project root. Choose uv for the
recommended workflow or venv + pip for the traditional workflow.
The following commands creates an in-project .venv, installs the project and
all of its depencencies defined in the pyproject.toml:
On later runs,
uv syncupdates the.venvand only creates it if missing.
Add Additional Packages¶
Add packages to the project environment and record them in pyproject.toml
when using uv:
Add the respective package to dependencies entry in the [project] table:
To synchronize an existing virtual environment with the definition file, update it from project root:
Run the Project¶
PyGuard is a library rather than a standalone command-line application. Use the project README for the middleware and FastAPI examples. After installation, verify that the package can be imported from the active environment:
Inspect the Environment¶
Show the active prefixes:
Show where installed packages live:
Show the folders where the interpreter imports the packages from