os.environ behaves like a dictionary of the environment variables your program was started with.
import os os.environ["APP_MODE"] = "production" # pretend it was set outside Python print(os.environ.get("APP_MODE", "development")) print(os.environ.get("LOG_LEVEL", "INFO")) # not set, so the default
production INFO
Pick the form by asking "can the program work without this?"
- Optional setting with a sensible default:
os.environ.get("LOG_LEVEL", "INFO"). - Required, like a database URL or an API key:
os.environ["DATABASE_URL"]. If it's missing, you get aKeyErrorthe moment the program starts, which beats a confusing failure an hour later when the first query runs.
Every value is a string
The environment only holds text. A port, a timeout or a flag has to be converted, and booleans need care:
import os os.environ["PORT"] = "8080" os.environ["DEBUG"] = "false" port = int(os.environ.get("PORT", "8000")) debug = os.environ.get("DEBUG", "false").lower() in ("1", "true", "yes") print(port + 1) print(debug) print(bool("false")) # the trap: any non-empty string is True
8081 False True
bool(os.environ["DEBUG"]) is True for "false", "0" and "no", because they're all non-empty strings. Compare the text instead.
Setting one
On your own machine, set it in the terminal before starting Python:
# macOS / Linux export SHOP_API_KEY="sk-live-..." # Windows PowerShell $env:SHOP_API_KEY = "sk-live-..."
For a project, most people keep them in a .env file and load it with python-dotenv (pip install python-dotenv):
from dotenv import load_dotenv import os load_dotenv() # reads .env in the current folder api_key = os.environ["SHOP_API_KEY"]
Add .env to .gitignore before your first commit. A key that reaches GitHub has to be treated as stolen, even if you delete it a minute later; the secrets lesson covers what to do instead.