Convert YAML file to python dict

I have the following problem: matching documents in a YAML file with dict and displaying them correctly.

I have the following YAML file, which is a server ( db.yml ):

 instanceId: i-aaaaaaaa environment:us-east serverId:someServer awsHostname:ip-someip serverName:somewebsite.com ipAddr:192.168.0.1 roles:[webserver,php] 

I am loading this YAML file which I can do without any problems. I think I understand that.

 instanceId = getInstanceId() stream = file('db.yml', 'r') dict = yaml.load_all(stream) for key in dict: if key in dict == "instanceId": print key, dict[key] 

I would like the logic to work as follows:

  • download yaml, map to dict
  • look in each dict in the document if instanceId matches what getInstanceId() was set, then print all the keys and values โ€‹โ€‹for this document.

If I look at the map data structure from the command line, I get:

 {'instanceId': 'i-aaaaaaaa environment:us-east serverId:someServer awsHostname:ip-someip serverName:someserver ipAddr:192.168.0.1 roles:[webserver,php]'} 

I think that I could incorrectly create the data structure for the YAML file, and when the content matches the dict I lost a little.

Side note: I cannot load all the documents in this file using yaml.load() , I tried yaml.load_all() , which seems to work, but my main problem still exists.

+30
python dictionary data-structures yaml
source share
4 answers

I think your yaml file should look like (or at least something like this, so it is structured anyway):

 instance: Id: i-aaaaaaaa environment: us-east serverId: someServer awsHostname: ip-someip serverName: somewebsite.com ipAddr: 192.168.0.1 roles: [webserver,php] 

Then yaml.load(...) returns:

 {'instance': {'environment': 'us-east', 'roles': ['webserver', 'php'], 'awsHostname': 'ip-someip', 'serverName': 'somewebsite.com', 'ipAddr': '192.168.0.1', 'serverId': 'someServer', 'Id': 'i-aaaaaaaa'}} 

And you can go from there ...


Used like this:

 >>> for key, value in yaml.load(open('test.txt'))['instance'].iteritems(): print key, value environment us-east roles ['webserver', 'php'] awsHostname ip-someip serverName somewebsite.com ipAddr 192.168.0.1 serverId someServer Id i-aaaaaaaa 
+32
source share

Additional error in code that is not related to YAML:

 for key in dict: if key in dict == "instanceId": # This doesn't do what you want print key, dict[key] 

in is an operator that works in sequence types as well as on cards. This is why this is not a syntax error ... but it does not do what you want.

key in dict will always be evaluated to True , because all keys that you execute are in dict. Thus, your code boils down to True == "instanceId" , which will always evaluate to False , because the boolean value True will never be equal to this string.

You may have noticed that the print statement does not produce any output; this is because it is never called.

+3
source share

Just use python-benedict , it is a subclass of dict that provides I / O support for most common formats, including yaml .

 from benedict import benedict # path can be a yaml string, a filepath or a remote url path = 'path/to/data.yml' d = benedict.from_yaml(path) # do stuff with your dict # ... # write it back to disk d.to_yaml(filepath=path) 

This is well tested and documented, check out the README to see all the features: https://github.com/fabiocaccamo/python-benedict

Install using pip: pip install python-benedict

0
source share

You can use the bios package for python3 as shown below.

 import bios my_dict = bios.read('data.yml') 

bios reads raw data from a file and converts a dict dict object. By file extension, it can determine the type of file.

0
source share

All Articles