Config¶
Main Configuration Class¶
- class varlord.config.Config(model, sources, policy=None, show_source_help=True)[source]
Bases:
objectMain configuration manager.
Provides a unified interface for loading configuration from multiple sources with customizable priority ordering.
Example
>>> @dataclass ... class AppConfig: ... host: str = "127.0.0.1" ... port: int = 8000 ... >>> cfg = Config( ... model=AppConfig, ... sources=[ ... sources.Defaults(model=AppConfig), ... sources.Env(prefix="APP_"), ... sources.CLI(), # Model auto-injected ... ], ... ) >>> config = cfg.load() >>> print(config.host)
- __init__(model, sources, policy=None, show_source_help=True)[source]
Initialize Config.
- Parameters:
sources (list[Source]) – List of configuration sources (order determines priority: later sources override earlier ones)
policy (PriorityPolicy | None) – Optional PriorityPolicy for per-key priority rules
show_source_help (bool) – Whether to show source mapping help in errors (default: True)
- Raises:
varlord.exceptions.ModelDefinitionError – If any field is missing required/optional metadata
Note
Priority is determined by sources order: later sources override earlier ones
Use PriorityPolicy only when you need per-key priority rules
Model defaults are automatically applied as base layer (no need for Defaults source)
Model is automatically injected to all sources (no need to pass model to sources)
All fields MUST have explicit required/optional metadata
- classmethod from_model(model, cli=True, dotenv='.env', etcd=None, policy=None)[source]
Create Config with common sources (convenience method).
- Parameters:
cli (bool) – Whether to include CLI source
dotenv (str | None) – Path to .env file (None to disable)
etcd (dict | None) – Etcd configuration dict with keys: host, port, prefix, watch
policy (PriorityPolicy | None) – Optional PriorityPolicy for per-key priority rules
- Returns:
Config instance
- Return type:
Config
Note
Model defaults are automatically applied as base layer
Source priority order: Defaults (auto) < DotEnv < Env < Etcd < CLI
All sources are filtered by model fields
All fields MUST have explicit required/optional metadata
Example
>>> from dataclasses import dataclass, field >>> @dataclass ... class AppConfig: ... host: str = field(default="127.0.0.1", ) ... port: int = field(default=8000, ) >>> cfg = Config.from_model( ... AppConfig, ... cli=True, ... dotenv=".env", ... )
- validate(config_dict=None)[source]
Validate configuration.
- Parameters:
config_dict (dict[str, Any] | None) – Optional configuration dict to validate. If None, loads and validates current configuration.
- Raises:
varlord.exceptions.RequiredFieldError – If required fields are missing.
- handle_cli_commands()[source]
Handle CLI commands (–help/-h and –check-variables/-cv) using current config.
This method processes basic CLI commands based on the current configuration. It should be called once at program startup, before calling load(). It handles CLI commands and exits if necessary: - –help/-h: Shows help with source priority and mapping rules, then exits with code 0 - –check-variables/-cv: Shows diagnostic table and exits with code 1 if required fields are missing
Note
This method uses the current Config’s sources and model to generate help information. It is designed to be called once at startup. After this method returns (without exiting), you can safely call load() to get the configuration.
- load(validate=True)[source]
Load configuration with automatic defaults and optional validation.
- Parameters:
validate (bool) – Whether to validate required fields (default: True)
- Returns:
Model instance with configuration loaded from all sources.
- Raises:
varlord.exceptions.RequiredFieldError – If required fields are missing and validate=True.
- Return type:
Note
This method loads configuration once. For dynamic updates, use load_store() instead.
For handling CLI commands (–help, –check-variables), call handle_cli_commands() first.
- load_store()[source]
Load configuration store (supports dynamic updates).
Automatically enables watch if any source supports it.
- Returns:
ConfigStore instance for runtime configuration management.
- Return type:
Note
ConfigStore will use the same defaults + sources logic.
- format_cli_help(prog=None)[source]
Generate CLI help text from model fields with source priority and mapping rules.
This method finds the CLI source and generates help text without using argparse’s built-in help, giving varlord complete control. It also includes source priority information and mapping rules.
- format_diagnostic_table()[source]
Generate diagnostic table showing all variables and their status.
- Returns:
Variable name
Required/Optional status
Load status (Loaded/Using Default/Missing)
Source (defaults/env/cli/dotenv/etc)
Value (if loaded)
- Return type:
Formatted ASCII table string showing
- handle_cli_flags(exit_on_help=True, exit_on_check_variables=False, prog=None)[source]
Handle CLI flags (–help/-h and –check-variables/-cv).
- Parameters:
- Returns:
Tuple of (help_shown, check_variables_shown)
- Return type:
Note
This method checks sys.argv for –help/-h and –check-variables/-cv flags. If help is shown and exit_on_help=True, the program will exit. If check_variables is shown and exit_on_check_variables=True, the program will exit.
- get_field_info()[source]
Get information about all fields in the model.
- to_dict(validate=True)[source]
Get current configuration as dictionary.
- Parameters:
validate (bool) – Whether to validate required fields (default: True)
- Returns:
Dictionary representation of the current configuration
- Return type:
Example
>>> cfg = Config(model=AppConfig, sources=[...]) >>> config_dict = cfg.to_dict() >>> print(config_dict["host"])
- dump_json(file_path, validate=True, indent=2)[source]
Export current configuration to JSON file.
- Parameters:
Example
>>> cfg = Config(model=AppConfig, sources=[...]) >>> cfg.dump_json("config.json")
- dump_yaml(file_path, validate=True, default_flow_style=False)[source]
Export current configuration to YAML file.
- Parameters:
Example
>>> cfg = Config(model=AppConfig, sources=[...]) >>> cfg.dump_yaml("config.yaml")
- Raises:
ImportError – If PyYAML is not installed
- dump_toml(file_path, validate=True)[source]
Export current configuration to TOML file.
- Parameters:
Example
>>> cfg = Config(model=AppConfig, sources=[...]) >>> cfg.dump_toml("config.toml")
- Raises:
ImportError – If tomli-w is not installed
- dump_env(file_path, validate=True, prefix='', uppercase=True, nested_separator='__')[source]
Export current configuration to .env file.
- Parameters:
Example
>>> cfg = Config(model=AppConfig, sources=[...]) >>> cfg.dump_env(".env", prefix="APP_") # Creates: APP_HOST=localhost # APP_PORT=8000
- __repr__()[source]
Return string representation.
Helper Methods (Internal)¶
Note
These methods are used internally by the Config class. They are documented here
for advanced users who want to understand the implementation or extend the functionality.
- Config._unwrap_optional_type(field_type)[source]¶
Unwrap Optional[T] to get T.
For Union[T, None] types, returns T. For other types, returns the original type.
- Parameters:
field_type (type) – Field type to unwrap
- Returns:
The non-None type from Optional[T], or the original type
- Return type:
Example
>>> self._unwrap_optional_type(Optional[str]) <class 'str'> >>> self._unwrap_optional_type(str) <class 'str'>
- Config._process_dataclass_instances(flat_dict)[source]¶
Convert all dataclass instances in flat_dict to dicts.
- Config._process_flat_keys(flat_dict, field_info, result)[source]¶
Process non-nested (flat) keys with type conversion.
- Config._collect_nested_keys(flat_dict, field_info)[source]¶
Collect all nested keys grouped by parent key.
- Config._process_nested_keys(nested_collections, field_info, result)[source]¶
Process collected nested structures recursively.
- Config._convert_to_dataclasses(result, field_info)[source]¶
Convert nested dicts to dataclass instances with type conversion.
- Config._flatten_to_nested(flat_dict, model)[source]¶
Convert flat dict with dot notation to nested structure.
Example
{“db.host”: “localhost”, “db.port”: 5432, “host”: “0.0.0.0”} → {“db”: {“host”: “localhost”, “port”: 5432}, “host”: “0.0.0.0”}
Usage Examples¶
Basic Usage¶
from dataclasses import dataclass, field
from varlord import Config, sources
@dataclass(frozen=True)
class AppConfig:
host: str = field(default="localhost")
port: int = field(default=8000)
debug: bool = field(default=False)
# Load configuration from environment variables
cfg = Config(model=AppConfig, sources=[sources.Env()])
config = cfg.load()
print(config.host, config.port, config.debug)
Multiple Sources with Priority¶
# Load from multiple sources (later sources override earlier ones)
cfg = Config(
model=AppConfig,
sources=[
sources.Env(), # Priority 1
sources.DotEnv(), # Priority 2
sources.CLI(), # Priority 3 (highest)
],
)
Warning
Pitfall: Source order matters! Later sources override earlier ones.
If PORT is set in both environment variables and CLI, the CLI value wins.
With Validation¶
cfg = Config(model=AppConfig, sources=[sources.Env()])
config = cfg.load(validate=True)
Note
Best Practice: Always validate configuration in production to catch errors early.