python-dotenv
Reads key-value pairs from .env files and sets them as environment variables — 12-factor app configuration pattern for Python. python-dotenv features: load_dotenv() to load .env into os.environ, dotenv_values() to load as dict without setting env vars, find_dotenv() to auto-locate .env up the directory tree, override= parameter to control whether existing env vars are overridden, dotenv_path parameter for explicit file path, Variable expansion (${OTHER_VAR}), comment support (#), multiline values with quotes, encoding parameter, and stream support for reading from file-like objects.
Score Breakdown
⚙ Agent Friendliness
🔒 Security
High-risk for secrets management if misused. CRITICAL: .env files containing API keys/passwords should NEVER be committed to git. Add .env to .gitignore. For production: use proper secrets management (AWS Secrets Manager, Vault, Kubernetes Secrets). python-dotenv is appropriate for development only. Logging os.environ after load_dotenv() can expose secrets — be careful with debug logging.
⚡ Reliability
Best When
Development environment configuration and 12-factor app patterns — python-dotenv is the standard for loading .env files in Python development.
Avoid When
Production secrets (use Vault/AWS Secrets Manager), complex typed config (use pydantic-settings), or when os.environ is already set by deployment infrastructure.
Use Cases
- • Agent load .env — from dotenv import load_dotenv; import os; load_dotenv(); api_key = os.getenv('API_KEY', 'default') — load env; agent loads .env file at startup; load_dotenv() is no-op if .env missing; os.getenv() with default for optional vars; call once at startup not per-request
- • Agent load as dict — from dotenv import dotenv_values; config = dotenv_values('.env'); config = dotenv_values('.env.test') — load as dict; agent loads .env without polluting os.environ; useful for testing or comparing environments; returns OrderedDict; missing file returns empty dict
- • Agent auto-find .env — from dotenv import load_dotenv, find_dotenv; load_dotenv(find_dotenv()) — find .env; agent finds .env by traversing parent directories from current file; find_dotenv(raise_error_if_not_found=True) raises IOError if not found; useful in nested project structures
- • Agent multiple environments — load_dotenv('.env.local', override=True) — environment override; agent loads environment-specific config; override=True replaces existing os.environ values; load_dotenv('.env') then load_dotenv('.env.local', override=True) for layered config; later load wins with override=True
- • Agent test isolation — from dotenv import dotenv_values; env = dotenv_values('.env.test'); with patch.dict(os.environ, env): run_tests() — test config; agent loads test-specific .env without modifying global environment; dotenv_values() as dict allows selective patching
Not For
- • Production secrets management — .env files in production are an anti-pattern; use AWS Secrets Manager, HashiCorp Vault, or Kubernetes secrets
- • Complex configuration schemas — dotenv is simple key=value only; for typed config with validation use pydantic-settings or dynaconf
- • Dynamic configuration — dotenv loads once at startup; for runtime config changes use a config server or environment-specific settings
Interface
Authentication
No auth — environment loading utility.
Pricing
python-dotenv is BSD 3-Clause licensed. Free for all use.
Agent Metadata
Known Gotchas
- ⚠ load_dotenv() does not override existing env vars by default — if API_KEY is already set in os.environ, load_dotenv() does NOT overwrite it; agent code relying on .env to override shell environment: use load_dotenv(override=True); this is intentional — shell environment takes precedence; useful for CI/CD where env is set externally
- ⚠ .env file must not be committed to git — agent code initializing repos: add .env to .gitignore immediately; .env.example should document required vars without values; agent reading required vars: check os.getenv('KEY') is not None and raise helpful error if missing rather than silently using None
- ⚠ Variable expansion uses ${VAR} syntax — BASE=/opt; FULL=${BASE}/sub in .env; python-dotenv expands ${BASE} to /opt; if BASE not defined, ${BASE} expands to empty string not error; agent code using expansion: test that dependent vars are defined before expansion; no circular expansion detection
- ⚠ load_dotenv() returns bool — load_dotenv() returns True if .env found and loaded, False if not found; agent code: result = load_dotenv(); if not result: logger.warning('.env not found — using environment variables'); use return value for diagnostic logging not silent failure
- ⚠ Multiline values require quotes — VALUE='line1\nline2' or VALUE="line1\nline2" in .env; unquoted values are single-line; actual newlines in unquoted values break parsing; agent code with multiline secrets (private keys): wrap in single or double quotes in .env file; or base64-encode them
- ⚠ dotenv_values() does NOT expand variables from os.environ — ${EXISTING_ENV_VAR} in .env file is expanded using values in .env only, not os.environ; agent code mixing dotenv and existing env vars: use load_dotenv() which does expand from os.environ; or merge manually: {**os.environ, **dotenv_values()}
Alternatives
Full Evaluation Report
Detailed scoring breakdown, competitive positioning, security analysis, and improvement recommendations for python-dotenv.
Scores are editorial opinions as of 2026-03-06.