William
William

Reputation: 85

TypeError when extracting float key pair value from JSON response

Background - I have a function that takes a variable called api_response (which itself was formatted using api_response = json.loads(response.text) from another function and tries to extract 2x key pair values from it - namely id and percent_complete and print them.

Function -

def unpack_response():
    api_response = api_call()
# Code Block # 1
    while "meta" not in api_response:
        id_value = "id"
        res1 = [val[id_value] for key, val in api_response.items() if id_value in val]
        id_value = "".join(res1)
        percent_value = "percent_complete"
        # The following line of code is referenced in the TypeError  
        res2 = [val['attributes'][percent_value] for key, val in api_response.items() if percent_value in val['attributes']]
        percent_value = "".join(res2)
        print(f' Your data requested, associated with ID: {id_value} is {percent_value} complete!')
        time.sleep(5)
        continue
# Code Block # 2
    if "meta" in api_response:
        print(api_response)
unpack_response()

JSON response (api_response) -

{'data': {'id': '2205853', 'type': 'jobs', 'attributes': {'job_type': 'PORTFOLIO_VIEW_RESULTS', 'started_at': '2021-12-17T02:53:48Z', 'parameters': {'end_date': '2021-12-14', 'output_type': 'json', 'view_id': 304078, 'portfolio_id': 1, 'portfolio_type': 'firm', 'start_date': '2021-12-14'}, 'percent_complete': 0.19, 'status': 'In Progress'}, 'relationships': {'creator': {'links': {'self': '/v1/jobs/2205853/relationships/creator', 'related': '/v1/jobs/2205853/creator'}, 'data': {'type': 'users', 'id': '731221'}}}, 'links': {'self': '/v1/jobs/2205853'}}, 'included': []}

Issue - the function returns the id key value pair without issue and prints (providing I remove all percent_complete-related code), however the "percent_complete" key pair value is causing the following TypeError.

Error -

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-38-8a61597dcee6> in <module>
     16     if "meta" in api_response:
     17         print(api_response)
---> 18 unpack_response()

<ipython-input-38-8a61597dcee6> in unpack_response()
      8         percent_value = "percent_complete"
      9 #         res2 = [val['attributes'][percent_value] for key, val in api_response.items() if percent_value in val['attributes']]
---> 10         res2 = [val['attributes'].get(percent_value, '') for key, val in api_response.items()]
     11         percent_value = "".join(res2)
     12         print(f' Your data requested, associated with ID: {id_value} is {percent_value} complete!')

<ipython-input-38-8a61597dcee6> in <listcomp>(.0)
      8         percent_value = "percent_complete"
      9 #         res2 = [val['attributes'][percent_value] for key, val in api_response.items() if percent_value in val['attributes']]
---> 10         res2 = [val['attributes'].get(percent_value, '') for key, val in api_response.items()]
     11         percent_value = "".join(res2)
     12         print(f' Your data requested, associated with ID: {id_value} is {percent_value} complete!')

TypeError: list indices must be integers or slices, not str

Can anyone help me understand why the id returns without issue (providing I remove all percent_complete-related code), and yet the key pair value of percent_complete does not. Is this something to do with the key pair value being a float?

Upvotes: 0

Views: 80

Answers (1)

William
William

Reputation: 85

Thanks to the many comments (thanks Barmar and rchrome), I have re-writtern my function as follows -

def unpack_response():
    api_response = api_call()
    if "meta" not in api_response:
        id_value = "id"
        res1 = [val[id_value] for key, val in api_response.items() if id_value in val]
        id_value = "".join(res1)
        percent_value = "percent_complete"
        res2 = api_response["data"]["attributes"].get("percent_complete", '')
        print(f' Your data requested, associated with ID: {id_value} is {res2} complete!')
        time.sleep(5)
        api_response = api_call()
    if not "meta" in api_response:
        print(api_response)
unpack_response()

Upvotes: 0

Related Questions