Search code examples
pythonyaml

Difference between yaml.load and yaml.SafeLoader in PyYAML


Python newbie here.

I installed PyYAML and tried using this bit of code I found modified on the net to parse a YAML file I was given.

import yaml

if __name__ == '__main__':
    try:
        foo = open("foo.txt","a+")
    except:
        print("Error in opening file.")

stream = open("s.yaml", 'r')
dictionary = yaml.load(stream)
#dictionary = yaml.SafeLoader(stream)
for key, value in dictionary.items():

    foo.write(key + " : " + str(value)+"\n")

Then I saw in the output that yaml.load was deprecated because of security issues. So I tried running it using SafeLoader instead. But that gave me the error

Traceback (most recent call last):
  File ".\parseYAML.py", line 11, in <module>
    for key, value in dictionary.items():
AttributeError: 'SafeLoader' object has no attribute 'items'

I can't post the actual data file here for business reasons, but does anyone have any hints on how I can get SafeLoader to work?


Solution

  • We use the following snippets of code that show some ways to use the SafeLoader: (the last line is probably what you're most interested in, for the simplest case)

    import yaml
    
    env_variable_matcher = re.compile(r'<your custom pattern here>')
    
    def env_variable_parser(loader, node):
        '''
        Parse a yaml value containing ${A-Z0-9_} as an environment variable
        '''
        ...
        return output
    
    # Add support for yaml tag named env_var which matches a string containing
    # an environment variable.  The environment variable will be replaced with its value
    yaml.add_implicit_resolver('!env_var', env_variable_matcher, Loader=yaml.SafeLoader)
    yaml.add_constructor('!env_var', env_variable_parser, Loader=yaml.SafeLoader)
    
    with open(config_file, 'r') as c_file:
        config = yaml.safe_load(c_file)