Confuse Configuration Library
Confuse is a Python configuration library that simplifies handling YAML-based settings for applications. It provides features like layered overrides, transparent type checking, integration with command-line arguments and environment variables, and automatic discovery of configuration files in OS-specific locations. The current version is 2.2.0, and the project maintains an active release cadence.
Warnings
- breaking Confuse v2.2.0 dropped support for Python 3.9. Projects using Python 3.9 or older must either stick to an earlier `confuse` version or upgrade their Python interpreter.
- breaking Since `confuse` v1.3.0, using `None` as a template for a configuration value (e.g., `config['key'].get(None)`) now sets the default to `None`. Previously, it was equivalent to having no default, making the key implicitly required. For explicitly required values without a default, use `confuse.REQUIRED`.
- gotcha Accessing configuration values directly (e.g., `config['key']`) returns a 'view' object, not the resolved value. To retrieve the actual value and apply validation/defaults, you must call the `.get()` method on the view (e.g., `config['key'].get(str)`). Forgetting `.get()` is a common mistake.
- gotcha Confuse resolves relative paths differently based on their source. Relative paths specified in config files are by default resolved relative to the application's configuration directory, while those from command-line options are relative to the current working directory. This can lead to unexpected path resolution if not explicitly handled, for instance, using `Filename` templates with `relative_to`, `in_app_dir`, or `in_source_dir` parameters.
- gotcha When defining templates for sequence validation, providing a Python list directly to `.get()` (e.g., `config.get([str])`) creates a `confuse.OneOf` template, not a `confuse.Sequence` template. This means it expects the *value itself* to match one of the types in the list, not that the value is a sequence of those types.
Install
-
pip install confuse
Imports
- Configuration
from confuse import Configuration
- LazyConfig
from confuse import LazyConfig
Quickstart
import confuse
import os
# Simulate a config_default.yaml in your package for defaults
# For this example, we'll create a dummy file for demonstration
# In a real app, this would be alongside your module, e.g., myapp/config_default.yaml
with open('config_default.yaml', 'w') as f:
f.write('greeting: Hello
name: World
port: 8080
enabled: true')
class MyAppConfig(confuse.Configuration):
# Override config_dir to point to current directory for this example
# In a real app, this would typically resolve OS-specific paths.
def config_dir(self):
return os.getcwd()
# Initialize configuration for 'MyGreatApp'
# __name__ is used by Confuse to find in-package config_default.yaml
config = MyAppConfig('MyGreatApp', __name__)
# Load environment variables with default prefix 'MYGREATAPP_'
# For example, export MYGREATAPP_NAME="Confuse User"
# and MYGREATAPP_PORT=9000
config.set_env()
# Get values, validating types
greeting = config['greeting'].get(str)
name = config['name'].get(str)
port = config['port'].get(int)
is_enabled = config['enabled'].get(bool)
print(f"Greeting: {greeting}")
print(f"Name: {name}")
print(f"Port: {port}")
print(f"Enabled: {is_enabled}")
# Test an environment variable override
os.environ['MYGREATAPP_NAME'] = 'AI Assistant'
os.environ['MYGREATAPP_PORT'] = '9001'
# Reload env vars to pick up changes
config.set_env()
print(f"\nAfter env var override:")
print(f"Name: {config['name'].get(str)}")
print(f"Port: {config['port'].get(int)}")
# Clean up dummy file
os.remove('config_default.yaml')