Configuration Loader¶
Public API for kstlib.config, covering the cascade helpers, loaders, and shortcuts used throughout the rest of
the library. The module is intentionally small: most of the behaviour lives in kstlib.config.loader, but this
namespace exposes the functions you are expected to import.
Tip
Pair this reference with Configuration for the feature guide.
Quick overview¶
load_from_file(path, *, strict_format=False, **overrides)reads a specific file (YAML/TOML/JSON/INI) and resolves anyinclude:directives.get_config(*, max_age=None, **overrides)executes the cascading search and memoizes the result so imports do not thrash the filesystem.require_config()mirrorsget_config()but raises immediately when no configuration has been loaded yet.clear_config()flushes the memoized cascade, useful in tests when multiple fixtures run in the same process.reload_config()is the ergonomic alias for “flush and reload from disk”, intended for interactive sessions (Jupyter, REPL) where the YAML files have been edited mid-session.
Core Functions¶
get_config¶
- kstlib.config.get_config(filename: 'str' = 'kstlib.conf.yml', force_reload: 'bool' = False, max_age: 'float | None' = None) 'Box' -> Box[source]
Return the current kstlib configuration object (singleton).
Loads the configuration only once, unless force_reload=True is set.
This is a backward-compatible wrapper. For new code, prefer ConfigLoader class.
- Parameters:
- Returns:
Configuration object (dot notation enabled).
- Return type:
Box
- Raises:
ConfigFileNotFoundError – If no configuration file is found in any location.
Examples
>>> config = get_config() >>> config = get_config(force_reload=True)
load_from_file¶
- kstlib.config.load_from_file(path: 'str | pathlib.Path', strict_format: 'bool' = False, sops_decrypt: 'bool' = True) 'Box' -> Box[source]
Load configuration from a specific file path.
Convenience wrapper for load_config(path=…).
This is a backward-compatible wrapper. For new code, prefer ConfigLoader.from_file().
- Parameters:
- Returns:
Configuration object with dot notation support.
- Raises:
ConfigFileNotFoundError – If the specified file doesn’t exist.
ConfigFormatError – On unsupported format or format mismatch.
ConfigCircularIncludeError – On circular includes.
- Return type:
Box
Examples
>>> config = load_from_file("/opt/myapp/config.yml") >>> config = load_from_file("/etc/app.yml", strict_format=True)
require_config¶
- kstlib.config.require_config() 'Box' -> Box[source]
Return the configuration object, raising an exception if not loaded.
Use this when you need to ensure a config is available.
This is a backward-compatible wrapper. For new code, prefer ConfigLoader class.
- Returns:
Loaded configuration.
- Raises:
ConfigNotLoadedError – If configuration has not been loaded yet.
- Return type:
Box
Examples
>>> config = require_config()
clear_config¶
- kstlib.config.clear_config() 'None' -> None[source]
Clear the singleton configuration cache.
Useful for testing or when you need to reload configuration.
Examples
>>> clear_config() >>> config = get_config() # Will reload from disk
reload_config¶
- kstlib.config.reload_config(filename: 'str' = 'kstlib.conf.yml') 'Box' -> Box[source]
Force-reload the singleton configuration from disk.
Equivalent to
clear_config()followed byget_config(), but explicit and discoverable in a single import. Designed for interactive sessions (Jupyter, REPL) where the underlying YAML files have been edited and the cached config needs to be refreshed without restarting the kernel.- Parameters:
filename (str) – Config filename to search for. Defaults to
kstlib.conf.yml.- Returns:
Freshly loaded
Boxconfiguration object. The singleton cache is updated in-place, so subsequentget_config()calls return the same fresh object.- Raises:
ConfigFileNotFoundError – If no configuration file is found in any search location.
- Return type:
Box
Note
When to use which:
reload_config(): explicit one-shot refresh (Jupyter/REPL).get_config(force_reload=True): same effect, but the intent is hidden in a kwarg.clear_config(): only flushes the cache; the nextget_config()call triggers the actual reload. Useful in tests that want to isolate the cache boundary.
Examples
>>> from kstlib.config import reload_config >>> cfg = reload_config() >>> cfg.mail.default 'corporate'
ConfigLoader Class¶
ConfigLoader¶
- class kstlib.config.ConfigLoader(strict_format=False, encoding='utf-8', sops_decrypt=True, *, auto=None, **auto_kwargs)[source]
Bases:
objectConfiguration loader with support for multiple formats and sources.
This class provides a clean, object-oriented interface for loading configuration from various sources with customizable behavior.
- strict_format
If True, included files must match parent format.
- encoding
File encoding for text-based formats.
- sops_decrypt
If True, auto-decrypt .sops.* files via SOPS binary.
- auto_discovery
Whether the constructor should immediately hydrate the config.
- auto_source
Source used for auto-discovery (cascading/env/file).
- auto_filename
Filename searched when auto-discovery cascades.
- auto_env_var
Environment variable used when auto_source is
"env".
- auto_path
Explicit path used when auto_source is
"file".
- auto
AutoDiscoveryConfigcarrying the effective auto-discovery options.
Examples
Instance-based usage with custom settings:
>>> loader = ConfigLoader(strict_format=True, encoding='utf-8') >>> config = loader.load_from_file("config.yml") >>> print(config.app.name)
Factory methods (one-liner convenience):
>>> config = ConfigLoader.from_file("config.yml") >>> config = ConfigLoader.from_env("CONFIG_PATH") >>> config = ConfigLoader.from_cascading("myapp.yml")
Multiple independent configs:
>>> dev_config = ConfigLoader().load_from_file("dev.yml") >>> prod_config = ConfigLoader(strict_format=True).load_from_file("prod.yml")
Disable SOPS decryption:
>>> loader = ConfigLoader(sops_decrypt=False) >>> config = loader.load_from_file("secrets.sops.yml") # Loads raw
- __init__(self, strict_format: 'bool' = False, encoding: 'str' = 'utf-8', sops_decrypt: 'bool' = True, *, auto: 'AutoDiscoveryConfig | None' = None, **auto_kwargs: 'Any') 'None' -> None[source]
Initialize a ConfigLoader with specific settings.
- Parameters:
strict_format (bool) – If True, included files must match parent file format.
encoding (str) – File encoding for text-based configuration formats.
sops_decrypt (bool) – If True, auto-decrypt .sops.* files via SOPS binary.
auto (AutoDiscoveryConfig | None) – Pre-built auto-discovery options. When omitted, keyword arguments such as
auto_sourceorauto_filenameare honoured.auto_kwargs (Any) – Legacy keyword arguments controlling auto-discovery:
auto_discovery,auto_source,auto_filename,auto_env_var, andauto_path.
- property cache: Box | None
Return the cached configuration instance, if any.
- property cache_timestamp: float | None
Return the epoch timestamp when the cache was last refreshed.
- property config: Box
Return the currently loaded configuration or raise if missing.
- __getattr__(self, item: 'str') 'Any' -> Any[source]
Proxy attribute access to the cached configuration.
- __getitem__(self, key: 'str') 'Any' -> Any[source]
Provide dict-style access to the cached configuration.
- load_from_file(self, path: 'str | pathlib.Path', *, purge_cache: 'bool' = True) 'Box' -> Box[source]
Load configuration from a specific file path.
- Parameters:
- Returns:
Configuration object with dot notation support.
- Raises:
ConfigFileNotFoundError – If the specified file doesn’t exist.
ConfigFormatError – On unsupported format or format mismatch.
ConfigCircularIncludeError – On circular includes.
- Return type:
Box
Examples
>>> loader = ConfigLoader() >>> config = loader.load_from_file("/opt/myapp/config.yml") >>> print(config.database.host)
- load_from_env(self, env_var: 'str' = 'CONFIG_PATH', *, purge_cache: 'bool' = True) 'Box' -> Box[source]
Load configuration from path specified in an environment variable.
- Parameters:
- Returns:
Configuration object with dot notation support.
- Raises:
ValueError – If environment variable is not set or empty.
ConfigFileNotFoundError – If the path in environment variable doesn’t exist.
- Return type:
Box
Examples
>>> import os >>> os.environ["CONFIG_PATH"] = "/opt/config.yml" >>> loader = ConfigLoader() >>> config = loader.load_from_env()
- load(self, filename: 'str' = 'kstlib.conf.yml', *, purge_cache: 'bool' = True) 'Box' -> Box[source]
Load configuration using cascading search across multiple locations.
- Search order (priority from lowest to highest):
Package default config (lowest priority - base layer)
System-wide config dirs from
platformdirs.site_config_dir(respectsXDG_CONFIG_DIRSon Linux, native locations on Mac/Windows). Missing files are skipped silently.User’s config directory (e.g., ~/.config/kstlib.conf.yml)
User’s home directory (e.g., ~/kstlib.conf.yml)
Current working directory (highest priority - overrides all)
- Parameters:
- Returns:
Configuration object with dot notation support.
- Raises:
ConfigFileNotFoundError – If no config file is found in any location.
- Return type:
Box
Examples
>>> loader = ConfigLoader() >>> config = loader.load("myapp.yml")
- classmethod from_file(path: 'str | pathlib.Path', strict_format: 'bool' = False, encoding: 'str' = 'utf-8', sops_decrypt: 'bool' = True) 'Box' -> Box[source]
Create loader and load file in one call (factory method).
- Parameters:
- Returns:
Configuration object with dot notation support.
- Return type:
Box
Examples
>>> config = ConfigLoader.from_file("config.yml") >>> config = ConfigLoader.from_file("config.yml", strict_format=True)
- classmethod from_env(env_var: 'str' = 'CONFIG_PATH', strict_format: 'bool' = False, encoding: 'str' = 'utf-8', sops_decrypt: 'bool' = True) 'Box' -> Box[source]
Create loader and load from environment variable in one call (factory method).
- Parameters:
- Returns:
Configuration object with dot notation support.
- Return type:
Box
Examples
>>> config = ConfigLoader.from_env("CONFIG_PATH") >>> config = ConfigLoader.from_env("MYAPP_CONFIG", strict_format=True)
- classmethod from_cascading(filename: 'str' = 'kstlib.conf.yml', strict_format: 'bool' = False, encoding: 'str' = 'utf-8', sops_decrypt: 'bool' = True) 'Box' -> Box[source]
Create loader and perform cascading search in one call (factory method).
- Parameters:
- Returns:
Configuration object with dot notation support.
- Return type:
Box
Examples
>>> config = ConfigLoader.from_cascading("myapp.yml") >>> config = ConfigLoader.from_cascading(strict_format=True)
SOPS Integration¶
SopsDecryptor¶
- class kstlib.config.SopsDecryptor(binary='sops', max_cache_entries=64)[source]
Bases:
objectLightweight SOPS decryptor with LRU cache.
This class provides SOPS file decryption with: - Configurable binary path - LRU cache with mtime-based invalidation - Clear error messages for troubleshooting
- binary
Name or path of the SOPS binary.
- max_cache
Maximum cache entries (clamped to hard limit).
Examples
>>> decryptor = SopsDecryptor() >>> content = decryptor.decrypt_file(Path("secrets.sops.yml"))
- __init__(self, binary: 'str' = 'sops', max_cache_entries: 'int' = 64) 'None' -> None[source]
Initialize the SOPS decryptor.
- property binary: str
Return the configured SOPS binary name.
- property max_cache: int
Return the maximum cache size.
- decrypt_file(self, path: 'pathlib.Path') 'str' -> str[source]
Decrypt a SOPS-encrypted file and return content as string.
- purge_cache(self, path: 'pathlib.Path | None' = None) 'None' -> None[source]
Clear cache entries.
- Parameters:
path (Path | None) – If provided, only clear this specific path. If None, clear all cached entries.
- property cache_size: int
Return the current number of cached entries.
get_decryptor¶
- kstlib.config.sops.get_decryptor(binary: 'str' = 'sops') 'SopsDecryptor' -> SopsDecryptor[source]
Get or create global SOPS decryptor singleton.
- Parameters:
binary (str) – SOPS binary name (only used on first call).
- Returns:
The global SopsDecryptor instance.
- Return type:
SopsDecryptor
Examples
>>> decryptor = get_decryptor() >>> content = decryptor.decrypt_file(path)
Exceptions¶
ConfigError¶
- class kstlib.config.ConfigError[source]
Bases:
KstlibErrorBase exception for configuration-related errors.
All config module exceptions inherit from this class.
ConfigFileNotFoundError¶
- class kstlib.config.ConfigFileNotFoundError[source]
Bases:
ConfigError,FileNotFoundErrorConfiguration file not found at specified location.
Raised when attempting to load a config file that doesn’t exist.
ConfigNotLoadedError¶
- class kstlib.config.ConfigNotLoadedError[source]
Bases:
ConfigError,RuntimeErrorConfiguration not loaded yet.
Raised by require_config() when attempting to access config before it has been loaded via get_config() or load_config().