Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/alex-ber/AlexBerUtils/llms.txt

Use this file to discover all available pages before exploring further.

The ymlparsers module is a streamlined wrapper around the HiYaPyCo library. It adds thread-safe Jinja2 variable substitution, a context manager to disable substitution on demand, and a consistent API for loading and dumping YAML. This module is the low-level backend for init_app_conf. It can also be used independently.
Optional dependency required. Install before use:
pip install alex-ber-utils[yml]
This installs hiyapyco and jinja2.

Setup

Call initConfig() once at application startup before calling any other function:
import alexber.utils.ymlparsers as ymlparsers

ymlparsers.initConfig()
This sets up the Jinja2 environment, the reentrant thread lock, and default options for load() and safe_dump().

Loading YAML files

load(yaml_files, **kwargs)

Loads and merges one or more YAML files hierarchically. Files listed later override earlier ones. Returns an OrderedDict. By default:
  • Lists are replaced, not merged (mergelists=False)
  • Jinja2 variable substitution is enabled (interpolate=True)
  • Values are cast to Python types after interpolation (castinterpolated=True)
  • Method is METHOD_SUBSTITUTE (later files override earlier ones)
import alexber.utils.ymlparsers as ymlparsers

ymlparsers.initConfig()

# Load a single file
config = ymlparsers.load(['config.yml'])

# Load multiple files — config-dev.yml overrides config.yml
config = ymlparsers.load(['config.yml', 'config-dev.yml'])
With Jinja2 variable substitution: Given config.yml:
app:
  inner_host_name: google.com
  cli_template: ping {{app.inner_host_name}}
config = ymlparsers.load(['config.yml'])
config['app']['cli_template']  # => 'ping google.com'
After a profile override in config-dev.yml that sets inner_host_name: yahoo.com, the template resolves to 'ping yahoo.com'.

Parameters

yaml_files
list[str]
Ordered list of YAML file paths or YAML strings. Files are merged left to right — each subsequent file overrides the previous.
method
int
Merge method. One of hiyapyco.METHOD_SIMPLE, METHOD_MERGE, or METHOD_SUBSTITUTE (default).
mergelists
bool
Whether to merge lists. Defaults to False (lists are replaced).
interpolate
bool
Whether to perform Jinja2 variable substitution. Defaults to True.
castinterpolated
bool
Whether to cast interpolated string values to Python types. Defaults to True.
encoding
str
File encoding. Defaults to 'utf-8'.
failonmissingfiles
bool
Raise an error if a file does not exist. Defaults to True.

Disabling variable substitution

DisableVarSubst()

A context manager that temporarily disables Jinja2 variable substitution inside load(). This is used internally by init_app_conf to read the raw base config (including unresolved {{...}} templates) before merging.
with ymlparsers.DisableVarSubst():
    raw_config = ymlparsers.load(['config.yml'])

# raw_config['app']['cli_template'] => 'ping {{app.inner_host_name}}'
# (substitution did NOT happen)
The context manager is thread-safe: it acquires HiYaPyCo.jinja2Lock and restores the original delimiter strings in the finally block, even if an exception is raised. You can also pass a custom Jinja2 environment and lock:
from jinja2 import Environment, DebugUndefined
from threading import RLock

my_env = Environment(undefined=DebugUndefined)
my_lock = RLock()

with ymlparsers.DisableVarSubst(jinja2ctx=my_env, jinja2Lock=my_lock):
    raw = ymlparsers.load(['config.yml'])

Parameters

jinja2ctx
jinja2.Environment
Custom Jinja2 environment to disable substitution on. Defaults to HiYaPyCo.jinja2ctx.
jinja2Lock
RLock
Lock for thread safety. Must be the same lock used by load(). Defaults to HiYaPyCo.jinja2Lock. Cannot be provided without jinja2ctx.

Dumping YAML

safe_dump(data, stream=None, **kwargs)

Dumps a Python object to YAML format. Supports primitive types, lists, dicts, and collections.OrderedDict. By default:
  • Block style (default_flow_style=False)
  • Key order is preserved (sort_keys=False)
import io
import alexber.utils.ymlparsers as ymlparsers
from collections import OrderedDict

ymlparsers.initConfig()

data = OrderedDict([
    ('general', OrderedDict([('profiles', ['dev', 'local'])])),
    ('app', OrderedDict([('host_name', 'google.com')])),
])

# Dump to a stream
with io.StringIO() as buf:
    ymlparsers.safe_dump(data, stream=buf)
    yaml_text = buf.getvalue()

print(yaml_text)
# general:
#   profiles:
#   - dev
#   - local
# app:
#   host_name: google.com

Parameters

data
any
The Python object to serialize.
stream
IO
A writable stream. If None, returns a string (via yaml.dump_all semantics).
default_flow_style
bool
Controls YAML style. False (default) uses block style. Pass True for inline/flow style.
sort_keys
bool
Whether to sort dictionary keys alphabetically. Defaults to False (insertion order preserved).

as_str(data, **kwargs)

Returns a string representation of the data in YAML format. A convenience wrapper around safe_dump().
data = {'general': {'profiles': ['dev', 'local']}}
yaml_str = ymlparsers.as_str(data)
print(yaml_str)
# general:
#   profiles:
#   - dev
#   - local

Parameters

data
any
The Python object to serialize to a YAML string.
Accepts the same **kwargs as safe_dump().

initConfig(**kwargs)

Initializes the module. Safe to call with no arguments. Must be called before load() or safe_dump().
jinja2Lock
RLock
Thread lock for synchronization in DisableVarSubst and load(). Defaults to a new RLock(). Available as HiYaPyCo.jinja2Lock after initialization.
jinja2ctx
dict
Configuration dict for the Jinja2 Environment. Supports all Environment keyword arguments plus a globals sub-key:
  • undefined: defaults to DebugUndefined
  • globals: dict of global functions available in templates; uname (platform.uname) is always injected
ymlparsers.initConfig(
    jinja2ctx={
        'undefined': StrictUndefined,
        'globals': {'my_fn': some_function}
    }
)
Available as HiYaPyCo.jinja2ctx after initialization.
load
dict
Default keyword arguments for load(). Overrides the built-in defaults:
# Built-in defaults:
{
    'method': hiyapyco.METHOD_SUBSTITUTE,
    'mergelists': False,
    'interpolate': True,
    'castinterpolated': True
}
safe_dump
dict
Default keyword arguments for safe_dump() and as_str(). Overrides the built-in defaults:
# Built-in defaults:
{
    'default_flow_style': False,
    'sort_keys': False
}

Customizing defaults example

from hiyapyco import METHOD_SIMPLE

ymlparsers.initConfig(
    load={
        'method': METHOD_SIMPLE,
        'mergelists': True,
        'interpolate': False,
    },
    safe_dump={
        'default_flow_style': True,
        'sort_keys': True,
    }
)

Thread safety

load() acquires HiYaPyCo.jinja2Lock for every interpolated string. DisableVarSubst also acquires the same lock. Both are safe to use concurrently from multiple threads — a common pattern is one thread loading with substitution and another loading without it simultaneously.

Build docs developers (and LLMs) love