Environment Variables in Python
Using os.environ and python-dotenv
Reading Environment Variables
Python provides environment variable access through the os module. The os.environmapping contains all environment variables as strings. Use dictionary-style access or the os.getenv()function:
import os
# Raises KeyError if not set
db_url = os.environ['DATABASE_URL']
# Returns None if not set (or a default)
log_level = os.getenv('LOG_LEVEL', 'info')
# Check if a variable exists
if 'API_KEY' in os.environ:
api_key = os.environ['API_KEY']The difference between os.environ['KEY'] and os.getenv('KEY') is error handling: the former raises KeyError for missing variables, while the latter returns None(or your default). Use os.environ[] for required variables and os.getenv() for optional ones.
Setting Environment Variables
Set variables in the shell before running your script, or modify os.environ at runtime:
# Shell
export DATABASE_URL=postgres://localhost/mydb
python app.py
# In Python
os.environ['MY_VAR'] = 'value'
del os.environ['MY_VAR'] # Remove a variablePopular Libraries
python-dotenv loads variables from a .env file into os.environ. Call load_dotenv() at the start of your application:
from dotenv import load_dotenv
load_dotenv() # loads .env from current directory
db_url = os.getenv('DATABASE_URL')pydantic-settings (part of the Pydantic ecosystem) provides typed, validated settings classes that read from environment variables automatically:
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
database_url: str
port: int = 3000
debug: bool = False
class Config:
env_file = '.env'
settings = Settings()
# settings.database_url is validated and typedenvirons is a simpler alternative that provides type casting and validation without needing a full settings class.
Common Gotchas
- All environment variable values are strings. You must explicitly cast to
int,float, orbool. Be careful with boolean parsing —bool('false')returnsTruein Python because it is a non-empty string. os.environis a mutable mapping. Changes persist for the lifetime of the process and are inherited by child processes, but do not affect the parent shell.- In Django, environment variables are commonly used in
settings.py. Make sureload_dotenv()runs before Django imports settings, typically inmanage.pyorwsgi.py.