Not able to get specific object from a json response using python - python

I have the following as part of a function to extract some info from a json response (at the bottom you can find a portion of it), and is working fine. But......
venues_list=[]
url = 'https://api.foursquare.com/v2/venues/search?client_id={}&client_secret={}&ll={},{}&v={}&categoryId={}&radius={}&limit={}'.format(CLIENT_ID, CLIENT_SECRET, lat, lng, VERSION, search_categoryId, radius, LIMIT)
results = requests.get(url).json()["response"]['venues']
venues_list.append([(
v['name'],
v['location']['lat'],
v['location']['lng'],
v['categories'][0]['name'],
v['id']) for v in results])
To the mix of objects I'm retrieving from the json file, i want to add:
v['location']['postalCode']
But is not working. I get a KeyError: 'postalCode'
If I do:
v['location']['distance']
v['location']['country']
v['location']['formattedAddress']
It works. I get no error.
These don't work either:
v['location']['cc']
v['location']['city']
I get the same KeyError: 'cc' , KeyError: 'city'
Is there something I'm missing? Can you help me understand why it behaves this way?
[{'id': '4ad4c061f964a52099f720e3',
'name': 'Live Organic Food Bar',
'location': {'address': '264 Dupont Street',
'lat': 43.67505287052667,
'lng': -79.40671518307245,
'labeledLatLngs': [{'label': 'display',
'lat': 43.67505287052667,
'lng': -79.40671518307245}],
'distance': 273,
'postalCode': 'M5R 1V7',
'cc': 'CA',
'city': 'Toronto',
'state': 'ON',
'country': 'Canada',
'formattedAddress': ['264 Dupont Street', 'Toronto ON M5R 1V7', 'Canada']},
'categories': [{'id': '4bf58dd8d48988d1d3941735',
'name': 'Vegetarian / Vegan Restaurant',
'pluralName': 'Vegetarian / Vegan Restaurants',
'shortName': 'Vegetarian / Vegan',
'icon': {'prefix': 'https://ss3.4sqi.net/img/categories_v2/food/vegetarian_',
'suffix': '.png'},
'primary': True}],
'referralId': 'v-1591407049',
'hasPerk': False},

Related

Extracting Text from Json Geocodio API

I'm using the Geocodio API to find congreessional district information for a given address. Here's my code:
from geocodio import GeocodioClient
import json
client = GeocodioClient('MY API KEY')
availible_offices = ['Congress', 'State Legislature']
# offices_dict = ['cd': "Congress",'stateleg': "State Legislature"]
location = str(client.geocode("100 Renaissance Center, Detroit, MI 48243",fields=["cd", "stateleg"]))
print(location)
json.loads(location)
Here's the json it prints:
{'input': {'address_components': {'number': '100', 'street': 'Renaissance', 'suffix': 'Ctr', 'formatted_street': 'Renaissance Ctr', 'city': 'Detroit', 'state': 'MI', 'zip': '48243', 'country': 'US'}, 'formatted_address': '100 Renaissance Ctr, Detroit, MI 48243'}, 'results': [{'address_components': {'number': '100', 'street': 'Renaissance', 'suffix': 'Ctr', 'formatted_street': 'Renaissance Ctr', 'city': 'Detroit', 'county': 'Wayne County', 'state': 'MI', 'zip': '48243', 'country': 'US'}, 'formatted_address': '100 Renaissance Ctr, Detroit, MI 48243', 'location': {'lat': 42.329033, 'lng': -83.039762}, 'accuracy': 1, 'accuracy_type': 'rooftop', 'source': 'Semcog', 'fields': {'congressional_districts': [{'name': 'Congressional District 14', 'district_number': 14, 'congress_number': '117th', 'congress_years': '2021-2023', 'proportion': 1, 'current_legislators': [{'type': 'representative', 'bio': {'last_name': 'Lawrence', 'first_name': 'Brenda', 'birthday': '1954-10-18', 'gender': 'F', 'party': 'Democrat'}, 'contact': {'url': 'https://lawrence.house.gov', 'address': '2463 Rayburn House Office Building Washington DC 20515-2214', 'phone': '202-225-5802', 'contact_form': None}, 'social': {'rss_url': None, 'twitter': 'RepLawrence', 'facebook': '395759603917487', 'youtube': None, 'youtube_id': 'UCf0USy9GNigkB8O9sS1dodw'}, 'references': {'bioguide_id': 'L000581', 'thomas_id': '02252', 'opensecrets_id': 'N00034068', 'lis_id': None, 'cspan_id': '79924', 'govtrack_id': '412638', 'votesmart_id': '78851', 'ballotpedia_id': 'Brenda Lawrence (Michigan)', 'washington_post_id': None, 'icpsr_id': '21530', 'wikipedia_id': 'Brenda Lawrence'}, 'source': 'Legislator data is originally collected and aggregated by https://github.com/unitedstates/'}, {'type': 'senator', 'bio': {'last_name': 'Stabenow', 'first_name': 'Debbie', 'birthday': '1950-04-29', 'gender': 'F', 'party': 'Democrat'}, 'contact': {'url': 'https://www.stabenow.senate.gov', 'address': '731 Hart Senate Office Building Washington DC 20510', 'phone': '202-224-4822', 'contact_form': 'https://www.stabenow.senate.gov/contact'}, 'social': {'rss_url': 'http://stabenow.senate.gov/rss/?p=news', 'twitter': 'SenStabenow', 'facebook': 'SenatorStabenow', 'youtube': 'senatorstabenow', 'youtube_id': 'UCFoDKCvxSwCUfDv-4Eg4K5A'}, 'references': {'bioguide_id': 'S000770', 'thomas_id': '01531', 'opensecrets_id': 'N00004118', 'lis_id': 'S284', 'cspan_id': '45451', 'govtrack_id': '300093', 'votesmart_id': '515', 'ballotpedia_id': 'Debbie Stabenow', 'washington_post_id': None, 'icpsr_id': '29732', 'wikipedia_id': 'Debbie Stabenow'}, 'source': 'Legislator data is originally collected and aggregated by https://github.com/unitedstates/'}, {'type': 'senator', 'bio': {'last_name': 'Peters', 'first_name': 'Gary', 'birthday': '1958-12-01', 'gender': 'M', 'party': 'Democrat'}, 'contact': {'url': 'https://www.peters.senate.gov', 'address': '724 Hart Senate Office Building Washington DC 20510', 'phone': '202-224-6221', 'contact_form': 'https://www.peters.senate.gov/contact/email-gary'}, 'social': {'rss_url': None, 'twitter': 'SenGaryPeters', 'facebook': 'SenGaryPeters', 'youtube': 'RepGaryPeters', 'youtube_id': 'UC7LYNbnKSK2VZqQ98YROWHQ'}, 'references': {'bioguide_id': 'P000595', 'thomas_id': '01929', 'opensecrets_id': 'N00029277', 'lis_id': 'S380', 'cspan_id': '50199', 'govtrack_id': '412305', 'votesmart_id': '8749', 'ballotpedia_id': 'Gary Peters', 'washington_post_id': None, 'icpsr_id': '20923', 'wikipedia_id': 'Gary Peters'}, 'source': 'Legislator data is originally collected and aggregated by https://github.com/unitedstates/'}]}], 'state_legislative_districts': {'house': {'name': 'State House District 6', 'district_number': '6', 'is_upcoming_state_legislative_district': False}, 'senate': {'name': 'State Senate District 1', 'district_number': '1', 'is_upcoming_state_legislative_district': False}}}}]}
Here's the error that I get:
Traceback (most recent call last):
File "/Users/aliallam/Desktop/APCSP/Create Task/Main.py", line 13, in <module>
json.loads(location)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/json/__init__.py", line 357, in loads
return _default_decoder.decode(s)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/json/decoder.py", line 353, in raw_decode
obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
I want to extract certain parts of the json and print them. Why am I getting this error and how do I go about doing that?
Thanks in advance!
Use eval():
dataj = eval(location)
dataj.keys()
Output:
dict_keys(['input', 'results'])

For loop in a dictionary inside a dictionary for dataframe construction in herepy (PlacesAPI)

I am using Python and I am trying to access the result of function PlacesAPI where I can see supermarkets around me and create a dataframe with few parts of each dictionary inside the main dictionary using a for loop, however I am getting the same information for different rows.
Can you please help me to put each different parts of dictionary in a different row?
Here is my code and the result (now reproducible):
from herepy import PlacesApi
import pandas as pd
def dataframe():
a = {'items': [{'title': 'Marcos Francisco dos Santos Padaria e Mercearia',
'id': 'here:pds:place:07675crc-dfd72cbf57bd45cc9277ed8530ffd61b',
'ontologyId': 'here:cm:ontology:supermarket',
'resultType': 'place',
'address': {'label': 'Marcos Francisco dos Santos Padaria e Mercearia, Rua Oswero Carmo Vilaça, 33, Petrópolis - RJ, 25635-101, Brazil',
'countryCode': 'BRA',
'countryName': 'Brazil',
'stateCode': 'RJ',
'state': 'Rio de Janeiro',
'city': 'Petrópolis',
'district': 'Petrópolis',
'street': 'Rua Oswero Carmo Vilaça',
'postalCode': '25635-101',
'houseNumber': '33'},
'position': {'lat': -22.5315, 'lng': -43.16904},
'access': [{'lat': -22.5314, 'lng': -43.16914}],
'distance': 134,
'categories': [{'id': '600-6300-0066', 'name': 'Grocery', 'primary': True},
{'id': '600-6300-0244', 'name': 'Bakery & Baked Goods Store'}],
'contacts': [{'phone': [{'value': '+552422312493'}]}]},
{'title': 'Mr. Frango',
'id': 'here:pds:place:076jx7ps-7c214f50052f0c23c9e5422ebde7d3cd',
'ontologyId': 'here:cm:ontology:supermarket',
'resultType': 'place',
'address': {'label': 'Mr. Frango, Rua Teresa, Petrópolis - RJ, 25635-530, Brazil',
'countryCode': 'BRA',
'countryName': 'Brazil',
'stateCode': 'RJ',
'state': 'Rio de Janeiro',
'city': 'Petrópolis',
'district': 'Petrópolis',
'street': 'Rua Teresa',
'postalCode': '25635-530'},
'position': {'lat': -22.52924, 'lng': -43.17222},
'access': [{'lat': -22.52925, 'lng': -43.1722}],
'distance': 545,
'categories': [{'id': '600-6300-0066', 'name': 'Grocery', 'primary': True},
{'id': '600-6000-0061', 'name': 'Convenience Store'}],
'references': [{'supplier': {'id': 'core'}, 'id': '1159487213'}],
'contacts': [{'phone': [{'value': '+552422201010'},
{'value': '+552422315720', 'categories': [{'id': '600-6000-0061'}]}]}]},
{'title': 'Mercadinho Flor de Petrópolis',
'id': 'here:pds:place:07675crc-6b03dfbac65a45c0bfc52ab9a3f04556',
'ontologyId': 'here:cm:ontology:supermarket',
'resultType': 'place',
'address': {'label': 'Mercadinho Flor de Petrópolis, Rua Teresa, 2060, Petrópolis - RJ, 25635-530, Brazil',
'countryCode': 'BRA',
'countryName': 'Brazil',
'stateCode': 'RJ',
'state': 'Rio de Janeiro',
'city': 'Petrópolis',
'district': 'Petrópolis',
'street': 'Rua Teresa',
'postalCode': '25635-530',
'houseNumber': '2060'},
'position': {'lat': -22.52895, 'lng': -43.17233},
'access': [{'lat': -22.52895, 'lng': -43.17219}],
'distance': 574,
'categories': [{'id': '600-6300-0066',
'name': 'Grocery',
'primary': True}]}]}
value = []
address = []
latlong = []
teste = pd.DataFrame(columns = ['nome','endereco','rua','numero',
'cidade','estado','cep','lat','long','raio'])
teste['nome'] = []
teste['endereco'] = []
teste['rua'] = []
teste['numero'] =[]
teste['cidade'] = []
teste['estado'] = []
teste['cep'] = []
teste['lat'] = []
teste['long'] = []
teste['raio'] = []
g = pd.DataFrame.from_dict(a.values())
h =[]
for i in range(3):
v = g[i].values[0]
h = v.items()
for k, l in h:
value.append(l)
for c, d in value[4].items():
address.append(d)
for la, lo in value[5].items():
latlong.append(lo)
novo_concorrente = {'nome': value[0], 'endereco':address[0],
'rua':address[7], 'numero':address[9],
'cidade':address[5], 'estado':address[3],
'cep':address[8],'lat':latlong[0],
'long':latlong[1],'raio':value[7]}
teste = teste.append(novo_concorrente, ignore_index=True)
return teste
You should focus on your for loop. I would suggest you to create a dictionary for each row you want to define in your final DataFrame, and then create a list to append those dictionaries to.
In example:
rows = []
for item in a["items"]:
row = {
"Latitude": item["position"]["lat"],
"Postal code": item["address"]["postalCode"],
}
rows.append(row)
result = DataFrame(rows)
result
Hope it helps as a starting point.

How save a json file in python from api response when the class is a list and object is not serializable

I have tried to find the answer but I could not find it
I am looking for the way to save in my computer a json file from python.
I call the API
configuration = api.Configuration()
configuration.api_key['X-XXXX-Application-ID'] = 'xxxxxxx'
configuration.api_key['X-XXX-Application-Key'] = 'xxxxxxxx1'
## List our parameters as search operators
opts= {
'title': 'Deutsche Bank',
'body': 'fraud',
'language': ['en'],
'published_at_start': 'NOW-7DAYS',
'published_at_end': 'NOW',
'per_page': 1,
'sort_by': 'relevance'
}
try:
## Make a call to the Stories endpoint for stories that meet the criteria of the search operators
api_response = api_instance.list_stories(**opts)
## Print the returned story
pp(api_response.stories)
except ApiException as e:
print('Exception when calling DefaultApi->list_stories: %s\n' % e)
I got the response like this
[{'author': {'avatar_url': None, 'id': 1688440, 'name': 'Pranav Nair'},
'body': 'The law firm will investigate whether the bank or its officials have '
'engaged in securities fraud or unlawful business practices. '
'Industries: Bank Referenced Companies: Deutsche Bank',
'categories': [{'confident': False,
'id': 'IAB11-5',
'level': 2,
'links': {'_self': 'https://,
'parent': 'https://'},
'score': 0.39,
'taxonomy': 'iab-qag'},
{'confident': False,
'id': 'IAB3-12',
'level': 2,
'links': {'_self': 'https://api/v1/classify/taxonomy/iab-qag/IAB3-12',
'score': 0.16,
'taxonomy': 'iab-qag'},
'clusters': [],
'entities': {'body': [{'indices': [[168, 180]],
'links': {'dbpedia': 'http://dbpedia.org/resource/Deutsche_Bank'},
'score': 1.0,
'text': 'Deutsche Bank',
'types': ['Bank',
'Organisation',
'Company',
'Banking',
'Agent']},
{'indices': [[80, 95]],
'links': {'dbpedia': 'http://dbpedia.org/resource/Securities_fraud'},
'score': 1.0,
'text': 'securities fraud',
'types': ['Practice', 'Company']},
'hashtags': ['#DeutscheBank', '#Bank', '#SecuritiesFraud'],
'id': 3004661328,
'keywords': ['Deutsche',
'behalf',
'Bank',
'firm',
'investors',
'Deutsche Bank',
'bank',
'fraud',
'unlawful'],
'language': 'en',
'links': {'canonical': None,
'coverages': '/coverages?story_id=3004661328',
'permalink': 'https://www.snl.com/interactivex/article.aspx?KPLT=7&id=58657069',
'related_stories': '/related_stories?story_id=3004661328'},
'media': [],
'paragraphs_count': 1,
'published_at': datetime.datetime(2020, 5, 19, 16, 8, 5, tzinfo=tzutc()),
'sentences_count': 2,
'sentiment': {'body': {'polarity': 'positive', 'score': 0.599704},
'title': {'polarity': 'neutral', 'score': 0.841333}},
'social_shares_count': {'facebook': [],
'google_plus': [],
'source': {'description': None,
'domain': 'snl.com',
'home_page_url': 'http://www.snl.com/',
'id': 8256,
'links_in_count': None,
'locations': [{'city': 'Charlottesville',
'country': 'US',
'state': 'Virginia'}],
'logo_url': None,
'name': 'SNL Financial',
'scopes': [{'city': None,
'country': 'US',
'level': 'national',
'state': None},
{'city': None,
'country': None,
'level': 'international',
'state': None}],
'title': None},
'summary': {'sentences': ['The law firm will investigate whether the bank or '
'its officials have engaged in securities fraud or '
'unlawful business practices.',
'Industries: Bank Referenced Companies: Deutsche '
'Bank']},
'title': "Law firm to investigate Deutsche Bank's US ops on behalf of "
'investors',
'translations': {'en': None},
'words_count': 26}]
In the documentation says "Stories you retrieve from the API are returned as JSON objects by default. These JSON story objects contain 22 top-level fields, whereas a full story object will contain 95 unique data points"​
The class is a list. When I have tried to save json file I have the error "TypeError: Object of type Story is not JSON serializable".
How I can save a json file in my computer?
The response you got is not json, json uses double quotes, but here its single quotes. Copy paste your response in the following link to see the issues
http://json.parser.online.fr/.
If you change it like
[{"author": {"avatar_url": None, "id": 1688440, "name": "Pranav Nair"},
"body": "......
It will work, You can use python json module to do it
import json
json.loads(the_dict_got_from_response).
But it should be the duty of the API provider to, To make it working you can json load the result you got.

how can i write a function that takes in a list of restaurants as an argument and returns a list of only the restaurants that are not closed?

fork_fig = {'categories': [{'alias': 'burgers', 'title': 'Burgers'},
{'alias': 'sandwiches', 'title': 'Sandwiches'},
{'alias': 'salad', 'title': 'Salad'}],
'coordinates': {'latitude': 35.10871, 'longitude': -106.56739},
'display_phone': '(505) 881-5293',
'distance': 3571.724649307866,
'id': 'fork-and-fig-albuquerque',
'image_url': 'https://s3-media1.fl.yelpcdn.com/bphoto/_-DpXKfS3jv6DyA47g6Fxg/o.jpg',
'is_closed': False,
'location': {'address1': '6904 Menaul Blvd NE',
'address2': 'Ste C',
'address3': '',
'city': 'Albuquerque',
'country': 'US',
'display_address': ['6904 Menaul Blvd NE', 'Ste C', 'Albuquerque, NM 87110'],
'state': 'NM',
'zip_code': '87110'},
'name': 'Fork & Fig',
'phone': '+15058815293',
'price': '$$',
'rating': 4.5,
'review_count': 604}
frontier_restaurant = {'categories': [{'alias': 'mexican', 'title': 'Mexican'},
{'alias': 'diners', 'title': 'Diners'},
{'alias': 'tradamerican', 'title': 'American (Traditional)'}],
'coordinates': {'latitude': 35.0808088832532, 'longitude': -106.619402244687},
'display_phone': '(505) 266-0550',
'distance': 4033.6583235266075,
'id': 'frontier-restaurant-albuquerque-2',
'image_url': 'https://s3-media4.fl.yelpcdn.com/bphoto/M9L2z6-G0NobuDJ6YTh6VA/o.jpg',
'is_closed': True,
'location': {'address1': '2400 Central Ave SE',
'address2': '',
'address3': '',
'city': 'Albuquerque',
'country': 'US',
'display_address': ['2400 Central Ave SE', 'Albuquerque, NM 87106'],
'state': 'NM',
'zip_code': '87106'},
'name': 'Frontier Restaurant',
'phone': '+15052660550',
'price': '$',
'rating': 4.0,
'review_count': 1369}
I have two restaurant list as above and i want to make function that returns a list of only the restaurants that are not closed by using conditional loops.
restaurants = [fork_fig, frontier_restaurant]
open_restaurants(restaurants)[0]['name'] ###I want restaurant name to be appear
Below is the code that I've been working on and cannot quite sure how I can fix this to get the value that I want to return.
def open_restaurants(restaurants):
selected = []
for i in restaurants:
if fork_fig['is_closed']:
selected = restaurants[1]
else:
selected = restaurants[0]
return selected
Continuing from the comment:
fork_fig = {'categories': [{'alias': 'burgers', 'title': 'Burgers'},
{'alias': 'sandwiches', 'title': 'Sandwiches'},
{'alias': 'salad', 'title': 'Salad'}],
'coordinates': {'latitude': 35.10871, 'longitude': -106.56739},
'display_phone': '(505) 881-5293',
'distance': 3571.724649307866,
'id': 'fork-and-fig-albuquerque',
'image_url': 'https://s3-media1.fl.yelpcdn.com/bphoto/_-DpXKfS3jv6DyA47g6Fxg/o.jpg',
'is_closed': False,
'location': {'address1': '6904 Menaul Blvd NE',
'address2': 'Ste C',
'address3': '',
'city': 'Albuquerque',
'country': 'US',
'display_address': ['6904 Menaul Blvd NE', 'Ste C', 'Albuquerque, NM 87110'],
'state': 'NM',
'zip_code': '87110'},
'name': 'Fork & Fig',
'phone': '+15058815293',
'price': '$$',
'rating': 4.5,
'review_count': 604}
frontier_restaurant = {'categories': [{'alias': 'mexican', 'title': 'Mexican'},
{'alias': 'diners', 'title': 'Diners'},
{'alias': 'tradamerican', 'title': 'American (Traditional)'}],
'coordinates': {'latitude': 35.0808088832532, 'longitude': -106.619402244687},
'display_phone': '(505) 266-0550',
'distance': 4033.6583235266075,
'id': 'frontier-restaurant-albuquerque-2',
'image_url': 'https://s3-media4.fl.yelpcdn.com/bphoto/M9L2z6-G0NobuDJ6YTh6VA/o.jpg',
'is_closed': True,
'location': {'address1': '2400 Central Ave SE',
'address2': '',
'address3': '',
'city': 'Albuquerque',
'country': 'US',
'display_address': ['2400 Central Ave SE', 'Albuquerque, NM 87106'],
'state': 'NM',
'zip_code': '87106'},
'name': 'Frontier Restaurant',
'phone': '+15052660550',
'price': '$',
'rating': 4.0,
'review_count': 1369}
restaurants = [fork_fig, frontier_restaurant]
def open_restaurants(restaurants):
selected = []
for i in restaurants:
if 'is_closed' in i:
if not i['is_closed']:
selected.append(i['name'])
return selected
print(open_restaurants(restaurants))
OUTPUT:
['Fork & Fig']
Shorter-version:
Using list-comprehension:
def open_restaurants(restaurants):
return [x['name'] for x in restaurants if 'is_closed' in x and not x["is_closed"]]
print(open_restaurants(restaurants))
Using get() instead of indexing:
def open_restaurants(restaurants):
return [x['name'] for x in restaurants if 'name' in x and not x.get('is_closed', True)]
print(open_restaurants(restaurants))
Use the filter function:
def open_restaurants(restaurants):
return filter(lambda r: not r['is_closed'], restaurants)
Use List Comprehension here. Its one line and easy to read
open_restaurants = [restaurant.get("name") for restaurant in restaurants if not restaurant.get("is_closed")]
Output: ["Fork & Fig"]
There is a simple way to append all your open restaurants to a new list and print their names.
You will need two loops to accomplish this.
Here is how to do it:
restaurants = [fork_fig, frontier_restaurant] # a list of restaurants
def open_restaurants(restaurants):
selected = []
for i in restaurants: # append all open restaurants to a new list
if not i['is_closed']:
selected.append(i)
return selected
my_open_restaurants = open_restaurants(restaurants) # call the function
for rest in my_open_restaurants: # print all the names
print(rest['name'])
In your example the output will be: Fork & Fig

Python parsing JSON nested data

I am trying to parse this JSON data from the setlist.fm api. I am trying to get all the song names in order from each setlist. I have looked around but none of the methods describe on the internet are working.
Here is the JSON data
{'itemsPerPage': 20,
'page': 1,
'setlist': [{'artist': {'disambiguation': '',
'mbid': 'cc197bad-dc9c-440d-a5b5-d52ba2e14234',
'name': 'Coldplay',
'sortName': 'Coldplay',
'tmid': 806431,
'url': 'https://www.setlist.fm/setlists/coldplay-3d6bde3.html'},
'eventDate': '15-11-2017',
'id': '33e0845d',
'info': 'Last show of the A Head Full of Dreams Tour',
'lastUpdated': '2017-11-23T14:51:05.000+0000',
'sets': {'set': [{'song': [{'cover': {'disambiguation': '',
'mbid': '9dee40b2-25ad-404c-9c9a-139feffd4b57',
'name': 'Maria Callas',
'sortName': 'Callas, Maria',
'url': 'https://www.setlist.fm/setlists/maria-callas-33d6706d.html'},
'name': 'O mio babbino caro',
'tape': True},
{'info': 'extended intro with Charlie '
'Chaplin speech',
'name': 'A Head Full of Dreams'},
{'name': 'Yellow'},
{'name': 'Every Teardrop Is a '
'Waterfall'},
{'name': 'The Scientist'},
{'info': 'with "Oceans" excerpt in '
'intro',
'name': 'God Put a Smile Upon Your '
'Face'},
{'info': 'with Tiësto Remix outro',
'name': 'Paradise'}]},
{'name': 'B-Stage',
'song': [{'name': 'Always in My Head'},
{'name': 'Magic'},
{'info': 'single version',
'name': 'Everglow'}]},
{'name': 'A-Stage',
'song': [{'info': 'with "Army of One" excerpt '
'in intro',
'name': 'Clocks'},
{'info': 'partial',
'name': 'Midnight'},
{'name': 'Charlie Brown'},
{'name': 'Hymn for the Weekend'},
{'info': 'with "Midnight" excerpt in '
'intro',
'name': 'Fix You'},
{'name': 'Viva la Vida'},
{'name': 'Adventure of a Lifetime'},
{'cover': {'disambiguation': '',
'mbid': '3f8a5e5b-c24b-4068-9f1c-afad8829e06b',
'name': 'Soda Stereo',
'sortName': 'Soda Stereo',
'tmid': 1138263,
'url': 'https://www.setlist.fm/setlists/soda-stereo-7bd6d204.html'},
'name': 'De música ligera'}]},
{'name': 'C-Stage',
'song': [{'info': 'extended',
'name': 'Kaleidoscope',
'tape': True},
{'info': 'acoustic',
'name': 'In My Place'},
{'name': 'Amor Argentina'}]},
{'name': 'A-Stage',
'song': [{'cover': {'mbid': '2c82c087-8300-488e-b1e4-0b02b789eb18',
'name': 'The Chainsmokers '
'& Coldplay',
'sortName': 'Chainsmokers, '
'The & '
'Coldplay',
'url': 'https://www.setlist.fm/setlists/the-chainsmokers-and-coldplay-33ce5029.html'},
'name': 'Something Just Like This'},
{'name': 'A Sky Full of Stars'},
{'info': 'Extended Outro; followed by '
'‘Believe In Love’ Tour '
'Conclusion Video',
'name': 'Up&Up'}]}]},
'tour': {'name': 'A Head Full of Dreams'},
'url': 'https://www.setlist.fm/setlist/coldplay/2017/estadio-ciudad-de-la-plata-la-plata-argentina-33e0845d.html',
'venue': {'city': {'coords': {'lat': -34.9313889,
'long': -57.9488889},
'country': {'code': 'AR', 'name': 'Argentina'},
'id': '3432043',
'name': 'La Plata',
'state': 'Buenos Aires',
'stateCode': '01'},
'id': '3d62153',
'name': 'Estadio Ciudad de La Plata',
'url': 'https://www.setlist.fm/venue/estadio-ciudad-de-la-plata-la-plata-argentina-3d62153.html'},
'versionId': '7b4ce6d0'},
{'artist': {'disambiguation': '',
'mbid': 'cc197bad-dc9c-440d-a5b5-d52ba2e14234',
'name': 'Coldplay',
'sortName': 'Coldplay',
'tmid': 806431,
'url': 'https://www.setlist.fm/setlists/coldplay-3d6bde3.html'},
'eventDate': '14-11-2017',
'id': '63e08ec7',
'info': '"Paradise", "Something Just Like This" and "De música '
'ligera" were soundchecked',
'lastUpdated': '2017-11-15T02:40:25.000+0000',
'sets': {'set': [{'song': [{'cover': {'disambiguation': '',
'mbid': '9dee40b2-25ad-404c-9c9a-139feffd4b57',
'name': 'Maria Callas',
'sortName': 'Callas, Maria',
'url': 'https://www.setlist.fm/setlists/maria-callas-33d6706d.html'},
'name': 'O mio babbino caro',
'tape': True},
{'info': 'extended intro with Charlie '
'Chaplin speech',
'name': 'A Head Full of Dreams'},
{'name': 'Yellow'},
{'name': 'Every Teardrop Is a '
'Waterfall'},
{'name': 'The Scientist'},
{'info': 'with "Oceans" excerpt in '
'intro',
'name': 'Birds'},
{'info': 'with Tiësto Remix outro',
'name': 'Paradise'}]},
{'name': 'B-Stage',
'song': [{'name': 'Always in My Head'},
{'name': 'Magic'},
{'info': 'single version; dedicated '
'to the Argentinian victims '
'of the New York terrorist '
'attack',
'name': 'Everglow'}]},
{'name': 'A-Stage',
'song': [{'info': 'with "Army of One" excerpt '
'in intro',
'name': 'Clocks'},
{'info': 'partial',
'name': 'Midnight'},
{'name': 'Charlie Brown'},
{'name': 'Hymn for the Weekend'},
{'info': 'with "Midnight" excerpt in '
'intro',
'name': 'Fix You'},
{'name': 'Viva la Vida'},
{'name': 'Adventure of a Lifetime'},
{'cover': {'disambiguation': '',
'mbid': '3f8a5e5b-c24b-4068-9f1c-afad8829e06b',
'name': 'Soda Stereo',
'sortName': 'Soda Stereo',
'tmid': 1138263,
'url': 'https://www.setlist.fm/setlists/soda-stereo-7bd6d204.html'},
'info': 'Coldplay debut',
'name': 'De música ligera'}]},
{'name': 'C-Stage',
'song': [{'info': 'Part 1: "The Guest House"',
'name': 'Kaleidoscope',
'tape': True},
{'info': 'acoustic; Will on lead '
'vocals',
'name': 'In My Place'},
{'info': 'song made for Argentina',
'name': 'Amor Argentina'},
{'info': 'Part 2: "Amazing Grace"',
'name': 'Kaleidoscope',
'tape': True}]},
{'name': 'A-Stage',
'song': [{'name': 'Life Is Beautiful'},
{'cover': {'mbid': '2c82c087-8300-488e-b1e4-0b02b789eb18',
'name': 'The Chainsmokers '
'& Coldplay',
'sortName': 'Chainsmokers, '
'The & '
'Coldplay',
'url': 'https://www.setlist.fm/setlists/the-chainsmokers-and-coldplay-33ce5029.html'},
'name': 'Something Just Like This'},
{'name': 'A Sky Full of Stars'},
{'name': 'Up&Up'}]}]},
This is part of the JSON I grabbed from the URL.
Below is the code I am trying touse:
import requests
import json
from pprint import*
url = "https://api.setlist.fm/rest/1.0/artist/cc197bad-dc9c-440d-a5b5-d52ba2e14234/setlists?p=1"
headers = {'x-api-key': 'API-KEY',
'Accept': 'application/json'}
r = requests.get(url, headers=headers)
data = json.loads(r.text)
#pprint(r.json())
response = data['setlist']
#pprint(response)
for item in response:
pprint(item['sets']['set']['song']['name'])
However I get this error that I cannot resolve nor find any help online with:
pprint(item['sets']['set']['song']['name'])
TypeError: list indices must be integers or slices, not str
Dictionaries (Dict) are accessed by keys.
Lists are accessed by indexes.
i.e.
# Dict get 'item'.
data = {'key': 'item'}
data['key']
# List get 'item0'.
data = ['item0', 'item1']
data[0]
# Dict with List get 'item0'.
data = {'key': ['item0', 'item1']}
data['key'][0]
Both storage types can be nested in JSON and either needs to be accessed in a
different manner.
You have nested Lists which need to be indexed through and that can be done by
a for loop.
I have no access to workable json data except for the Python incomplete object
that you show so I have not tested my code. Thus, no assurance that this
is correct. If not, it may demonstrate how to do the task.
import requests
import json
from pprint import *
url = "https://api.setlist.fm/rest/1.0/artist/cc197bad-dc9c-440d-a5b5-d52ba2e14234/setlists?p=1"
headers = {'x-api-key': 'API-KEY',
'Accept': 'application/json'}
r = requests.get(url, headers=headers)
data = json.loads(r.text)
result = []
for setlist_item in data['setlist']:
for set_item in setlist_item['sets']['set']:
for song_item in set_item['song']:
result += [song_item['name']]
print(result)
Each for loop is processing each list to finally get to extending the result with
each song name.

Categories