'How can I explore a dictionary into a dictionary when im consuming an API. Example with PokeAPI

I'm trying to see the value of a key in a nested dictionary consuming an api. The code below iterate each pokemon in a the list of all pokemons and print some of its attributes. I know how to print the value of a single key like height, id, name or base_experience but how can I print the name of each ability?? for example:

JSON CODE

"id": 1,
"height": 7,
"name": "bulbasur",
"abilities": [
    {
      "ability": {
        "name": "overgrow",
        "url": "https://pokeapi.co/api/v2/ability/65/"
      },
      "is_hidden": false,
      "slot": 1
    },
    {
      "ability": {
        "name": "chlorophyll",
        "url": "https://pokeapi.co/api/v2/ability/34/"
      },
      "is_hidden": true,
      "slot": 3
    }
  ]

PYTHON CODE

import requests

def print_restul(json_respnse):
    pokemones = json_respnse.get("results")
    for pokemon in pokemones:
        # print(pokemon)
        explore_pokemon(pokemon)

def explore_pokemon(pokemon):
    url_pokemon = pokemon.get("url")
    r = requests.get(url_pokemon)
    json_respnse = r.json()
    # print(json_respnse.keys())
    print("el id del pokemon {} es {}, y la altura es de {}".format(pokemon.get("name"),json_respnse.get("id"),json_respnse.get("height"),))

if __name__ == "__main__":
    url = 'http://pokeapi.co/api/v2/pokemon'
    r = requests.get(url)
    json_respnse = r.json()
    print_restul(json_respnse)

    for _ in range(10):
        print("== nuevo ciclo for === ")
        url_next = json_respnse.get("next")
        r = requests.get(url_next)
        json_respnse = r.json()
        print_restul(json_respnse)


Solution 1:[1]

Loop over the abilities list and get all the names.

def explore_pokemon(pokemon):
    url_pokemon = pokemon.get("url")
    r = requests.get(url_pokemon)
    json_respnse = r.json()
    # print(json_respnse.keys())
    print("el id del pokemon {} es {}, y la altura es de {}".format(pokemon.get("name"),json_respnse.get("id"),json_respnse.get("height"),))
    abilities = ", ".join(a['ability']['name'] for a in json_response.get("abilities", []))
    print(f'abilities: {abilities}')

Solution 2:[2]

In long run it might be a better idea to model your data as dataclasses instead of python dict objects. It will also promote code quality and code reuse which I feel is a good idea in general.

To work with nested dataclass model and easily generate it from json, I suggest using wiz command-line from dataclass-wizard. This library can be install with pip install dataclass-wizard and then you have access to wiz utility from a terminal to generate a nested dataclass schema.

In this scenario, your code now becomes like below:

def explore_pokemon(pokemon):
    url_pokemon = pokemon.get("url")
    r = requests.get(url_pokemon)
    json_respnse = Data.from_dict(r.json())
    # print(json_respnse.keys())
    print("el id del pokemon {} es {}, y la altura es de {}".format(pokemon.get("name"),json_respnse.id,json_respnse.height),)
    abilities = ", ".join(a.ability.name for a in json_respnse.abilities)
    print(f'abilities: {abilities}')

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Barmar
Solution 2 rv.kvetch