Skip to content

Instantly share code, notes, and snippets.

@zobayer1
Last active December 1, 2023 16:01
Show Gist options
  • Save zobayer1/26e25bf98c8e647e095b48283309fe72 to your computer and use it in GitHub Desktop.
Save zobayer1/26e25bf98c8e647e095b48283309fe72 to your computer and use it in GitHub Desktop.
Parsing environment variables in an YAML file using PyYAML library
"""A simple yaml loader
Load the content of an yaml file into a python dict. Environment variable can be specified with ${VAR_NAME}. A
default string value can be specified with ${VAR_NAME:DEFAULT}. Able to process multiple occurrences.
requirement: PyYAML
run: python loader.py
"""
import os
import re
from typing import Any
import yaml
from yaml.parser import ParserError
_var_matcher = re.compile(r"\${([^}^{]+)}")
_tag_matcher = re.compile(r"[^$]*\${([^}^{]+)}.*")
def _path_constructor(_loader: Any, node: Any):
def replace_fn(match):
envparts = f"{match.group(1)}:".split(":")
return os.environ.get(envparts[0], envparts[1])
return _var_matcher.sub(replace_fn, node.value)
def load_yaml(filename: str) -> dict:
yaml.add_implicit_resolver("!envvar", _tag_matcher, None, yaml.SafeLoader)
yaml.add_constructor("!envvar", _path_constructor, yaml.SafeLoader)
try:
with open(filename, "r") as f:
return yaml.safe_load(f.read())
except (FileNotFoundError, PermissionError, ParserError):
return dict()
if __name__ == "__main__":
print(load_yaml("sample.yaml"))
# A sample YAML file
version: 1
node1:
- field: ${VAR1}
- field: some ${VAR2} and some
- field: test ${VAR1} some text'${VAR2}' some other values
- field: test with default ${VAR3:123}
- field: ${VAR3:}${VAR4}
"""Test for yaml loader
A simple pytest script to test loading environment variables in an yaml file
requirement: pytest
run: pytest -s
"""
import os
import pytest
from loader import load_yaml
def test_loader():
"""Test fails if loader fails to parse environment variables"""
os.environ.update({"VAR1": "var1", "VAR2": "var2"})
data = load_yaml("sample.yaml")
assert "var1" in data["node1"][0]["field"]
assert "var2" in data["node1"][1]["field"]
assert all(x in data["node1"][2]["field"] for x in ["var1", "var2"])
assert "123" in data["node1"][3]["field"]
assert "" == data["node1"][4]["field"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment