Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update YAML file programmatically

Tags:

python

yaml

I've a Python dict that comes from reading a YAML file with the usual

yaml.load(stream)

I'd like to update the YAML file programmatically given a path to be updated like:

group1,option1,option11,value

and save the resulting dict again as a yaml file. I'm facing the problem of updating a dicntionary, taking into account that the path is dynamic (let's say a user is able to enter the path through a simple CLI I've created using Cmd).

Any ideas?

thanks!

UPDATE Let me be more specific on the question: The issue is with updating part of a dictionary where I do not know in advance the structure. I'm working on a project where all the configuration is stored on YAML files, and I want to add a CLI to avoid having to edit them by hand. This a sample YAML file, loaded to a dictionary (config-dict) using PyYaml:

config:
 a-function: enable
 b-function: disable
 firewall:
  NET:
   A:
    uplink: enable
    downlink: enable
   B:
    uplink: enable
    downlink: enable
  subscriber-filter:
   cancellation-timer: 180
 service:
  copy:
   DS: enable
  remark:
   header-remark:
    DSC: enable
    remark-table:
 port:
  linkup-debounce: 300
  p0:
   mode: amode
  p1:
   mode: bmode
  p2:
   mode: amode
  p3:
   mode: bmode

I've created the CLI with Cmd, and it's working great even with autocompletion. The user may provide a line like:

config port p1 mode amode

So, I need to edit:

config-dict['config']['port']['p1']['mode'] and set it to 'amode'. Then, use yaml.dump() to create the file again. Another possible line would be:

config a-function enable

So config-dict['config']['a-function'] has to be set to 'enable'.

My problem is when updating the dictionary. If Python passed values as a reference would be easy: Just iterate through the dict until the right value is found and save it. Actually this is what I'm doing for the Cmd autocomplete. But I don't know how to do the update.

Hope I explained myself better now!

Thanks in advance.

like image 293
Ignacio Verona Avatar asked May 28 '14 14:05

Ignacio Verona


1 Answers

In fact the solution follows simple patter: load - modify - dump:

Before playing, be sure you have pyyaml installed:

$ pip install pyyaml

testyaml.py

import yaml
fname = "data.yaml"

dct = {"Jan": {"score": 3, "city": "Karvina"}, "David": {"score": 33, "city": "Brno"}}

with open(fname, "w") as f:
    yaml.dump(dct, f)

with open(fname) as f:
    newdct = yaml.load(f)

print newdct
newdct["Pipi"] = {"score": 1000000, "city": "Stockholm"}

with open(fname, "w") as f:
    yaml.dump(newdct, f)

Resulting data.yaml

$ cat data.yaml
David: {city: Brno, score: 33}
Jan: {city: Karvina, score: 3}
Pipi: {city: Stockholm, score: 1000000}
like image 128
Jan Vlcinsky Avatar answered Oct 15 '22 05:10

Jan Vlcinsky