Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
API call question
#1
Hi,

When you launch an API call to the imdb (movie database) e.g. to retrieve details about a film (e.g. 'TOPKAPI'),
your response is an elaborate dictionary where dictionaries are mixed with lists etc..
In order to "pretty print" this mess, i constructed the code below, which works fine.
But, i feel that this is a bespoke solution for this site. Other responses may be constructed differently.
Is there a more elegant solution?
response = requests.request("GET", url, headers=headers)
dictfilm = response.json()

def prettyStr(k,v):
    print(f'{k} \t  : {v}')

def prettyDict(x):
    for k,v in x.items():
            print(f'{k} \t  : {v}')

def prettyList(x):
    print(f'{x[0]} \t : {x[1]}')
    
for k,v in dictfilm.items():
    if type(v) == str:
        prettyStr(k,v)
    elif type(v) == dict:
        prettyDict(v)
    elif type(v) == list:
        for element in v:
            if type(element) == dict:
                prettyDict(element)
            elif type(element) == list:
                prettyList(element)
            else:
                print('You forgot this piece')               
    else:
        print('You forgot this piece')
thx,
Paul
Output:
{'id': 'tt0058672', 'title': 'Topkapi\xa0', 'year': '1964', 'length': '2h', 'rating': '7.0', 'rating_votes': '7904', 'poster': 'https://m.media-amazon.com/images/M/MV5BMTM2MTcyNDQ4Nl5BMl5BanBnXkFtZTcwMzQxNDY3NA@@.jpg', 'plot': 'A conman gets mixed up with a group of thieves who plan to rob an Istanbul museum to steal a jewelled dagger.', 'trailer': {'id': 'vi1705313561', 'link': 'https://www.imdb.com/videoplayer/vi1705313561'}, 'cast': [{'actor': 'Melina Mercouri', 'actor_id': 'nm0580479', 'character': 'Elizabeth Lipp'}, {'actor': 'Peter Ustinov', 'actor_id': 'nm0001811', 'character': 'Arthur Simon Simpson'}, {'actor': 'Maximilian Schell', 'actor_id': 'nm0001703', 'character': 'Walter Harper'}, {'actor': 'Robert Morley', 'actor_id': 'nm0605923', 'character': 'Cedric Page'}, {'actor': 'Jess Hahn', 'actor_id': 'nm0353916', 'character': 'Hans Fisher'}, {'actor': 'Gilles Ségal', 'actor_id': 'nm0845329', 'character': 'Giulio the Human Fly'}, {'actor': 'Akim Tamiroff', 'actor_id': 'nm0848667', 'character': 'Gerven - the Cook'}, {'actor': 'Titos Vandis', 'actor_id': 'nm0888937', 'character': 'Harback (as Titos Wandis)'}, {'actor': 'Ege Ernart', 'actor_id': 'nm0259623', 'character': 'Maj. Ali Tufan'}, {'actor': 'Senih Orkan', 'actor_id': 'nm0649901', 'character': 'First Shadow'}, {'actor': 'Ahmet Danyal Topatan', 'actor_id': 'nm0867626', 'character': 'Second Shadow'}, {'actor': 'Joe Dassin', 'actor_id': 'nm0202087', 'character': 'Josef'}, {'actor': 'Despo Diamantidou', 'actor_id': 'nm0221615', 'character': 'Voula'}], 'technical_specs': [['Runtime', '2 hr (120 min)'], ['Sound Mix', 'Mono (Westrex Recording System)'], ['Color', 'Color (Technicolor)'], ['Aspect Ratio', '1.66 : 1 (intended ratio)'], ['Laboratory', 'Laboratoires Franay Tirages Cinematographiques (LTC), Paris, France (as Franay L.T.C. St. Cloud)'], ['Negative Format', '35 mm'], ['Cinematographic Process', 'Spherical'], ['Printed Film Format', '35 mm']]}
It is more important to do the right thing, than to do the thing right.(P.Drucker)
Better is the enemy of good. (Montesquieu) = French version for 'kiss'.
Reply
#2
I did something similar here for another API, maybe you can deduce something from it

import requests

quote = "'"
i = 1
for page in range(1, 3):
    url = f'https://exclusive.radio/app//wp-json/wp/v2/stations/?page={page}&orderby=title&order=asc&_embed=true&per_page=99&search=&station_category=3'
    data = requests.get(url)
    
    if data:
        a = (data.json())
        for b in a:
            name = b.get("title")["rendered"].replace("Exclusively ", "").replace("Exclusively-", "").replace("’", quote).replace("&", "& ")
            if name.startswith("-") and name.endswith("-"):
                name = name.replace("-", "")
            url = b.get("_exr_postmeta_stream")
            line = f'{name},{url}'
            print(line)
            i += 1
print(f"{i} Stations")
Reply
#3
It seems that you get a prettier layout if you print it like this:
print(json.dumps(dictfilm, sort_keys=True, indent=4))
But still not presentable Dodgy

Paul
It is more important to do the right thing, than to do the thing right.(P.Drucker)
Better is the enemy of good. (Montesquieu) = French version for 'kiss'.
Reply
#4
Out of interest, why do you want to pretty print the JSON? It is a format really meant to be consumed by machines (which obviously don't care about the formatting), so if you're wanting to output it for humans, you probably want to print it out in your own way anyway.
Reply
#5
(Aug-29-2020, 06:00 AM)ndc85430 Wrote: Out of interest, why do you want to pretty print the JSON? It is a format really meant to be consumed by machines (which obviously don't care about the formatting), so if you're wanting to output it for humans, you probably want to print it out in your own way anyway.

This format is what the API call returns. I would like to (1) filter it, (2) report on it.

I will "standardise" the info, by converting it info 1 long, simple dict.
Then i can do whatever is required, easily.

It would be more "user-friendly", to use a popular term from the eighties, to deliver
the data like that in the first place. Machines would still be able to read it. Smile

Paul
It is more important to do the right thing, than to do the thing right.(P.Drucker)
Better is the enemy of good. (Montesquieu) = French version for 'kiss'.
Reply
#6
I usually just use pprint to get a better display for myself.
The json.dumps as mention should give better formatted display.

With pprint.
import requests
from pprint import pprint
import json

response = requests.get('http://api.open-notify.org/astros.json')
pprint(response.json())
Output:
{'message': 'success', 'number': 3, 'people': [{'craft': 'ISS', 'name': 'Chris Cassidy'}, {'craft': 'ISS', 'name': 'Anatoly Ivanishin'}, {'craft': 'ISS', 'name': 'Ivan Vagner'}]}
With json.dumps
import requests
from pprint import pprint
import json

response = requests.get('http://api.open-notify.org/astros.json')
print(json.dumps(response.json(), indent=2, sort_keys=True))
Output:
{ "message": "success", "number": 3, "people": [ { "craft": "ISS", "name": "Chris Cassidy" }, { "craft": "ISS", "name": "Anatoly Ivanishin" }, { "craft": "ISS", "name": "Ivan Vagner" } ] }
In browser i use JSONView.
[Image: ubMxpI.png]
So you see that json.dumps and JSONView show the same formatted way.
The display is more for myself to see how it's formatted,i usually parse out values that i need or present for the users.
Reply
#7
(Aug-29-2020, 08:42 AM)snippsat Wrote: The display is more for myself to see how it's formatted,i usually parse out values that i need or present for the users.

Agreed!
Paul
It is more important to do the right thing, than to do the thing right.(P.Drucker)
Better is the enemy of good. (Montesquieu) = French version for 'kiss'.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020