1

I am trying to write a python code for drift management, which compares the application's configuration in JSON with the predefined dictionary of key-value pairs.

Ex: Application configuration in JSON:

{
    "location": "us-east-1",
    "properties": [
        {
            "type": "t2.large",
            "os": "Linux"
        }
    ],
    "sgs": {
        "sgid": "x-1234"
    }
}

Ex: Dictionary with desired values to compare:

{
"os": "Windows",
"location": "us-east-1"
}

Expected output:

Difference is:
{
"os": "Windows"
}

I have been trying to convert the entire JSON (including sub dicts) into a single dict without sub dicts, and then iterate over it with each values of desired dict. I am able to print all the key, values in line but couldn't convert into a dict.

Is there a better way to do this? Or any references that could help me out here?

import json
def openJsonFile(file):
    with open(file) as json_data:
        workData = json.load(json_data)
        return workData

def recursive_iter(obj):
    if isinstance(obj, dict):
        for item in obj.items():
            yield from recursive_iter(item)
    elif any(isinstance(obj, t) for t in (list, tuple)):
        for item in obj:
            yield from recursive_iter(item)
    else:
        yield obj

data =  openJsonFile('file.json')
for item in recursive_iter(data):
    print(item)

Expected output:

{
"location": "us-east-1",
"type": "t2.large",
"os": "Linux"
"sgid": "x-1234"
}
martineau
  • 119,623
  • 25
  • 170
  • 301
SNR
  • 460
  • 5
  • 20

1 Answers1

0

I think this will do what you say you want. I used the dictionary flattening code in this answer with a small modification — I changed it to not concatenate the keys of parent dictionaries with those of the nested ones since that seems to be what you want. This assumes that the keys used in all nested dictionaries are unique from one another, which in my opinion is a weakness of your approach.

You asked for references that could help you: Searching this website for related questions is often a productive way to find solutions to your own problems. This is especially true when what you want to know is something that has probably been asked before (such as how to flatten nested dictionaries).

Also note that I have written the code to closely follow the PEP 8 - Style Guide for Python Code guidelines — which I strongly suggest you read (and start following as well).

import json

desired = {
    "os": "Windows",
    "location": "us-east-1"
}

def read_json_file(file):
    with open(file) as json_data:
        return json.load(json_data)

def flatten(d):
    out = {}
    for key, val in d.items():
        if isinstance(val, dict):
            val = [val]
        if isinstance(val, list):
            for subdict in val:
                deeper = flatten(subdict).items()
                out.update({key2: val2 for key2, val2 in deeper})
        else:
            out[key] = val
    return out

def check_drift(desired, config):
    drift = {}
    for key, value in desired.items():
        if config[key] != value:
            drift[key] = value
    return drift


if __name__ == '__main__':
    from pprint import pprint

    config = flatten(read_json_file('config.json'))
    print('Current configuration (flattened):')
    pprint(config, width=40, sort_dicts=False)
    drift = check_drift(desired, config)
    print()
    print('Drift:')
    pprint(drift, width=40, sort_dicts=False)

This is the output it produces:

Current configuration (flattened):
{'location': 'us-east-1',
 'type': 't2.large',
 'os': 'Linux',
 'sgid': 'x-1234'}

Drift:
{'os': 'Windows'}
martineau
  • 119,623
  • 25
  • 170
  • 301