{"id":2902,"library":"confuse","title":"Confuse Configuration Library","description":"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.","status":"active","version":"2.2.0","language":"en","source_language":"en","source_url":"https://github.com/beetbox/confuse","tags":["configuration","yaml","config","settings"],"install":[{"cmd":"pip install confuse","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Requires Python 3.10 or higher.","package":"python","optional":false},{"reason":"Implicitly used for YAML parsing, though not a direct pip dependency.","package":"PyYAML","optional":false}],"imports":[{"note":"The primary class for managing application configuration.","symbol":"Configuration","correct":"from confuse import Configuration"},{"note":"Use for module-level configuration objects to defer parsing until needed, avoiding 'Bad Idea' of parsing at module load time.","symbol":"LazyConfig","correct":"from confuse import LazyConfig"}],"quickstart":{"code":"import confuse\nimport os\n\n# Simulate a config_default.yaml in your package for defaults\n# For this example, we'll create a dummy file for demonstration\n# In a real app, this would be alongside your module, e.g., myapp/config_default.yaml\nwith open('config_default.yaml', 'w') as f:\n    f.write('greeting: Hello\nname: World\nport: 8080\nenabled: true')\n\nclass MyAppConfig(confuse.Configuration):\n    # Override config_dir to point to current directory for this example\n    # In a real app, this would typically resolve OS-specific paths.\n    def config_dir(self):\n        return os.getcwd()\n\n# Initialize configuration for 'MyGreatApp'\n# __name__ is used by Confuse to find in-package config_default.yaml\nconfig = MyAppConfig('MyGreatApp', __name__)\n\n# Load environment variables with default prefix 'MYGREATAPP_'\n# For example, export MYGREATAPP_NAME=\"Confuse User\"\n# and MYGREATAPP_PORT=9000\nconfig.set_env()\n\n# Get values, validating types\ngreeting = config['greeting'].get(str)\nname = config['name'].get(str)\nport = config['port'].get(int)\nis_enabled = config['enabled'].get(bool)\n\nprint(f\"Greeting: {greeting}\")\nprint(f\"Name: {name}\")\nprint(f\"Port: {port}\")\nprint(f\"Enabled: {is_enabled}\")\n\n# Test an environment variable override\nos.environ['MYGREATAPP_NAME'] = 'AI Assistant'\nos.environ['MYGREATAPP_PORT'] = '9001'\n\n# Reload env vars to pick up changes\nconfig.set_env()\n\nprint(f\"\\nAfter env var override:\")\nprint(f\"Name: {config['name'].get(str)}\")\nprint(f\"Port: {config['port'].get(int)}\")\n\n# Clean up dummy file\nos.remove('config_default.yaml')","lang":"python","description":"This quickstart demonstrates how to initialize `confuse.Configuration`, load default settings from a `config_default.yaml` file, and apply overrides from environment variables. It also shows how to retrieve values with type validation using the `.get()` method."},"warnings":[{"fix":"Upgrade Python to 3.10+ or pin `confuse<2.2.0`.","message":"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.","severity":"breaking","affected_versions":">=2.2.0"},{"fix":"Replace `None` in templates where a required value without default is intended with `confuse.REQUIRED`.","message":"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`.","severity":"breaking","affected_versions":">=1.3.0"},{"fix":"Always append `.get()` when retrieving a configuration value from a view.","message":"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.","severity":"gotcha","affected_versions":"All"},{"fix":"Be explicit about path resolution using `confuse.Filename` templates and its parameters (`cwd`, `relative_to`, `in_app_dir`, `in_source_dir`) or ensure all paths are absolute.","message":"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.","severity":"gotcha","affected_versions":"All"},{"fix":"For a sequence of items, explicitly use `confuse.Sequence(str)` or the appropriate type, not `[str]`.","message":"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.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}