Search code examples
pythonyamlpyyamlruamel.yaml

Yaml dump python dictionary as mapping without single quotes


I want to dump a dict to a yaml file without the surrounding quotes. Basically like a mapping

import yaml

windows_list = []
server_list = ['abc-def-01', 'pqr-str-02']
site_list = ['dev', 'prod']

server_dict = dict(zip(server_list, site_list))

for k,v in server_dict.items():
    a = '{ SERVER: '+k+', SITE: '+v+' }'
    windows_list.append(a)

final_dict = {'service':'something','servers': windows_list}

with open('config.yml', 'w') as yaml_file:
    yaml.dump(final_dict, yaml_file, default_flow_style=False)

The output of config.yml is below:

service: some name
servers:
- '{ SERVER: abc-def-01, SITE: dev }'
- '{ SERVER: pqr-str-02, SITE: prod }'

I do not want the quotes around it. I want it to be a mapping without the quotes

Desired output

service: some name
servers:
- { SERVER: abc-def-01, SITE: dev }
- { SERVER: pqr-str-02, SITE: prod }

I read this post and it says its not possible to remove quotes if you have special characters, but I want to know if there is a workaround of some sort to achieve what I want.


Solution

  • The quotes are needed because the strings you create and dump, look like a flow-style mapping. In other words when you load what you desire you get a different data-structure than what you created "by hand" (or would load from the output you get).

    If you are stuck with such a situation, the best thing to do is load what you want to get and dump the Python datastructure so you know what need to create. That also verifies if what you want is actually YAML:

    import sys
    import ruamel.yaml
    
    yaml_str = """\
    service: some name
    servers:
    - { SERVER: abc-def-01, SITE: dev }
    - { SERVER: pqr-str-02, SITE: prod }
    """
    
    yaml = ruamel.yaml.YAML(typ='safe')
    data = yaml.load(yaml_str)
    print(data)
    

    which gives:

    {'service': 'some name', 'servers': [{'SERVER': 'abc-def-01', 'SITE': 'dev'}, {'SERVER': 'pqr-str-02', 'SITE': 'prod'}]}
    

    As you can see the sequence consists of dictionaries, so that is what you need to append:

    import sys
    import ruamel.yaml
    
    
    windows_list = []
    server_list = ['abc-def-01', 'pqr-str-02']
    site_list = ['dev', 'prod']
    
    server_dict = dict(zip(server_list, site_list))
    
    for k,v in server_dict.items():
        a = { 'SERVER': k, 'SITE': v }
        windows_list.append(a)
    
    final_dict = {'service':'something', 'servers': windows_list}
    
    yaml = ruamel.yaml.YAML()
    yaml.default_flow_style = None
    yaml.dump(final_dict, sys.stdout)
    

    Which results in:

    service: something
    servers:
    - {SERVER: abc-def-01, SITE: dev}
    - {SERVER: pqr-str-02, SITE: prod}
    

    BTW. The recommended extension for YAML files has been .yaml since September 2006.