0

I'm having trouble parsing this json for a particular key:

sample.json:

{
    "AccessToken": {
        "ABCD": {
            "credential_type": "AccessToken",
            "secret": "abcdefghijklmnopqrstuxwxyz",
            "home_account_id": "4dafe035-ff2",
            "environment": "login.microsoftonline.com",
            "client_id": "f16f9f797",
            "target": "Directory.Read.All User.Read profile openid email",
            "realm": "56c621fa50f2",
            "token_type": "Bearer",
            "cached_at": "1599671717",
            "expires_on": "1599675316",
            "extended_expires_on": "1599675316"
        }
    },
    "Account": {
        "EFGH": {
            "home_account_id": "f977-41eb-8241613.56c62bbe-8598-4b85-9e51-1ca753fa50f2",
            "environment": "login.microsoftonline.com",
            "realm": "56c62bbe8598",
            "local_account_id": "4dafe0353-304e48a51613",
            "username": "foo@mail.com",
            "authority_type": "MS"
        }
    },
    "IdToken": {
        "WXYZ": {
            "credential_type": "IdToken",
            "secret": "abcdefghijklmnopqrstuxwxyz",
            "home_account_id": "4dafe035-ff2",
            "environment": "login.microsoftonline.com",
            "realm": "56c6a753fa50f2",
            "client_id": "f169aaf9f797"
        }
    }
}

The goal is to parse and print the "secret" from the "IdToken" section.

abcdefghijklmnopqrstuxwxyz

So far, I can print the entire "IdToken" section, but I just want the secret.

import json

with open('sample.json') as json_file:
    data = json.load(json_file)

print(data['IdToken'])
print(data['IdToken'][0]['secret'])  #Tried this. Doesnot work
Bless
  • 4,071
  • 2
  • 35
  • 39
noober
  • 1,267
  • 3
  • 16
  • 29

2 Answers2

3

You need to do

print(data['IdToken']['WXYZ']['secret'])

When you do data['IdToken'][0], it takes the first element from data['IdToken'] if data['IdToken'] was an array. But here, data['IdToken'] is a dict. To get an element from a dict, you need to use the dict key inside square brackets.

EDIT: (If you don't know the exact key, but only know the position)

JSON doesn't guarantee the order of elements in a map/dict. So, unless you are sure that the items in the dict will appear in a particular order, don't use this solution. But anyways, here is how you do it - you can do print(data['IdToken'][list(data['IdToken'].keys())[0]]['secret']). Also make sure to use OrderedDict while parsing JSON. Check out this answer for that - https://stackoverflow.com/a/47111106/1421222.

Bless
  • 4,071
  • 2
  • 35
  • 39
  • so what if `WXYZ` is some long random string (which I don't want to add in my print) which is why I abbreviated it for this example. Is there a way to do this positionally? In order words, the section IdToken will always be the 3rd record if i'm making sense. thanks. – noober Sep 09 '20 at 19:25
  • JSON parsing doesn't guarantee the order of elements in a map/dict. So, unless you are sure that the items in the dict will be in a particular order, I'd suggest not to use this solution. So here is how you do it - you can do `print(data['IdToken'][list(data['IdToken'].keys())[0]]['secret'])`. Also make sure to use `OrderedDict` while parsing JSON. Check out this answer for that - https://stackoverflow.com/a/47111106/1421222. – Bless Sep 09 '20 at 19:36
  • 1
    Good explanation with context. I will consider both answers as valid. Appreciate it. – noober Sep 09 '20 at 19:43
1

If you want to index on the nested dict of data you should just use its keys and append it on the list where you index on it with an index of [0] to get the first key which is dict to and get the secret

Example

print(data['IdToken'][[*(data['IdToken'].keys())][0]]['secret'])

and the above method will get the key of IdToken and if you don't know it

Umutambyi Gad
  • 3,784
  • 3
  • 13
  • 33