Python shows up in DevOps as the glue between CLIs — automation scripts, Lambda handlers, Ansible modules, CI tooling. This page covers the environment and stdlib patterns you reach for constantly, not the language itself.
Version & REPL
python3 --versionPrints the installed Python version.
python3 -m venv .venvCreates an isolated virtual environment in .venv, so project dependencies don't leak into or clash with the system Python.
source .venv/bin/activateActivates a virtual environment in the current shell — installed packages and the python/pip commands now resolve inside it.
deactivateExits the active virtual environment, returning to the system (or previously active) Python.
Packaging (pip)
pip install requestsInstalls a package into the active environment.
pip install -r requirements.txtInstalls every package pinned in a requirements file.
pip freeze > requirements.txtWrites every installed package and its exact version to a requirements file, for a reproducible environment.
pip list --outdatedShows installed packages that have a newer version available.
Pin your dependencies
pip freeze output pins exact versions transitively too — commit it for applications (reproducibility) but use
looser ranges in a library's own pyproject.toml so it doesn't force conflicting pins on whoever depends on it.
Running Scripts
python3 script.pyRuns a script with the active interpreter.
python3 -m module_nameRuns an installed module as a script — resolves via sys.path rather than a file path, and is how you invoke most CLI tools distributed as Python packages (python3 -m pytest, python3 -m http.server).
python3 -c 'import sys; print(sys.path)'Runs a one-line inline script — handy for quick checks without a file.
Formatting & Linting
black .Auto-formats every Python file in the current directory to a consistent style.
ruff check .Lints the codebase for errors and style issues; fast enough to run on every save or in CI without noticeable delay.
mypy .Type-checks the codebase against its type hints, catching a class of bugs before runtime.
Working with Files
from pathlib import Path
for path in Path("/var/log/app").glob("*.log"):
if path.stat().st_size > 100_000_000:
print(f"{path}: {path.stat().st_size / 1e6:.1f} MB")import json
with open("config.json") as f:
config = json.load(f)
config["retries"] = 3
with open("config.json", "w") as f:
json.dump(config, f, indent=2)Running Shell Commands (subprocess)
import subprocess
result = subprocess.run(
["kubectl", "get", "pods", "-o", "json"],
capture_output=True,
text=True,
check=True,
)
print(result.stdout)Avoid shell=True with untrusted input
subprocess.run(cmd, shell=True) passes the string through a real shell — if any part of cmd comes from
outside your own code (an argument, an API payload, an env var), that's a command injection vulnerability. Pass a
list of arguments (as above) instead; it never invokes a shell at all.
Environment Variables & Args
import os
import argparse
api_key = os.environ["API_KEY"] # raises KeyError if unset — fail loudly on missing config
timeout = os.environ.get("TIMEOUT", "30") # falls back to a default instead
parser = argparse.ArgumentParser()
parser.add_argument("--env", required=True, choices=["dev", "staging", "prod"])
parser.add_argument("--dry-run", action="store_true")
args = parser.parse_args()Virtual Environments vs. Docker
venv
Isolates Python packages only — same OS, same system libraries, same Python interpreter version as whatever's installed. Fast to create, cheap to throw away, but doesn't reproduce the runtime environment itself.
Docker
Isolates the entire runtime — OS packages, system libraries, and a pinned Python version, not just pip packages. The right choice once "works on my machine" needs to mean the OS layer too, not just dependencies.