Retrieving data from a Python Tuple - python

I am trying to retrieve and reuse data from a JSON object in a for loop in Python. An example of a single JSON object below:
{
"id": "123456789",
"envs": [
"env:remote1",
"env:remote2",
"env:remote3"
],
"moves": {
"sequence1": "half glass full",
"sequence2": "half glass empty"
}
}
For loop example
for i in ids:
print(i["envs"])
print(i["moves"])
envs will be successfully printed since it is a list. However, since moves is a tuple I receive a KeyError as it is looking for a key in a dictionary. What is the Python recommended way of pulling data from a tuple in this instance. For example, I want to print sequence1 or sequence2.
Thanks

It appears you made a typographic error.
From this code
ids = [
{
"id": "123456789",
"envs": [
"env:remote1",
"env:remote2",
"env:remote3",
],
"moves": {
"sequence1": "half glass full",
"sequence2": "half glass empty",
},
}
]
for i in ids:
print(i["envs"])
print(i["moves"])
I obtain these results
['env:remote1', 'env:remote2', 'env:remote3']
{'sequence1': 'half glass full', 'sequence2': 'half glass empty'}

Related

Spotipy search track name and return album, track and artist

I'm trying to get to grips with spotipy (again) I'm trying to return the artist, album, and track name from search by track title.
track = "Pretend we're dead"
results = sp.search(q="track:" + track, type="track")
for idx, artist, album, track in enumerate(results['tracks']['artist']['album']['items']):
print(idx, track['name'], track['artist'], album['album'])
Expected results:
Pretend We're Dead, L7, Bricks Are Heavy
Pretend We're Dead, L7, Pretend We're Dead - The Best Of
Pretend We're Dead - Remastered, L7, Fast & Frightning
I'm failing on deconstructing the list comprehension that are the results.
The error I'm getting is:
Traceback (most recent call last):
print(idx, track['name'], track['artist_id'])
KeyError: 'artist_id'
Looking at the docs, I see that the response is going to look like this (leaving out the boring parts):
{
"album": {}
"artists": [
{
"genres": [
"Prog rock",
"Grunge"
],
"href": "string",
"id": "string",
"images": [
{
"url": "https://i.scdn.co/image/ab67616d00001e02ff9ca10b55ce82ae553c8228\n",
"height": 300,
"width": 300
}
],
"name": "string",
"popularity": 0,
"type": "artist",
"uri": "string"
}
]
}
Looking at this, artists is a key within the result, and it is a list of dictionaries, with each dict being a single artist for the track.
Using that info, this would be the way to refer to the first artist's id:
track["artists"][0]["id"]
If this isn't right, the trick to doing this is to just print(json.dumps(track, indent=3)) and look at the actual JSON you are receiving.

How to parse nested JSON object?

I am working on a new project in HubSpot that returns nested JSON like the sample below. I am trying to access the associated contacts id, but am struggling to reference it correctly (the id I am looking for is the value '201' in the example below). I've put together this script, but this script only returns the entire associations portion of the JSON and I only want the id. How do I reference the id correctly?
Here is the output from the script:
{'contacts': {'paging': None, 'results': [{'id': '201', 'type': 'ticket_to_contact'}]}}
And here is the script I put together:
import hubspot
from pprint import pprint
client = hubspot.Client.create(api_key="API_KEY")
try:
api_response = client.crm.tickets.basic_api.get_page(limit=2, associations=["contacts"], archived=False)
for x in range(2):
pprint(api_response.results[x].associations)
except ApiException as e:
print("Exception when calling basic_api->get_page: %s\n" % e)
Here is what the full JSON looks like ('contacts' property shortened for readability):
{
"results": [
{
"id": "34018123",
"properties": {
"content": "Hi xxxxx,\r\n\r\nCan you clarify on how the blocking of script happens? Is it because of any CSP (or) the script will decide run time for every URL’s getting triggered from browser?\r\n\r\nRegards,\r\nLogan",
"createdate": "2019-07-03T04:20:12.366Z",
"hs_lastmodifieddate": "2020-12-09T01:16:12.974Z",
"hs_object_id": "34018123",
"hs_pipeline": "0",
"hs_pipeline_stage": "4",
"hs_ticket_category": null,
"hs_ticket_priority": null,
"subject": "RE: call followup"
},
"createdAt": "2019-07-03T04:20:12.366Z",
"updatedAt": "2020-12-09T01:16:12.974Z",
"archived": false
},
{
"id": "34018892",
"properties": {
"content": "Hi Guys,\r\n\r\nI see that we were placed back on the staging and then removed again.",
"createdate": "2019-07-03T07:59:10.606Z",
"hs_lastmodifieddate": "2021-12-17T09:04:46.316Z",
"hs_object_id": "34018892",
"hs_pipeline": "0",
"hs_pipeline_stage": "3",
"hs_ticket_category": null,
"hs_ticket_priority": null,
"subject": "Re: Issue due to server"
},
"createdAt": "2019-07-03T07:59:10.606Z",
"updatedAt": "2021-12-17T09:04:46.316Z",
"archived": false,
"associations": {
"contacts": {
"results": [
{
"id": "201",
"type": "ticket_to_contact"
}
]
}
}
}
],
"paging": {
"next": {
"after": "35406270",
"link": "https://api.hubapi.com/crm/v3/objects/tickets?associations=contacts&archived=false&hs_static_app=developer-docs-ui&limit=2&after=35406270&hs_static_app_version=1.3488"
}
}
}
You can do api_response.results[x].associations["contacts"]["results"][0]["id"].
Sorted this out, posting in case anyone else is struggling with the response from the HubSpot v3 Api. The response schema for this call is:
Response schema type: Object
String results[].id
Object results[].properties
String results[].createdAt
String results[].updatedAt
Boolean results[].archived
String results[].archivedAt
Object results[].associations
Object paging
Object paging.next
String paging.next.after
String paging.next.linkResponse schema type: Object
String results[].id
Object results[].properties
String results[].createdAt
String results[].updatedAt
Boolean results[].archived
String results[].archivedAt
Object results[].associations
Object paging
Object paging.next
String paging.next.after
String paging.next.link
So to access the id of the contact associated with the ticket, you need to reference it using this notation:
api_response.results[1].associations["contacts"].results[0].id
notes:
results[x] - reference the result in the index
associations["contacts"] -
associations is a dictionary object, you can access the contacts item
by it's name
associations["contacts"].results is a list - reference
by the index []
id - is a string
In my case type was ModelProperty or CollectionResponseProperty couldn't reach dict anyhow.
For the record this got me to go through the results.
for result in list(api_response.results):
ID = result.id

Doing a collection find in PyMongo and has no effect

Hi I was facing a problem when I doing PyMongo.
keywords is a user input by list(input().split())
When I doing the results = post_collection.find()
I tried four different statement after the find bracket,
{"Title": keyword} or {"Body": keyword} or {"Tags": keyword}
{"title": keyword} or {"body": keyword} or {"tags": keyword}
"Title": {"$in": keywords}} or {"Body": {"$in": keywords}} or {"Tags": {"$in": keywords}
{}
1,2,3 gives me no response, the results.count() return 0 to me , and it will never goes into next 'for posts in results' loop, it will just skip the for loop and keep going to the next input section.
4 returns me all the posts in my json file opened in the beginning.
I was wondering why I was having that problem, and I am struggling about it the whole day.
Thank you for your time
Below is part of my code.
part of code
Part of document
{
"Id": "1",
"PostTypeId": "1",
"AcceptedAnswerId": "9",
"CreationDate": "2010-08-17T19:22:37.890",
"Score": 16,
"ViewCount": 28440,
"Body": "What is the hardware and software differences between Intel and PPC Macs?\n",
"OwnerUserId": "10",
"LastEditorUserId": "15",
"LastEditDate": "2010-09-08T15:12:04.097",
"LastActivityDate": "2017-09-21T12:16:56.790",
"Title": "What is the difference between Intel and PPC?",
"Tags": "",
"AnswerCount": 9,
"CommentCount": 0,
"FavoriteCount": 6,
"ContentLicense": "CC BY-SA 2.5"
},
The or statement doesn't work like this in mongoDb. Read more here
Here is the query
{
"$or": [
{
"title": keyword
},
{
"body": keyword
}
{
"tags": keyword
}
]
}
Here is a working example
The problem in your code is under print(3). In your mongo request, the way you are passing the keyword is actually invalid, because this one is blocked in the scope of for loop on top of it. So the mongo request can't reach the correct keyword. The solution is to push all the code under print(keyword), in the first for loop. Like this:
for keyword in keywords:
print(keyword)
print(3)
results = posts_collection.find({"$or": [{"Title": keyword}, {"Body": keyword}, {"Tags": keyword}]})
print(results)
print(results.count())
print(4)
for posts in results:
print(5)
if posts['PostTypeId'] == 1:
print(posts['titlse']) # ...
else:
print(1)
continue

Accessing nested objects with python

I have a response that I receive from foursquare in the form of json. I have tried to access the certain parts of the object but have had no success. How would I access say the address of the object? Here is my code that I have tried.
url = 'https://api.foursquare.com/v2/venues/explore'
params = dict(client_id=foursquare_client_id,
client_secret=foursquare_client_secret,
v='20170801', ll=''+lat+','+long+'',
query=mealType, limit=100)
resp = requests.get(url=url, params=params)
data = json.loads(resp.text)
msg = '{} {}'.format("Restaurant Address: ",
data['response']['groups'][0]['items'][0]['venue']['location']['address'])
print(msg)
Here is an example of json response:
"items": [
{
"reasons": {
"count": 0,
"items": [
{
"summary": "This spot is popular",
"type": "general",
"reasonName": "globalInteractionReason"
}
]
},
"venue": {
"id": "412d2800f964a520df0c1fe3",
"name": "Central Park",
"contact": {
"phone": "2123106600",
"formattedPhone": "(212) 310-6600",
"twitter": "centralparknyc",
"instagram": "centralparknyc",
"facebook": "37965424481",
"facebookUsername": "centralparknyc",
"facebookName": "Central Park"
},
"location": {
"address": "59th St to 110th St",
"crossStreet": "5th Ave to Central Park West",
"lat": 40.78408342593807,
"lng": -73.96485328674316,
"labeledLatLngs": [
{
"label": "display",
"lat": 40.78408342593807,
"lng": -73.96485328674316
}
],
the full response can be found here
Like so
addrs=data['items'][2]['location']['address']
Your code (at least as far as loading and accessing the object) looks correct to me. I loaded the json from a file (since I don't have your foursquare id) and it worked fine. You are correctly using object/dictionary keys and array positions to navigate to what you want. However, you mispelled "address" in the line where you drill down to the data. Adding the missing 'a' made it work. I'm also correcting the typo in the URL you posted.
I answered this assuming that the example JSON you linked to is what is stored in data. If that isn't the case, a relatively easy way to see exact what python has stored in data is to import pprint and use it like so: pprint.pprint(data).
You could also start an interactive python shell by running the program with the -i switch and examine the variable yourself.
data["items"][2]["location"]["address"]
This will access the address for you.
You can go to any level of nesting by using integer index in case of an array and string index in case of a dict.
Like in your case items is an array
#items[int index]
items[0]
Now items[0] is a dictionary so we access by string indexes
item[0]['location']
Now again its an object s we use string index
item[0]['location']['address]

Error while parsing json from IBM watson using python

I am trying to parse out a JSON download using python and here is the download that I have:
{
"document_tone":{
"tone_categories":[
{
"tones":[
{
"score":0.044115,
"tone_id":"anger",
"tone_name":"Anger"
},
{
"score":0.005631,
"tone_id":"disgust",
"tone_name":"Disgust"
},
{
"score":0.013157,
"tone_id":"fear",
"tone_name":"Fear"
},
{
"score":1.0,
"tone_id":"joy",
"tone_name":"Joy"
},
{
"score":0.058781,
"tone_id":"sadness",
"tone_name":"Sadness"
}
],
"category_id":"emotion_tone",
"category_name":"Emotion Tone"
},
{
"tones":[
{
"score":0.0,
"tone_id":"analytical",
"tone_name":"Analytical"
},
{
"score":0.0,
"tone_id":"confident",
"tone_name":"Confident"
},
{
"score":0.0,
"tone_id":"tentative",
"tone_name":"Tentative"
}
],
"category_id":"language_tone",
"category_name":"Language Tone"
},
{
"tones":[
{
"score":0.0,
"tone_id":"openness_big5",
"tone_name":"Openness"
},
{
"score":0.571,
"tone_id":"conscientiousness_big5",
"tone_name":"Conscientiousness"
},
{
"score":0.936,
"tone_id":"extraversion_big5",
"tone_name":"Extraversion"
},
{
"score":0.978,
"tone_id":"agreeableness_big5",
"tone_name":"Agreeableness"
},
{
"score":0.975,
"tone_id":"emotional_range_big5",
"tone_name":"Emotional Range"
}
],
"category_id":"social_tone",
"category_name":"Social Tone"
}
]
}
}
I am trying to parse out 'tone_name' and 'score' from the above file and I am using following code:
import urllib
import json
url = urllib.urlopen('https://watson-api-explorer.mybluemix.net/tone-analyzer/api/v3/tone?version=2016-05-19&text=I%20am%20happy')
data = json.load(url)
for item in data['document_tone']:
print item["tone_name"]
I keep running into error that tone_name not defined.
As jonrsharpe said in a comment:
data['document_tone'] is a dictionary, but 'tone_name' is a key in dictionaries much further down the structure.
You need to access the dictionary that tone_name is in. If I am understanding the JSON correctly, tone_name is a key within tones, within tone_categories, within document_tone. You would then want to change your code to go to that level, like so:
for item in data['document_tone']['tone_categories']:
# item is an anonymous dictionary
for thing in item[tones]:
print(thing['tone_name'])
The reason more than one for is needed is because of the mix of lists and dictionaries in the file. 'tone_categories is a list of dictionaries, so it accesses each one of those. Then, it iterates through the list tones, which is in each one and full of more dictionaries. Those dictionaries are the ones that contain 'tone_name', so it prints the value of 'tone_name'.
If this does not work, let me know. I was unable to test it since I could not get the rest of the code to work on my computer.
You are incorrectly walking the structure. The root node has a single document_tone key, the value of which only has the tone_categories key. Each of the categories has a list of tones and it's name. Here is how you would print it out (adjust as needed):
for cat in data['document_tone']['tone_categories']:
print('Category:', cat['category_name'])
for tone in cat['tones']:
print('-', tone['tone_name'])
The result of this is:
Category: Emotion Tone
- Anger
- Disgust
- Fear
- Joy
- Sadness
Category: Language Tone
- Analytical
- Confident
- Tentative
Category: Social Tone
- Openness
- Conscientiousness
- Extraversion
- Agreeableness
- Emotional Range

Categories