whoisearth whoisearth - 1 year ago 64
JSON Question

skipping a json key if does not exist

I'm running the following:

for server in server_list:
for item in required_fields:
print item, eval(item)

There is a possibility that some keys may not exist, but worse it's represented on a parent key not the one I'm scanning for.

So I'm scanning the json for the following key:


Which doesn't exist but it's actually the parent that is null:


How do I write my code to account for this? It's not giving a key error. Right now I get the following traceback:

Traceback (most recent call last):
File "C:/projects/blah/scripts/test.py", line 29, in <module>
print item, eval(item)
File "<string>", line 1, in <module>
TypeError: 'NoneType' object has no attribute '__getitem__'

Full code:

import csv
import json
import os
import requests
import sys

required_fields = ["server['server_name']","server['server_info']['asset_type']['display_name']",
"server['asset_status']['display_name']", "server['record_owner']['group_name']",
"server['environment']['display_name']", "server['is_virtual']",
"server['managed_by']['display_name']", "server['server_info']['billable_ibm']",
"server['server_info']['serial_number']", "server['location']['display_name']",
"server['inception_date']", "server['server_info']['decommission_date']" ]

# Query API for all servers
def get_servers_info():
servers_info = requests.get('url')
return servers_info.json()

def get_server_info(sid):
server_info = requests.get('url')
return server_info.json()

server_list = get_servers_info()
for server in server_list:
for item in required_fields:
print item, eval(item)

Answer Source

In fact you should avoid eval. After the json load since you know the key name, you can use a list to go deeper in the tree.

server['server_management']['primary_business_owner']['name']" => ["server_management', 'primary_business_owner', 'name']

Here a snippet for a json validation against a list of required fields.

    "d": {
    "a": 3

def _get_attr(dict_, attrs):
        src = attrs[:]
        root = attrs.pop(0)
        node = dict_[root]
        null = object()
        for i, attr in enumerate(attrs[:]):
                node = node.get(attr, null)
            except AttributeError:
                node = null
            if node is null:
                # i+2 pop and last element
                raise ValueError("%s not present (level %s)" % (attr, '->'.join(src[: i+2])))
        return node
    except KeyError:
        raise ValueError("%s not present" % root)

# assume list of required field
reqs = [
    ["d", "p", "r"],
    ["d", "p", "r", "e"],

for req in reqs:
        _get_attr(data, req)
    except ValueError as E:
# prints
# k not present
# e not present (level d->p->r->e)
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download