configuration loading utils
Project description
conf-loaders
Configuration loading utilities for Python projects. Load settings from YAML with environment variable substitution, relative path resolution, encrypted passwords, and advanced merge operations.
pip install conf-loaders
What it does
conf-loaders solves the problem of keeping default settings in Python code while allowing local overrides via YAML files. It provides:
- YAML settings loading with automatic environment variable substitution (
${VAR}or${VAR:-default}) - Relative path resolution — relative paths in YAML are resolved to absolute paths automatically
- Update operations — extend lists, append items, update dicts without replacing the whole structure
- Encrypted passwords — load AES/RSA encrypted secrets from separate YAML files
- Environment variable parsing — parse prefixed environment variables into nested dict structures
Quick start
Basic usage in Django/Flask settings.py
# settings.py — default values
DEBUG = False
ALLOWED_HOSTS = ["localhost"]
DATABASES = {
"default": {"ENGINE": "django.db.backends.sqlite3"}
}
# config.yaml — local overrides
DEBUG: true
ALLOWED_HOSTS@extend:
- "my-domain.com"
DATABASES@update:
default:
NAME: "/path/to/db.sqlite3"
# At the end of settings.py
from conf_loaders.utils.settings_load import load_settings_from_yaml
load_settings_from_yaml("config.yaml", object_to_update=locals())
After loading, locals() contains merged values from both sources.
Features
Environment variable substitution
YAML files are pre-processed with varsubst before parsing:
DB_HOST: "${DB_HOST:-localhost}"
DB_PORT: "${DB_PORT:-5432}"
Relative path resolution
String values that look like relative paths are resolved to absolute paths using base_dir:
# Relative to the directory passed as base_dir
LOG_PATH: "../../data/logs/app.log"
MODEL_DIR: "./models"
To disable resolution for a specific value, prefix it with !:
# Will remain "./relative/path" without resolution
PATTERN: "!./relative/path"
Path resolution is recursive — works inside nested dicts and lists.
U can disable all these operations by setting base_dir=....
Update operations
By default, a YAML key replaces the entire Python value. Use @operation suffixes to merge instead:
@extend — extend a list
ALLOWED_HOSTS@extend:
- "api.example.com"
- "app.example.com"
@append — append a single item
ALLOWED_HOSTS@append: "admin.example.com"
@update — update a dict (merge keys)
DATABASES@update:
default:
HOST: "postgres.internal"
@bind — replace contents, keep object reference
Useful when other modules hold references to the list/dict:
# Clears SCRIPT_ROOTS and fills with new values,
# but the list object in memory stays the same
SCRIPT_ROOTS@bind:
- scripts/common/
- scripts/custom/
@setdefault — set only if not defined
DEBUG@setdefault: false
If DEBUG is already defined in settings.py, the YAML value is ignored.
Full operation reference
| Operation | Effect | Requires existing var |
|---|---|---|
| (no suffix) | Replace entirely | No |
@setdefault |
Set only if undefined | No |
@bind |
Clear + refill, keep object reference | No |
@append |
Append one item to list | Yes |
@try-append |
Append one item, create list if missing | No |
@extend |
Extend list with multiple items | Yes |
@try-extend |
Extend list, create if missing | No |
@update |
Merge dict keys | Yes |
@try-update |
Merge dict keys, create dict if missing | No |
Nested key access
Operations support dot-notation for nested structures:
# Sets DATABASES["default"]["PORT"] = 5433
DATABASES.default.PORT: 5433
# Appends to nested list
DATABASES.default.OPTIONS@append: "sslmode=require"
Encrypted passwords
Store sensitive values in a separate encrypted file:
from conf_loaders.utils.settings_load import load_passwords_from_yaml
load_passwords_from_yaml(
passwords_file="secrets.yaml",
secret_key_file=".secret.key",
object_to_update=locals(),
)
# secrets.yaml
DB_PASSWORD: "AES$salt$ciphertext"
API_KEY: "AES$salt$ciphertext"
Supported algorithms: AES, RSA.
Environment variable parsing
Load prefixed environment variables into settings:
from conf_loaders.utils.settings_load import load_vars_from_env
load_vars_from_env(
object_to_update=locals(),
prefix="MYAPP_", # Only vars starting with MYAPP_
secret_key_file=".secret.key", # Auto-decrypt encrypted values
)
With MYAPP_DB_HOST=localhost and MYAPP_DB_PORT_NUMBER=5432 and MYAPP_USE_PROXY_FLAG=1 in environment:
# Results in:
DB_HOST = "localhost"
DB_PORT = 5432
USE_PROXY = True
Double underscores create nested dicts: MYAPP_CACHE__REDIS__HOST=localhost → CACHE["REDIS"]["HOST"] = "localhost".
API reference
load_settings_from_yaml
load_settings_from_yaml(
path: str | Path,
object_to_update: MutableMapping[str, Any],
base_dir: str | Path | None = None,
show_update_errors: bool = True,
)
- path — path to YAML file
- object_to_update — dict-like object to update, usually
locals() - base_dir — directory for resolving relative paths;
Nonedisables resolution - show_update_errors — whether to print values in error messages
load_passwords_from_yaml
load_passwords_from_yaml(
passwords_file: str | Path,
secret_key_file: str | Path,
object_to_update: MutableMapping[str, Any],
password_sep: str = "$",
) -> Dict[str, Dict[str, str]]
Returns a dict of successfully decrypted variables with their algorithms and keys.
load_vars_from_env
load_vars_from_env(
object_to_update: MutableMapping[str, Any],
secret_key_file: str | Path | None = None,
password_sep: str = "$",
prefix: str = "TRANSLATE_",
)
save_settings_debug
save_settings_debug(settings: Mapping[str, Any])
If settings contains SAVE_SETTINGS_DEBUG key with a file path, dumps all settings to that file as JSON (for debugging).
File utilities
conf_loaders.utils.docrender_utils.files provides helpers for common file operations:
read_yaml(path)/write_yaml(path, data)— YAML I/Oread_json(path)/write_json(path, data)— JSON I/Oread_text(path)/write_text(path, text)— Text I/Omkdir(path)/mkdir_of_file(path)/mkparents(path)— Directory creationcopy_file(src, dst)/move_file(src, dst)— File operationstouch(path)/rmdir(path)— Basic file ops
Changelog
0.6.0
save_settings_debug:- if
base_dir=Nonethen it will be extracted fromsettings.BASE_DIR
- if
0.5.0
load_settings_from_yaml:- relative path resolution can be disabled at all (even
!removing) usingbase_dir=... - relative values start from
!provide warning ifbase_dir=None resolve_content_from_env=Falsedisables file content resolving from environment
- relative path resolution can be disabled at all (even
save_settings_debug:base_diroption (like inload_settings_from_yaml) provides supplement path resolution for debugging purposes
0.4.0
- Relative path resolution is now recursive — works inside nested dicts and lists, not just top-level values
- Values starting with
!are excluded from path resolution
Earlier versions
- Initial release with YAML loading,
varsubst, update operations, encrypted passwords, and env var parsing
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file conf_loaders-0.6.0-py3-none-any.whl.
File metadata
- Download URL: conf_loaders-0.6.0-py3-none-any.whl
- Upload date:
- Size: 24.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eed6de9584ab6e624cb7daea23f3e4ede12fbdfda4f87374fb10b991bbf5d9ac
|
|
| MD5 |
29f2f4b3b673f07f670bf9aa7734c8e8
|
|
| BLAKE2b-256 |
85bede37d278afd8c67c7a6a3bb9c6950cfffe4052382c43d8434ad9379a5ef3
|