python-decouple
python-decouple provides a clean, strict separation of configuration settings from code, inspired by The Twelve-Factor App methodology. It allows you to store parameters in environment variables, `.env` files, or `settings.ini` files, making it easy to manage different environments (development, staging, production). The current version is 3.8, and it sees active maintenance with minor releases typically a few times a year addressing bug fixes and minor improvements.
Warnings
- breaking In `v3.8`, accessing keys that are not found within INI repositories will now strictly raise a `KeyError` by default, rather than silently failing or returning `None`.
- gotcha If a setting is not found in any repository (environment variables, `.env`, `settings.ini`) and no `default` value is provided, `config()` will raise an `UndefinedValueError`. This is a core design principle of `decouple` to ensure strictness.
- gotcha The `Csv` cast function (or any custom cast that splits a string) when used with `default=None` in `v3.6` and earlier could result in an infinite hang. This was fixed in `v3.7`.
- gotcha python-decouple loads settings in a specific order of precedence: Environment variables take highest priority, followed by `.env` files, and then `settings.ini` files. If a setting is defined in multiple places, the one with higher precedence will be used.
Install
-
pip install python-decouple
Imports
- config
from decouple import config
- AutoConfig
from decouple import AutoConfig
Quickstart
import os
from decouple import config
# Create a dummy .env file for demonstration
with open('.env', 'w') as f:
f.write('DATABASE_URL=postgres://user:pass@host:5432/dbname\n')
f.write('DEBUG=True\n')
f.write('SECRET_KEY="my_secret_key"\n')
f.write('ALLOWED_HOSTS=localhost,127.0.0.1\n')
# Read a setting from .env or environment variable
db_url = config('DATABASE_URL')
print(f"Database URL: {db_url}")
# Read a boolean setting, casting it
debug = config('DEBUG', cast=bool)
print(f"Debug mode: {debug} (type: {type(debug)})")
# Read a string with a default value if not found
api_key = config('API_KEY', default='default_api_key')
print(f"API Key: {api_key}")
# Read a list using Csv cast
hosts = config('ALLOWED_HOSTS', cast=lambda v: v.split(','))
print(f"Allowed Hosts: {hosts} (type: {type(hosts)})")
# Clean up the dummy .env file
os.remove('.env')