close

How to replace environment variable value in yaml file to be parsed using python script

Hello Guys, How are you all? Hope You all Are Fine. Today We Are Going To learn about How to replace environment variable value in yaml file to be parsed using python script in Python. So Here I am Explain to you all the possible Methods here.

Without wasting your time, Let’s start This Article.

How to replace environment variable value in yaml file to be parsed using python script?

  1. How to replace environment variable value in yaml file to be parsed using python script?

    Here is an alternative version which does use a new Loader class if you do not want to modify the global/default yaml Loader.

  2. replace environment variable value in yaml file to be parsed using python script

    Here is an alternative version which does use a new Loader class if you do not want to modify the global/default yaml Loader.

Method 1

PY-yaml library doesn’t resolve environment variables by default. You need to define an implicit resolver that will find the regex that defines an environment variable and execute a function to resolve it.

You can do it through yaml.add_implicit_resolver and yaml.add_constructor. In the code below, you are defining a resolver that will match on ${ env variable } in the YAML value and calling the function path_constructor to look up the environment variable.

import yaml
import re
import os

path_matcher = re.compile(r'\$\{([^}^{]+)\}')
def path_constructor(loader, node):
  ''' Extract the matched value, expand env variable, and replace the match '''
  value = node.value
  match = path_matcher.match(value)
  env_var = match.group()[2:-1]
  return os.environ.get(env_var) + value[match.end():]

yaml.add_implicit_resolver('!path', path_matcher)
yaml.add_constructor('!path', path_constructor)

data = """
env: ${VAR}/file.txt
other: file.txt
"""

if __name__ == '__main__':
  p = yaml.load(data, Loader=yaml.FullLoader)
  print(os.environ.get('VAR')) ## /home/abc
  print(p['env']) ## /home/abc/file.txt

Method 2

Here is an alternative version which does use a new Loader class if you do not want to modify the global/default yaml Loader.

And more importantly, it correctly replaces interpolated strings that are not just the environment variables, eg path/to/${SOME_VAR}/and/${NEXT_VAR}/foo/bar

        path_matcher = re.compile(r'.*\$\{([^}^{]+)\}.*')
        def path_constructor(loader, node):
            return os.path.expandvars(node.value)

        class EnvVarLoader(yaml.SafeLoader):
            pass

        EnvVarLoader.add_implicit_resolver('!path', path_matcher, None)
        EnvVarLoader.add_constructor('!path', path_constructor)

        with open(configPath) as f:
            c = yaml.load(f, Loader=EnvVarLoader)

Summery

It’s all About this issue. Hope all Methods helped you a lot. Comment below Your thoughts and your queries. Also, Comment below which Method worked for you? Thank You.

Also, Read