CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-confuse

Painless YAML configuration library for Python applications with validation, type checking, and multi-source data merging

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

views.mddocs/

Views and Data Access

Dictionary-like interface for querying configuration data with support for nested access, type conversion, and validation. ConfigView provides the primary API for accessing configuration values with transparent type checking and error handling.

Capabilities

ConfigView Class

Base class for configuration queries that provides dictionary-like access with validation and type conversion capabilities.

class ConfigView:
    def get(self, template=REQUIRED):
        """
        Get configuration value with optional validation template.
        
        Parameters:
        - template: Type or Template object for validation/conversion
        
        Returns:
        Validated and converted configuration value
        
        Raises:
        - NotFoundError: If value is missing and required
        - ConfigTypeError: If value doesn't match expected type
        - ConfigValueError: If value is invalid
        """
    
    def exists(self):
        """
        Check if this configuration key exists in any source.
        
        Returns:
        bool: True if key exists, False otherwise
        """
    
    def first(self):
        """
        Get the first available value and its source.
        
        Returns:
        tuple: (value, source) pair
        
        Raises:
        - NotFoundError: If no value is found
        """
    
    def keys(self):
        """
        Get all available keys from all sources for this view.
        
        Returns:
        list: Available configuration keys
        
        Raises:
        - ConfigTypeError: If this view is not a dictionary
        """
    
    def items(self):
        """
        Get key-value pairs as (key, subview) tuples.
        
        Returns:
        list: Tuples of (key, ConfigView) pairs
        """
    
    def values(self):
        """
        Get all values as ConfigView objects.
        
        Returns:
        list: ConfigView objects for each value
        """
    
    def sequence(self):
        """
        Iterate over this view as a list.
        
        Returns:
        generator: ConfigView objects for each list item
        
        Raises:
        - ConfigTypeError: If this view is not a list
        """
    
    def set(self, value):
        """
        Override this configuration value with highest priority.
        
        Parameters:
        - value: New configuration value
        """
    
    def add(self, value):
        """
        Add a default value with lowest priority.
        
        Parameters:
        - value: Default configuration value
        """
    
    def set_args(self, namespace, dots=False):
        """
        Overlay parsed command-line arguments onto configuration.
        
        Parameters:
        - namespace: argparse.Namespace or dict with argument values
        - dots (bool): Split keys on dots to create nested structure
        """
    
    def all_contents(self):
        """
        Get all values from all sources for this view.
        
        Returns:
        generator: (value, source) tuples for all matching values
        """
    
    def flatten(self, redact=False):
        """
        Generate flat dictionary representation of configuration.
        
        Parameters:
        - redact (bool): Replace sensitive values with redaction placeholder
        
        Returns:
        dict: Flattened configuration with dot-separated keys
        """
    
    def set_redaction(self, path, flag):
        """
        Mark a configuration path as sensitive for redaction.
        
        Parameters:
        - path (str): Configuration path (e.g., 'database.password')
        - flag (bool): Whether to redact this path
        """
    
    def get_redactions(self):
        """
        Get dictionary of redaction flags for configuration paths.
        
        Returns:
        dict: Mapping of paths to redaction flags
        """
    
    def resolve(self):
        """
        Generate all (value, source) pairs for this view from all sources.
        
        Returns:
        generator: (value, ConfigSource) tuples in priority order
        """
    
    def root(self):
        """
        Get the root ConfigView for this view hierarchy.
        
        Returns:
        RootView: Root view containing all configuration sources
        """
    
    def __iter__(self):
        """
        Iterate over configuration keys or sequence items.
        
        Returns:
        generator: Keys for mappings or ConfigView objects for sequences
        """
    
    def __contains__(self, key):
        """
        Check if key exists in configuration.
        
        Parameters:
        - key: Key to check for existence
        
        Returns:
        bool: True if key exists in any source
        """
    
    def __getitem__(self, key):
        """
        Access nested configuration via subscript notation.
        
        Parameters:
        - key: Dictionary key or list index
        
        Returns:
        Subview: ConfigView for the nested configuration item
        """
    
    def __setitem__(self, key, value):
        """
        Set nested configuration value via subscript notation.
        
        Parameters:
        - key: Dictionary key or list index
        - value: Value to set
        """
    
    def __str__(self):
        """
        Get string representation of configuration value.
        
        Returns:
        str: String representation of the first available value
        """
    
    def __bool__(self):
        """
        Check if this configuration view has any values.
        
        Returns:
        bool: True if any sources contain values for this view
        """

Type Conversion Methods

Convenience methods for common type conversions with built-in validation.

class ConfigView:
    def as_str(self):
        """
        Get value as string.
        
        Returns:
        str: String representation of value
        """
    
    def as_str_expanded(self):
        """
        Get value as string with environment variable expansion.
        
        Returns:
        str: String with $VAR and ${VAR} expanded
        """
    
    def as_filename(self):
        """
        Get value as validated filename with path resolution.
        
        Returns:
        str: Absolute path to file
        """
    
    def as_path(self):
        """
        Get value as pathlib.Path object.
        
        Returns:
        pathlib.Path: Path object for the file
        """
    
    def as_number(self):
        """
        Get value as numeric type (int or float).
        
        Returns:
        int or float: Numeric value
        """
    
    def as_choice(self, choices):
        """
        Get value validated against list of choices.
        
        Parameters:
        - choices: Sequence of valid values or Enum class
        
        Returns:
        Validated choice value
        """
    
    def as_str_seq(self, split=True):
        """
        Get value as list of strings.
        
        Parameters:
        - split (bool): Split single strings on whitespace
        
        Returns:
        list: List of string values
        """
    
    def as_pairs(self, default_value=None):
        """
        Get value as list of key-value pairs.
        
        Parameters:
        - default_value: Default value for keys without explicit values
        
        Returns:
        list: List of (key, value) tuples
        """

Subview Access

Accessing nested configuration data through subscript notation and attribute-style access.

class Subview(ConfigView):
    def __init__(self, parent, key):
        """
        Create a subview for accessing nested configuration data.
        
        Parameters:
        - parent (ConfigView): Parent view object
        - key: Dictionary key or list index for access
        """

Usage Examples

Basic Value Access

import confuse

config = confuse.Configuration('myapp')

# Dictionary-style access
database_host = config['database']['host'].get(str)
port = config['database']['port'].get(int)

# Check if key exists
if config['debug'].exists():
    debug_mode = config['debug'].get(bool)

# Get with default using template
timeout = config['timeout'].get(confuse.Number(30.0))

Type Conversion

import confuse

config = confuse.Configuration('myapp')

# Basic type conversions
name = config['app_name'].as_str()
count = config['worker_count'].as_number()
config_file = config['config_path'].as_filename()
output_dir = config['output_dir'].as_path()

# String expansion with environment variables
expanded_path = config['data_path'].as_str_expanded()  # Expands $HOME/data

# Choice validation
log_level = config['log_level'].as_choice(['DEBUG', 'INFO', 'WARNING', 'ERROR'])

# List of strings
plugins = config['plugins'].as_str_seq()  # ['plugin1', 'plugin2']
keywords = config['keywords'].as_str_seq(split=True)  # 'foo bar' -> ['foo', 'bar']

Dictionary and List Access

import confuse

config = confuse.Configuration('myapp')

# Iterate over dictionary keys
for key in config['servers']:
    server_config = config['servers'][key]
    print(f"Server {key}: {server_config['host'].as_str()}")

# Get all keys and values
server_keys = config['servers'].keys()
server_views = config['servers'].values()

# Iterate over list items
for server_view in config['server_list'].sequence():
    hostname = server_view['hostname'].as_str()
    port = server_view['port'].as_number()
    print(f"Server: {hostname}:{port}")

# List iteration with index access
servers = config['servers']
for i, server_view in enumerate(servers):
    print(f"Server {i}: {server_view.get(str)}")

Command-Line Integration

import confuse
import argparse

config = confuse.Configuration('myapp')

# Parse command-line arguments
parser = argparse.ArgumentParser()
parser.add_argument('--host', default='localhost')
parser.add_argument('--port', type=int, default=8080)
parser.add_argument('--database-url', dest='database.url')
parser.add_argument('--verbose', action='store_true')

args = parser.parse_args()

# Overlay arguments onto configuration
config.set_args(args, dots=True)  # Split 'database.url' into nested structure

# Access merged configuration
host = config['host'].as_str()  # From args or config file
port = config['port'].as_number()  # From args or config file
db_url = config['database']['url'].as_str()  # From --database-url

Error Handling

import confuse

config = confuse.Configuration('myapp')

try:
    # This will raise NotFoundError if 'required_setting' is missing
    value = config['required_setting'].get(str)
except confuse.NotFoundError:
    print("Required setting is missing from configuration")

try:
    # This will raise ConfigTypeError if value is not an integer
    count = config['item_count'].get(int)
except confuse.ConfigTypeError as e:
    print(f"Invalid type for item_count: {e}")

try:
    # This will raise ConfigValueError for invalid values
    level = config['log_level'].as_choice(['DEBUG', 'INFO', 'WARNING', 'ERROR'])
except confuse.ConfigValueError as e:
    print(f"Invalid log level: {e}")

Complex Data Structures

import confuse

config = confuse.Configuration('myapp')

# Working with nested dictionaries
database_config = config['database']
if database_config.exists():
    # Get individual values
    host = database_config['host'].as_str()
    port = database_config['port'].as_number()
    ssl_enabled = database_config['ssl'].get(bool)
    
    # Check for optional nested values
    if database_config['connection_pool'].exists():
        max_connections = database_config['connection_pool']['max_size'].get(int)

# Working with lists of dictionaries
for server in config['servers'].sequence():
    hostname = server['hostname'].as_str()
    options = server['options'].as_str_seq()
    print(f"Server {hostname} with options: {options}")

# Key-value pair processing
pairs = config['environment'].as_pairs()
for key, value in pairs:
    print(f"Environment: {key}={value}")

View State and Manipulation

import confuse

config = confuse.Configuration('myapp')

# Set values at runtime
config['debug'] = True
config.set({'logging': {'level': 'DEBUG', 'format': 'detailed'}})

# Add default values (lowest priority)
config.add({'timeout': 30, 'retries': 3})

# Set nested values
config['database']['host'] = 'production.db.example.com'

# Check current configuration state
all_keys = list(config.keys())
has_database = 'database' in config
database_exists = config['database'].exists()

Redaction and Sensitive Data

import confuse

config = confuse.Configuration('myapp')
config.set({'database': {'password': 'secret123', 'host': 'localhost'}})

# Mark sensitive paths for redaction
config.set_redaction('database.password', True)
config.set_redaction('api_key', True)

# Get flat configuration with redaction
flat_config = config.flatten(redact=True)
print(flat_config)  # {'database.password': 'REDACTED', 'database.host': 'localhost'}

# Get redaction settings
redactions = config.get_redactions()
print(redactions)  # {'database.password': True, 'api_key': True}

# Iterate over all configuration values and sources
for value, source in config.all_contents():
    print(f"Value: {value}, Source: {source.filename}")

Install with Tessl CLI

npx tessl i tessl/pypi-confuse

docs

configuration.md

index.md

sources.md

templates.md

views.md

tile.json