Python & JSON Phrasing issues - python

I am having issues phrasing the TwitchAPI JSON. I am trying to read the name which is under multiple layers (not Sure of the correct term for this).
Here is part of the API JSON:
{
"_links": {
"next": "https://api.twitch.tv/kraken/channels/test_user/follows?direction=DESC&limit=25&offset=25",
"self": "https://api.twitch.tv/kraken/channels/test_user/follows?direction=DESC&limit=25&offset=0"
},
"_total": 336,
"follows": [
{
"_links": {
"self": "https://api.twitch.tv/kraken/users/test_follower/follows/channels/test_user"
},
"created_at": "2014-07-24T20:21:10Z",
"user": {
"_id": 00000001,
"_links": {
"self": "https://api.twitch.tv/kraken/users/test_follower"
},
"bio": null,
"created_at": "2014-07-05T17:27:45Z",
"display_name": "test_follower",
"logo": null,
"name": "test_follower",
"type": "user",
"updated_at": "2014-07-24T20:20:29Z"
}
},
Etc, it continues with multiple name values I wish to collect.
How do I get the name item? This is my current attempt:
print [data['name'] for data in data['follows']['user']]
But this just gives the error:
TypeError: list indices must be integers, not str

data['follows'] is a list, you can't use ['user'] to get the element in this list.
You need a loop or using data['follows'][0] to get
{
"_links": {
"self": "https://api.twitch.tv/kraken/users/test_follower/follows/channels/test_user"
},
"created_at": "2014-07-24T20:21:10Z",
"user": {
"_id": 00000001,
"_links": {
"self": "https://api.twitch.tv/kraken/users/test_follower"
},
"bio": null,
"created_at": "2014-07-05T17:27:45Z",
"display_name": "test_follower",
"logo": null,
"name": "test_follower",
"type": "user",
"updated_at": "2014-07-24T20:20:29Z"
}
}
So, data['follows'][0]['user'] will get you
"user": {
"_id": 00000001,
"_links": {
"self": "https://api.twitch.tv/kraken/users/test_follower"
},
"bio": null,
"created_at": "2014-07-05T17:27:45Z",
"display_name": "test_follower",
"logo": null,
"name": "test_follower",
"type": "user",
"updated_at": "2014-07-24T20:20:29Z"
}
then you append [name] after it to get the name of the user.
So the answer is: print data['follows'][0]['user']['name']
or
print [data['user']['name'] for data in data['follows']]
The for loop is not correct even if you change data['follows']['user'] to data['follows'][0]['user'], since data['name'] is not valid.
====I CANNOT COMMENT ON ANSWERS=======
The other answer is not correct because there's no 'name' in data['follows']

I think that is something like:
print [data['name'] for data in data['follows']]
I hope this helps

Related

Use python to parase JSON data

After running a GET API call, I am presented with the following output:
{
"limit": 1000,
"offset": 0,
"records": [{
"associatedItems": [{
"id": "rk:db",
"name": "rk:db",
"parentId": "10000",
"parentName": "com.atlassian.crowd.directory.IdentityPlatformRemoteDirectory",
"typeName": "USER"
}],
"category": "group management",
"created": "2022-10-13T17:44:01.633+0000",
"eventSource": "",
"id": 42914,
"objectItem": {
"name": "system-administrators",
"parentId": "10000",
"parentName": "com.atlassian.crowd.directory.IdentityPlatformRemoteDirectory",
"typeName": "GROUP"
},
"summary": "User added to group"
}, {
"associatedItems": [{
"id": "rk:da",
"name": "rk:da",
"parentId": "10000",
"parentName": "com.atlassian.crowd.directory.IdentityPlatformRemoteDirectory",
"typeName": "USER"
}],
"category": "group management",
"created": "2022-10-13T17:44:01.610+0000",
"eventSource": "",
"id": 42913,
"objectItem": {
"name": "site-admins",
"parentId": "10000",
"parentName": "com.atlassian.crowd.directory.IdentityPlatformRemoteDirectory",
"typeName": "GROUP"
}
}],
"total": 492
}
I want to extract each element from the "records" array to create multiple JSON objects.
One (1) JSON object per array element.
For example: JSON Object #1
{
"associatedItems": [{
"id": "rk:db",
"name": "rk:db",
"parentId": "10000",
"parentName": "com.atlassian.crowd.directory.IdentityPlatformRemoteDirectory",
"typeName": "USER"
}],
"category": "group management",
"created": "2022-10-13T17:44:01.633+0000",
"eventSource": "",
"id": 42914,
"objectItem": {
"name": "system-administrators",
"parentId": "10000",
"parentName": "com.atlassian.crowd.directory.IdentityPlatformRemoteDirectory",
"typeName": "GROUP"
},
"summary": "User added to group"
}
Ideally, I want to perform the JSON object manipulation using Python.
Can anyone help me achieve this goal? Thanks!
Not sure if this is "best practice". But I was able to convert the "records" array (nested inside of the GET api response) into a Python dictionary. I then used a FOR loop to convert each array element back into valid JSON.
jira_records = response.json()['records']
for record in jira_records:
x = json.dumps(record)
print(x)
The final result is 1 (valid) JSON object per array element--which is exactly what I needed.
If there is less roundabout way to accomplish this, I'de love to "learn more".

Modify the value of a field of a specific nested object (its index) depending on a condition

I would like to modify the value of a field on a specific index of a nested type depending on another value of the same nested object or a field outside of the nested object.
As example, I have the current mapping of my index feed:
{
"feed": {
"mappings": {
"properties": {
"attacks_ids": {
"type": "keyword"
},
"created_by": {
"type": "keyword"
},
"date": {
"type": "date"
},
"groups_related": {
"type": "keyword"
},
"indicators": {
"type": "nested",
"properties": {
"date": {
"type": "date"
},
"description": {
"type": "text"
},
"role": {
"type": "keyword"
},
"type": {
"type": "keyword"
},
"value": {
"type": "keyword"
}
}
},
"malware_families": {
"type": "keyword"
},
"published": {
"type": "boolean"
},
"references": {
"type": "keyword"
},
"tags": {
"type": "keyword"
},
"targeted_countries": {
"type": "keyword"
},
"title": {
"type": "text"
},
"tlp": {
"type": "keyword"
}
}
}
}
}
Take the following document as example:
{
"took": 194,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "feed",
"_type": "_doc",
"_id": "W3CS7IABovFpcGfZjfyu",
"_score": 1,
"_source": {
"title": "Test",
"date": "2022-05-22T16:21:09.159711",
"created_by": "finch",
"tlp": "white",
"published": true,
"references": [
"test",
"test"
],
"tags": [
"tag1",
"tag2"
],
"targeted_countries": [
"Italy",
"Germany"
],
"malware_families": [
"family1",
"family2"
],
"groups_related": [
"group1",
"griup2"
],
"attacks_ids": [
""
],
"indicators": [
{
"value": "testest",
"description": "This is a test",
"type": "sha256",
"role": "file",
"date": "2022-05-22T16:21:09.159560"
},
{
"value": "testest2",
"description": "This is a test 2",
"type": "ipv4",
"role": "c2",
"date": "2022-05-22T16:21:09.159699"
}
]
}
}
]
}
}
I would like to make this update: indicators[0].value = 'changed'
if _id == 'W3CS7IABovFpcGfZjfyu'
or if title == 'some_title'
or if indicators[0].role == 'c2'
I already tried with a script, but it seems I can't manage to get it work, I hope the explanation is clear, ask any question if not, thank you.
Edit 1:
I managed to make it work, however it needs the _id, still looking for a way to do that without it.
My partial solution:
update = Pulse.get(id="XHCz7IABovFpcGfZWfz9") #Pulse is my document
update.update(script="for (indicator in ctx._source.indicators) {if (indicator.value=='changed2') {indicator.value='changed3'}}")
# Modify depending on the value of a field inside the same nested object

Python - Find value anywhere within JSON and return location

In Python I'm currently working with a very large JSON file with some deep dictionaries and arrays. I'm having an issue where it's not constant. For example that's below, it's essentially countries, with regions/states, cities, and suburbs. The issue is that if there is only one suburb, it'll return a dictionary, though if there's more than one, it's a array with a dictionary making me have to add another line of code to go deeper. Sure, can ifelse/for it, but this is only a very small portion of the inconstancy and it's just not proper going ifelse all the time.
What I'd like to do is simply search anything within Belgium for the dictionary entry "code": "8400" and return it's location within the JSON file. What would be my best approach in order to do something like this? Thanks!
***SNIP***
{
"code": "BE",
"name": "Belgium",
"regions": {
"region": [
{
"code": "45",
"name": "Flanders",
"places": {
"place": [
{
"code": "1790",
"name": "Affligem"
},
{
"code": "8570",
"name": "Anzegem"
},
{
"code": "8630",
"name": "Diksmuide"
},
{
"code": "9600",
"name": "Ronse"
}
]
},
"subregions": {
"subregion": [
{
"code": "46",
"name": "Coast",
"places": {
"place": [
{
"code": "8300",
"name": "Knokke-Heist"
},
{
"code": "8400",
"name": "Oostende",
"subplaces": {
"subplace": {
"code": "8450",
"name": "Bredene"
}
}
},
{
"code": "8420",
"name": "De Haan"
},
{
"code": "8430",
"name": "Middelkerke"
},
{
"code": "8434",
"name": "Westende-Bad"
},
{
"code": "8490",
"name": "Jabbeke"
},
{
"code": "8660",
"name": "De Panne"
},
{
"code": "8670",
"name": "Oostduinkerke"
}
]
}
},
{
"code": "47",
"name": "Cities",
"places": {
"place": [
{
"code": "1000",
"name": "Brussels"
},
{
"code": "2000",
"name": "Antwerp"
},
{
"code": "8000",
"name": "Bruges"
},
{
"code": "8340",
"name": "Damme"
},
{
"code": "9000",
"name": "Gent"
}
]
}
},
{
"code": "48",
"name": "Interior",
"places": {
"place": [
{
"code": "2260",
"name": "Westerlo"
},
{
"code": "2400",
"name": "Mol"
},
{
"code": "2590",
"name": "Berlaar"
},
{
"code": "8500",
"name": "Kortrijk",
"subplaces": {
"subplace": {
"code": "8940",
"name": "Wervik"
}
}
},
{
"code": "8610",
"name": "Handzame"
},
{
"code": "8755",
"name": "Ruiselede"
},
{
"code": "8900",
"name": "Ieper"
},
{
"code": "8970",
"name": "Poperinge"
}
]
}
},
EDIT:
I was asked to show how I'm currently getting through this JSON file. Root is a dictionary containing numbers that equal the city/suburb I'm trying to search for. It doesn't define whether it is a city or suburb before hand. Below is my lazyly coded search while I was trying to learn how to dig through this JSON file, until I realized how complicated it was getting and got a bit stuck.
SNIP
for k in dataDict['countries']['country']:
if k['code'] == root['country']:
for y in k['regions']['region']['places']['place']:
if y['code'] == root['place']:
city = y['name']
else:
try:
for p in y['subplaces']['subplace']:
if p['code'] == root['place']:
city = p['name']
except:
pass
If I understand well, each dictionary has the following structure:
{"code": # some int
"name": # some str
none / "country" / "place" / whatever # some dict or list
You can write a recursive function that handle one and only one dict:
def foo(my_dict):
if my_dict['code'] == root['place']:
city = my_dict['name']
elif "country" in my_dict:
city = foo(my_dict['country'])
elif "place" in my_dict:
#
# and so on...
else:
city = None
return city
Hope this example will help you.

Accessing values from json in Pylons

In my controller I'm getting a json string (called c.order_history which looks like:
[
{
"status": [
{
"status": "created",
"timestamp": "2012-04-06 00:14:10"
},
{
"status": "authed",
"timestamp": "2012-04-06 00:14:17"
}
],
"product_info": [
{
"id": 3,
"quantity": 1,
"created": "2012-04-06 00:14:10",
"image_id": 13341
},
{
"id": 2,
"quantity": 1,
"created": "2012-04-06 00:14:10",
"image_id": 13323
},
{
"id": 1,
"quantity": 1,
"created": "2012-04-06 00:14:10",
"image_id": 13322
}
],
"shipping_charge": "0.00",
"order_number": "0723094747433",
"shipping_address": {
"country_code": null,
"extended_address": "Unit Z",
"locality": "Las Vagas",
"company": null,
"phone": null,
"postal_code": "31415",
"full_name": "Boris Karloff",
"nickname": null,
"region": "NV",
"street_address": "123 Random Way"
},
"subtotal": "59.00"
}
]
I'm passing it through json.loads(order_history) to turn it into a dict, and then trying to extract each key so I can then get the subsequent key/values within them like:
c.product_info = [{'product_info' : product_info} for product_info in c.order_history]
Which outputs the entire json string, but it's just named product_info now. Can someone steer me in the right direction on how I can access say, the timestamp value, product_info[0]['image_id'] and shipping_address values, etc.?
It looks like c.order_history will be a list of dictionaries, to just grab the product_info key from each of these dictionaries in a list comprehension you would do the following:
[{'product_info': order['product_info']} for order in c.order_history]

How to Convert Json Value of Http Post Parameter to Python Dict in Django?

I am using Django to receive and process push notifications from the foursquare real-time api. Each checkin is pushed as a POST request to my server containing a single parameter named checkin. I am trying to grab the value of the checkin parameter and convert it to a python dict. However, calling json.loads always results in the following error:
NameError: name 'true' is not defined
I know the json is valid, so I must be doing something wrong.
The code is:
import json
def push(request):
if request.is_secure():
checkin_json = request.POST['checkin']
checkin = json.load(request.POST)
The body of the post request is:
"checkin =
{
"id": "4e6fe1404b90c00032eeac34",
"createdAt": 1315955008,
"type": "checkin",
"timeZone": "America/New_York",
"user": {
"id": "1",
"firstName": "Jimmy",
"lastName": "Foursquare",
"photo": "https://foursquare.com/img/blank_boy.png",
"gender": "male",
"homeCity": "New York, NY",
"relationship": "self"
},
"venue": {
"id": "4ab7e57cf964a5205f7b20e3",
"name": "foursquare HQ",
"contact": {
"twitter": "foursquare"
},
"location": {
"address": "East Village",
"lat": 40.72809214560253,
"lng": -73.99112284183502,
"city": "New York",
"state": "NY",
"postalCode": "10003",
"country": "USA"
},
"categories": [
{
"id": "4bf58dd8d48988d125941735",
"name": "Tech Startup",
"pluralName": "Tech Startups",
"shortName": "Tech Startup",
"icon": "https://foursquare.com/img/categories/building/default.png",
"parents": [
"Professional & Other Places",
"Offices"
],
"primary": true
}
],
"verified": true,
"stats": {
"checkinsCount": 7313,
"usersCount": 565,
"tipCount": 128
},
"url": "http://foursquare.com"
}
}"
Try json.loads(checkin_json) instead of json.load(request.POST). Notice the extra 's'.
change checkin = json.load(request.POST) to checkin = json.loads(checkin_json)
On python, boolean values are Capitalized (first letter is uppercase): True/False.
Check this.
EDIT:
Pay attentiot at this lines:
"primary": true
}
],
"verified": true,
Both "true" values are lowercase and need to be capitalized

Categories

Resources