ConfigBase
ConfigBase is the core class of the Configr library that handles loading configuration from files and converting it to
dataclasses.
Overview
ConfigBase provides a robust mechanism for loading and validating configuration data from various file formats (JSON,
YAML, etc.) and converting it to strongly-typed Python dataclasses. It supports nested dataclass structures and provides
a flexible, extensible interface for adding custom loaders.
Class Definition
class ConfigBase(Generic[T]):
"""
Base class for configuration management.
Handles loading configuration from files and conversion to dataclasses.
"""
Class Variables
| Variable | Type | Description |
|---|---|---|
_loaders |
list[type[ConfigLoader]] |
List of available configuration loader classes. |
Methods
set_config_dir
Set the directory where configuration files are stored.
Parameters
config_dir: A string or Path object representing the directory where configuration files are stored.
Example
from configr import ConfigBase
# Set the configuration directory
ConfigBase.set_config_dir("configs")
# Or using a Path object
from pathlib import Path
ConfigBase.set_config_dir(Path("configs"))
get_available_loaders
Get all available configuration loader classes.
Returns
A list of available configuration loader classes.
Example
from configr import ConfigBase
# Get all available loaders
loaders = ConfigBase.get_available_loaders()
print(loaders) # [JSONConfigLoader, YAMLConfigLoader, DotEnvConfigLoader, EnvVarConfigLoader]
get_available_file_loaders
Get all available file-based configuration loader classes.
Returns
A list of available file-based configuration loader classes.
Example
from configr import ConfigBase
# Get all available file loaders
file_loaders = ConfigBase.get_available_file_loaders()
print(file_loaders) # [JSONConfigLoader, YAMLConfigLoader, DotEnvConfigLoader]
add_loader
Add another loader
Parameters
loader: The loader class to add.
Example
from configr import ConfigBase, FileConfigLoader
from typing import Any, TypeVar
T = TypeVar('T')
class TOMLConfigLoader(FileConfigLoader):
"""Loader for TOML configuration files."""
ext: list[str] = ['.toml'] # Supported file extensions
@classmethod
def load(cls, name: str, config_class: type[T] = None) -> dict[str, Any]:
"""Load TOML configuration from the specified path."""
try:
import toml
except ImportError:
raise ImportError("The 'toml' package is required for TOML support. Install with 'pip install toml'.")
config_file_path = cls._get_config_file_path(name)
with open(config_file_path) as f:
return toml.load(f)
# Register the TOML loader
ConfigBase.add_loader(TOMLConfigLoader)
remove_loader
Remove a specific loader.
Parameters
loader: The loader to remove.
Example
from configr import ConfigBase
from configr.loaders.loader_yaml import YAMLConfigLoader
# Remove the YAML loader
ConfigBase.remove_loader(YAMLConfigLoader)
load
Load configuration from file and convert it to the specified dataclass.
Parameters
config_class: The dataclass to convert configuration to.config_data: Optional dictionary containing configuration data. If not provided, it will be loaded from the file.
Returns
An instance of the specified dataclass with loaded configuration.
Raises
TypeError: Ifconfig_classis not a dataclass.ConfigFileNotFoundError: If the configuration file is not found.ConfigValidationError: If the configuration fails validation.ConfigLoadError: If the configuration loading fails.
Example
from configr import ConfigBase, config_class
@config_class
class DatabaseConfig:
username: str
password: str
database: str
host: str = "localhost"
port: int = 5432
# Load configuration from file
db_config = ConfigBase.load(DatabaseConfig)
# Or with explicit configuration data
config_data = {
"host": "db.example.com",
"port": 5432,
"username": "admin",
"password": "secure_password",
"database": "my_app"
}
db_config = ConfigBase.load(DatabaseConfig, config_data)
Private Methods
These methods are intended for internal use by the ConfigBase class:
__load_config_data
Load configuration data from file or loader and return as a dictionary.
__filter_fields
Filter the data to include only the fields defined in the dataclass.
@classmethod
def __filter_fields(cls, fields: dict[str, type], raw_config_data: dict[str, Any]) -> dict[str, Any]:
__load_nested_dataclasses
Recursively load nested dataclasses.
_get_loader
Determine the appropriate loader for the given configuration class.
Implementation Details
The ConfigBase class:
- Determines the appropriate file to load based on the configuration class
- Tries to find the file with different supported extensions from available loaders
- Uses the appropriate loader to parse the file into a dictionary
- Filters the data to include only fields defined in the dataclass
- Handles nested dataclass structures recursively
- Performs type validation using
FieldTypeChecker - Creates and returns an instance of the specified dataclass with the loaded configuration data
Example Usage
from configr import ConfigBase, config_class
from dataclasses import dataclass
@dataclass
class DatabaseConfig:
username: str
password: str
name: str
host: str = "localhost"
port: int = 5432
@config_class(file_name="app.yaml")
class AppConfig:
debug: bool = False
log_level: str = "INFO"
database: DatabaseConfig = None # Nested configuration
# Set custom configuration directory
ConfigBase.set_config_dir("my_configs")
# Load configurations
app_config = ConfigBase.load(AppConfig)
# Use the loaded configuration
print(f"Debug mode: {app_config.debug}, Log level: {app_config.log_level}")
if app_config.database:
print(f"Connecting to {app_config.database.name} at {app_config.database.host}:{app_config.database.port}")