Last active
December 1, 2023 16:01
-
-
Save zobayer1/26e25bf98c8e647e095b48283309fe72 to your computer and use it in GitHub Desktop.
Parsing environment variables in an YAML file using PyYAML library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""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")) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""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