How to update yaml file using python

python, pyyaml

Solution

The ruamel.yaml package was specifically enhanced (by me starting from PyYAML) to do this kind of round-trip, programmatic, updating.

If you start with (please note I removed the extra initial spaces):

init_config: {}
instances:
    - host: <IP>              # update with IP
      username: <username>    # update with user name
      password: <password>    # update with password

and run:

import ruamel.yaml

file_name = 'input.yaml'
config, ind, bsi = ruamel.yaml.util.load_yaml_guess_indent(open(file_name))

instances = config['instances']
instances[0]['host'] = '1.2.3.4'
instances[0]['username'] = 'Username'
instances[0]['password'] = 'Password'

yaml = ruamel.yaml.YAML()
yaml.indent(mapping=ind, sequence=ind, offset=bsi) 
with open('output.yaml', 'w') as fp:
    yaml.dump(config, fp)

The output will be:

init_config: {}
instances:
    - host: 1.2.3.4           # update with IP
      username: Username      # update with user name
      password: Password      # update with password

The ordering of mapping keys (`host`, `username` and `password`), the style and the comments are preserved without any further specific action.

Instead of having the indent and block sequence indent guessed, you can do a manual traditional load, and set the indent values yourself:

yaml = ruamel.yaml.YAML()
yaml.indent(mapping=6, sequence=4)
with open(file_name) as fp:
    config = yaml.load(fp)

If you look at the history of this answer, you can see how to do this with a more limited, PyYAML like, API.

Problem

I have a `some.yaml` file with the below contents. ``` init_config: {} instances: - host: <IP> username: <username> password: <password> ``` The yaml file should be parsed and updated as below. ``` init_config: {} instances: - host: 1.2.3.4 username: Username password: Password ``` How do I parse the values and update them appropriately?

Original source

Related problems