You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

wl-config-manager

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

wl-config-manager

A flexible configuration manager for Python applications with .env support

0.1.43
pipPyPI
Maintainers
1

WL Config Manager

A flexible configuration manager for Python applications that supports multiple file formats, environment variable overrides, and dot notation access.

Features

  • Multiple Formats - YAML, JSON, and INI configuration files
  • Dot Notation - Access nested values with config.server.port
  • Environment Variables - Override config values with environment variables
  • Default Values - Built-in defaults with easy overrides
  • File Search - Automatically find config files in standard locations
  • Validation - Ensure required keys are present
  • CLI Tool - Command-line interface for config manipulation
  • Type Conversion - Automatic type conversion for environment variables
  • Live Reload - Reload configuration without restarting

Installation

pip install wl-config-manager

Dependencies

  • wl_version_manager
  • pyyaml>=5.1

Quick Start

Basic Usage

from wl_config_manager import ConfigManager

# Load config from file
config = ConfigManager(config_path="config.yaml")

# Access values with dot notation
port = config.server.port
debug = config.app.debug

# Or use get() method
database_url = config.get("database.url", default="sqlite:///app.db")

Configuration File Example

# config.yaml
app:
  name: "My Application"
  debug: false
  version: "1.0.0"

server:
  host: "0.0.0.0"
  port: 8080
  workers: 4

database:
  url: "postgresql://localhost/myapp"
  pool_size: 10
  echo: false

logging:
  level: "INFO"
  format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"

Configuration Loading

Search Paths

If no config path is specified, the manager searches these locations in order:

from wl_config_manager import ConfigManager, DEFAULT_SEARCH_PATHS

# Default search paths on Fedora/CentOS:
# - ~/.config/
# - /etc/
# - /etc/app/
# - current working directory

# Use default search paths
config = ConfigManager(search_paths=DEFAULT_SEARCH_PATHS)

# Or specify custom search paths
config = ConfigManager(search_paths=["/opt/myapp", "/etc/myapp"])

File Formats

The format is auto-detected by file extension, or can be specified:

# Auto-detect format
config = ConfigManager(config_path="settings.json")  # JSON
config = ConfigManager(config_path="app.ini")       # INI
config = ConfigManager(config_path="config.yaml")   # YAML

# Explicitly specify format
config = ConfigManager(config_path="myconfig", format="yaml")

Environment Variable Overrides

Override configuration values using environment variables:

# Configure with env prefix
config = ConfigManager(
    config_path="config.yaml",
    env_prefix="MYAPP_"
)

# Environment variables override config file values
# MYAPP_SERVER__PORT=9000 overrides server.port
# MYAPP_APP__DEBUG=true overrides app.debug
# MYAPP_DATABASE__URL=postgres://prod-server/db overrides database.url

Environment variable rules:

  • Prefix + double underscore (__) for nested values
  • Values are automatically converted to appropriate types (bool, int, float, string)
  • Case-insensitive (environment vars are converted to lowercase)

Default Configuration

Provide default values that are used if not found in config file or environment:

default_config = {
    "app": {
        "name": "DefaultApp",
        "debug": False
    },
    "server": {
        "port": 8080,
        "host": "localhost"
    }
}

config = ConfigManager(
    config_path="config.yaml",
    default_config=default_config
)

Validation

Ensure required configuration keys are present:

# Validate required keys
config = ConfigManager(
    config_path="config.yaml",
    required_keys=["app.name", "server.port", "database.url"]
)
# Raises ConfigValidationError if any required keys are missing

Accessing Configuration Values

Dot Notation Access

# Direct attribute access
app_name = config.app.name
port = config.server.port

# Nested access
log_level = config.logging.level

# Safe access with get()
smtp_host = config.get("email.smtp.host", default="localhost")

# Get entire sections
server_config = config.server  # Returns namespace object
server_dict = config.get("server")  # Returns dict

Dictionary-like Access

# The configuration objects support dict-like operations
if "debug" in config.app:
    print(f"Debug mode: {config.app.debug}")

# Iterate over sections
for section, values in config:
    print(f"{section}: {values}")

# Get items from a section
for key, value in config.items("server"):
    print(f"{key} = {value}")

Modifying Configuration

Set Values

# Set single value
config.set("app.version", "2.0.0")
config.set("server.port", 9000)

# Create nested structures
config.set("new_feature.enabled", True)
config.set("new_feature.options.timeout", 30)

# Update multiple values
config.update({
    "version": "2.0.0",
    "debug": True
})

# Update with prefix
config.update({"port": 9000, "workers": 8}, prefix="server")

Save Configuration

# Save to original file
config.save()

# Save to different file
config.save("new_config.yaml")

# Save in different format
config.save("config.json")  # Auto-converts to JSON

Advanced Usage

Reload Configuration

# Reload from source file (picks up external changes)
config.reload()

Create from Dictionary

config_dict = {
    "app": {"name": "MyApp"},
    "server": {"port": 8080}
}

config = ConfigManager.from_dict(config_dict)

Create from Environment Only

# Load configuration entirely from environment variables
config = ConfigManager.from_env("MYAPP_")

Logging Configuration

# Set logging level for config manager
config = ConfigManager(
    config_path="config.yaml",
    log_level=logging.DEBUG  # See config loading details
)

# Set up file logging
from wl_config_manager import setup_file_logging

setup_file_logging(
    log_dir="/var/log",
    app_name="myapp",
    log_level=logging.INFO
)

Command Line Interface

The package includes a CLI tool for managing configurations:

View Configuration

# Get entire config
wl_config_manager get config.yaml

# Get specific value
wl_config_manager get config.yaml server.port

# Get with default
wl_config_manager get config.yaml app.missing --default="not found"

# Output as JSON
wl_config_manager get --format=json config.yaml

Modify Configuration

# Set values
wl_config_manager set config.yaml app.debug true
wl_config_manager set config.yaml server.port 9000

# Create new config file
wl_config_manager create --format=yaml new_config.yaml

# Create from template
wl_config_manager create --template=default.yaml --vars='{"app":{"name":"MyApp"}}' config.yaml

Validate Configuration

# Check required keys
wl_config_manager validate --required=app.name,server.port config.yaml

Convert Formats

# Convert between formats
wl_config_manager convert config.ini config.yaml
wl_config_manager convert settings.yaml settings.json

List Configuration

# List all values
wl_config_manager list config.yaml

# List section only
wl_config_manager list config.yaml --section=server

Environment Variables

# Show config from environment variables
wl_config_manager env MYAPP_ --format=json

Error Handling

The module provides specific exceptions for different error types:

from wl_config_manager import (
    ConfigError,           # Base exception
    ConfigFileError,       # File not found/readable
    ConfigFormatError,     # Invalid file format
    ConfigValidationError  # Validation failures
)

try:
    config = ConfigManager(config_path="config.yaml")
except ConfigFileError as e:
    print(f"Config file error: {e}")
    print(f"File path: {e.file_path}")
except ConfigValidationError as e:
    print(f"Validation error: {e}")
    print(f"Missing keys: {e.get_missing_keys()}")

Best Practices

  • Use Environment Variables for Secrets

    export MYAPP_DATABASE__PASSWORD="secret"
    export MYAPP_API__KEY="secret-key"
    
  • Provide Sensible Defaults

    default_config = {
        "server": {"port": 8080, "host": "0.0.0.0"},
        "logging": {"level": "INFO"}
    }
    
  • Validate Critical Configuration

    required_keys = ["database.url", "app.secret_key"]
    config = ConfigManager(required_keys=required_keys)
    
  • Use Type Hints with Config Objects

    from typing import TYPE_CHECKING
    if TYPE_CHECKING:
        from types import SimpleNamespace
    
    def setup_server(server_config: SimpleNamespace):
        port = server_config.port
        host = server_config.host
    

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Keywords

configuration config yaml json ini environment variables dotenv env settings

FAQs

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts