1

I want to replace the values from YAML file into a JSON file using Python 3.

I have many JSON files where I want to get the values from a master YAML file and replace only certain values like source server ip, email, hostname.

E.g. I have this YAML file (mast_conf.yaml):

-  sourcesystem1:
    sourceServer: 1.2.3.500
    MailTo: gokul@gmail.com
-  sourcesystem2:
    sourceServer1: 2.2.3.500
    sourceServer2: 3.2.3.500
    MailTo: gokul@gmail.com

A JSON file (sourcesystem1.json):

{
    "source":"sourcesystem1",
    "frequency":"daily",
    "sourceServer":"1.2.1.2",
    "hostName":"1.2.1.3",
    "fileFormat":"csv",
    "delimiterType":"semicolon"
}

Another JSON file (sourcesystem2.json):

{
    "source":"sourcesystem2",
    "frequency":"daily",
    "sourceServer":"1.2.3.2",
    "hostName":"1.2.1.7",
    "fileFormat":"csv",
    "delimiterType":"commaseperated"
}

Below is my code I am trying out to parse the value from the json file

import json
import yaml


with open("master_conf.yaml", 'r') as f:
yaml_config = yaml.safe_load(f)


yaml_config = {
list(config.keys()[0]): list(config[config.keys()[0]])
for config in yaml_config
}


json_files = ( "sourcesystem1.json",
"sourcesystem2.json",
)


for json_file in json_files:
with open(json_file, "r") as f:
sourcesystem_conf = json.load(f)


sourcesystem = sourcesystem_conf["source"]


if sourcesystem in yaml_config:
for key, value in yaml_config[sourcesystem].items():
sourcesystem_conf[key] = value


with open(json_file, "w") as f:
json.dump(sourcesystem_conf, f, indent=2)

I am getting the below error by program

TypeError: 'dict_keys' object does not support indexing

When I run indivudually I get this issue for yaml

>>> yaml_config = { ... config.keys()[0]: config[config.keys()[0]] ... for config in yaml_config ... } Traceback (most recent call last): File "<stdin>", line 3, in <module> File "<stdin>", line 3, in <dictcomp> TypeError: 'dict_keys' object is not subscriptable >>>

Is there easier method to achieve my end goal where I want to replace the values in the JSON file from the Yaml configuration file

This is needed to update 1000s of Json file in a automated way for updating it from a master Yaml file

user3764303
  • 29
  • 2
  • 11
  • What about using pyyaml library to load the file (https://pyyaml.org/wiki/PyYAMLDocumentation) and use the json library to build the output ones (https://docs.python.org/fr/3.6/library/json.html) ? – GabrielC May 19 '20 at 10:57
  • 2
    Please describe what exactly your problem with this task is. We are keen to help you figure out errors in your code or explain things you don't understand, but you seem to be just asking for a solution. – flyx May 19 '20 at 10:58

1 Answers1

1

The easiest way is to use pyyaml, see Jon's answer.

Then you can load you yaml file using it :

>>> import yaml
>>> yaml_config = yaml.safe_load(yaml_file)
>>> yaml_config
[{'sourcesystem1': {'MailTo': 'gokul@gmail.com', 'sourceServer': '1.2.3.500'}},
 {'sourcesystem2': {'MailTo': 'gokul@gmail.com',
   'sourceServer1': '2.2.3.500',
   'sourceServer2': '3.2.3.500'}}]

It will be easier to manipulate a dict with source systems as keys.

In python 2 aDict.keys() returns a list so the following will work :

>>> yaml_config = {
    config.keys()[0]: config[config.keys()[0]]
    for config in yaml_config
}
>>> yaml_config
{'sourcesystem1': {'MailTo': 'gokul@gmail.com', 'sourceServer': '1.2.3.500'},
 'sourcesystem2': {'MailTo': 'gokul@gmail.com',
  'sourceServer1': '2.2.3.500',
  'sourceServer2': '3.2.3.500'}}

In python 3 aDict.keys() no longer returns a list so you can simply use a for loop :

yaml_config = {}
for config in yaml_config_raw:
    source = [key for key in config][0]
    yaml_config[source] = config[source]

Then you can just iterate over your json files to update them :

import json
import yaml

with open("mast_conf.yaml", 'r') as f:
    yaml_config_raw = yaml.safe_load(f)


yaml_config = {}
for config in yaml_config_raw:
    source = [key for key in config][0]
    yaml_config[source] = config[source]

json_files = (
    "sourcesystem1.json",
    "sourcesystem2.json",
)

for json_file in json_files:
    with open(json_file, "r") as f:
        sourcesystem_conf = json.load(f)

    sourcesystem = sourcesystem_conf["source"]

    if sourcesystem in yaml_config:
        for key, value in yaml_config[sourcesystem].items():
            sourcesystem_conf[key] = value

    with open(json_file, "w") as f:
        json.dump(sourcesystem_conf, f, indent=2)
H4kim
  • 418
  • 5
  • 8
  • thank you . I tried to run . I am getting this error – user3764303 May 19 '20 at 11:37
  • 1
    sorry it's json.load – H4kim May 19 '20 at 14:09
  • import json import yaml import sys with open("master_conf.yaml", 'r') as f: yaml_config = yaml.safe_load(f) json_file=sys.argv[1] for json_file in json_file: with open(json_file, 'r') as f: sourcesystem_conf = json.load(f) sourcesystem = sourcesystem_conf["source"] if sourcesystem in yaml_config: for key, value in yaml_config[sourcesystem].items(): sourcesystem_conf[key] = value print ('export {}={}'.format(key, value)) with open(json_file, "w") as f: json.dump(sourcesystem_conf, f, indent=2) – user3764303 May 19 '20 at 15:05
  • I am getting the error - FileNotFoundError: [Errno 2] No such file or directory: 't' – user3764303 May 19 '20 at 15:06
  • the values are not getting replaced in the json file here. empty lines are printed. when I print the values – user3764303 May 19 '20 at 15:45
  • It's working for me... Did you use the last version ? – H4kim May 19 '20 at 15:56
  • I am getting this error ,after updating your latest code - TypeError: 'dict_keys' object does not support indexing – user3764303 May 19 '20 at 17:00
  • Traceback (most recent call last): File "parser8.py", line 9, in for config in yaml_config File "parser8.py", line 9, in for config in yaml_config – user3764303 May 19 '20 at 17:03
  • >>> yaml_config = { ... config.keys()[0]: config[config.keys()[0]] ... for config in yaml_config ... } Traceback (most recent call last): File "", line 3, in File "", line 3, in TypeError: 'dict_keys' object is not subscriptable >>> – user3764303 May 20 '20 at 02:59
  • it would be great if you can update the solution here – user3764303 May 20 '20 at 15:27
  • We are not using the same version of python. I updated my answer – H4kim May 21 '20 at 15:38