Mik Kim
Mik Kim

Reputation: 53

Updating a YAML file in Python

I am updating the following template.yaml file in Python3:

alpha:
  alpha_1: 
  alpha_2: 

beta:
  beta_1: 
  beta_2:
    -  beta_2a:
       beta_2b:

gamma: 

Using ruamel.py I am able to fill the blank space correctly.

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

and updating each element I am able to arrive to:

alpha:
  alpha_1: "val_alpha1"
  alpha_2: "val_alpha2"

beta:
  beta_1: "val_beta1"
  beta_2: 
    -  beta_2a: "val_beta2a"
       beta_2b: "val_beta2b"

gamma: "val_gamma"

Here there is the issue, I may need other children elements in beta_2 node, in this way:

alpha:
  alpha_1: "val_alpha1"
  alpha_2: "val_alpha2"

beta:
  beta_1: "val_beta1"
  beta_2: 
    -  beta_2a: "val_beta2a"
       beta_2b: "val_beta2b"

    -  beta_2c: "val_beta2c"
       beta_2d: "val_beta2d"

gamma: "val_gamma"

I do not know in advance if I could need more branches like above and change the template each time is not an option. My attempts with update() or appending dict were unsuccessful. How can I get the desired result?

My attempt:

entry = config["beta"]["beta_2"]

entry[0]["beta_2a"] = "val_beta2a"
entry[0]["beta_2b"] = "val_beta2b"

entry[0].update = {"beta_2c": "val_beta2a", "beta_2d": "val_beta2d"}

In this case, the program does not display any changes in the results, meaning that the last line with update did not work at all.

Upvotes: 1

Views: 157

Answers (1)

Anthon
Anthon

Reputation: 76578

2022-03-31 16:18:34 ['ryd', '--force', 'so-71693609.ryd']

Your indent is five for the list with a two space offset for the indicator (-), so there is no real need to try and analyse the indent unless some other program changes that.

The value for beta_2 is a list, to get what you want you need to append a dictionary to that list:

import sys
from pathlib import Path
import ruamel.yaml
from ruamel.yaml.scalarstring import DoubleQuotedScalarString as DQ

file_name = Path('template.yaml')

   
yaml = ruamel.yaml.YAML()
yaml.indent(sequence=5, offset=2)
config = yaml.load(file_name)

config['alpha'].update(dict(alpha_1=DQ('val_alpha1'), alpha_2=DQ('val_alpha2')))
config['beta'].update(dict(beta_1=DQ('val_beta1')))
config['gamma'] = DQ('val_gamma')
entry = config["beta"]["beta_2"]

entry[0]["beta_2a"] = DQ("val_beta2a")
entry[0]["beta_2b"] = DQ("val_beta2b")

entry.append(dict(beta_2c=DQ("val_beta2a"), beta_2d=DQ("val_beta2d")))

yaml.dump(config, sys.stdout)

which gives:

alpha:
  alpha_1: "val_alpha1"
  alpha_2: "val_alpha2"
beta:
  beta_1: "val_beta1"
  beta_2:
    -  beta_2a: "val_beta2a"
       beta_2b: "val_beta2b"
    -  beta_2c: "val_beta2a"
       beta_2d: "val_beta2d"
gamma: "val_gamma"

Upvotes: 1

Related Questions