pythonpython-3.xpyyaml

Array does not have indent or space in PyYAML


In the code below I created the net_plan_dict variable dictionary and converted it into a YAML format file. Inside the dictionary I have a field called addresses which is an array of three elements. After creating the YAML file, the three array elements were not placed under the addresses field :

import yaml

net_plan_dict = {
    'networking': {
        'addresses': ['192.168.1.1', '192.168.1.2', "192.168.1.3"],
        'gateway4': '192.168.121.1'
    }
}

with open("new.yaml", "w") as f:
    yaml.dump(net_plan_dict, f)

Output of the above code is as follows (in the file below, the IPs are not below the address and have no space or indent).

new.yaml:

networking:
  addresses:
  - 192.168.1.1 <-------- does not have indent
  - 192.168.1.2
  - 192.168.1.3
  gateway4: 192.168.121.1


but my goal is to get this output file (how to create this file, when ips are under addresses field):

networking:
  addresses:
    - 192.168.1.1
    - 192.168.1.2
    - 192.168.1.3
  gateway4: 192.168.121.1


Solution

  • PyYAML's dump() doesn't have the fine control to have a different indent for the mappings (2 positions) and sequences (4 positions), nor can it offset the sequence indicator (-) within the space of the (sequence) indent).

    If you want that kind of control over your output you should use ruamel.yaml (disclaimer: I am the author of that package):

    import sys
    import ruamel.yaml
    
    
    net_plan_dict = {
        'networking': {
            'addresses': ['192.168.1.1', '192.168.1.2', "192.168.1.3"],
            'gateway4': '192.168.121.1'
        }
    }
    
    
    yaml = ruamel.yaml.YAML()
    yaml.indent(mapping=2, sequence=4, offset=2)
    yaml.dump(net_plan_dict, sys.stdout)
    

    which gives:

    networking:
      addresses:
        - 192.168.1.1
        - 192.168.1.2
        - 192.168.1.3
      gateway4: 192.168.121.1