maskeda
maskeda

Reputation: 183

python 3 json parsing specific keys returning errors

I'm building a script to pull the values for stored under the json key ['records']['short_name']. This should return the short name for our applications.

JSON redacted example:

{
  "totalRecords": 214575,
  "nextPageAvailable": true,
  "records": [
    {
      "_id": "xxxxxxxxxxxxxxxx",
      "sys_updated_on": "2019-07-18 14:30:52",
      "short_name": "Application Test"
    }
  ],
  "lastUpdated": "2019-11-08T18:43:42.000Z"
}

My redacted code:

import json
import requests

url = "https://url.com/api/v3/data"

app_query = {"widgetId":"Assets", "asset_type":"Application", "install_status":"Active"}

headers = {
    'authority': "url.com",
    'accept': "application/json, textplain, */*",
    'authorization': "Bearer key_redacted",
    'Host': "url",
    'Accept-Encoding': "gzip, deflate",
    'Connection': "keep-alive",
    'cache-control': "no-cache"
    }

app_data = requests.request("GET", url, headers=headers, params=app_query)

app_json = json.loads(app_data.text)

if app_data.status_code == 200:
    print(app_json['records']['short_name'][0])

elif app_data.status_code == 404:
    print('404 - Not Found.')

The output I get is:

Traceback (most recent call last):
  File "query.py", line 23, in <module>
    print(app_json['records']['short_name'][0])
TypeError: list indices must be integers or slices, not str

Upvotes: 0

Views: 33

Answers (1)

luigibertaco
luigibertaco

Reputation: 1132

The reason for the error is that you are trying to get a key short_name from a list that returns from records.

You just have to change:

print(app_json['records']['short_name'][0])

to

print(app_json['records'][0]['short_name'])

The final code would be:

import json
import requests

url = "https://url.com/api/v3/data"

app_query = {"widgetId":"Assets", "asset_type":"Application", "install_status":"Active"}

headers = {
    'authority': "url.com",
    'accept': "application/json, textplain, */*",
    'authorization': "Bearer key_redacted",
    'Host': "url",
    'Accept-Encoding': "gzip, deflate",
    'Connection': "keep-alive",
    'cache-control': "no-cache"
    }

app_data = requests.request("GET", url, headers=headers, params=app_query)

app_json = json.loads(app_data.text)

if app_data.status_code == 200:
    print(app_json['records'][0]['short_name'])

elif app_data.status_code == 404:
    print('404 - Not Found.')

Pleas be aware that some things could be improved, for example.

app_json = json.loads(app_data.text)

could be replaced with:

app_json = app_data.json()

also, if the records list return a empty list of records, it would also break.

Consider using .get() when collecting data from "unsafe" dicts.

I.e:

app_json.get('records')
# you could optionally set a default value
app_json.get('records', [])

Upvotes: 1

Related Questions