Parse json response in python - python

The workplace api returns a json response:
{
"name": "AA",
"owner": {
"name": "ser1",
"id": "1234"
},
"id": "567",
"admins": {
"data": [
{
"name": "codez",
"id": "457"
},
],
"paging": {
"cursors": {
"before": "qwrqwreqreqr",
"after": "teyryryryr"
}
}
}
I access the json response in python using the below for loop:
for item in feed:
row = [item["name"],item["id"], item["email"], item["privacy"],item["updated_time"],item["admins"]["data"]["name"]]
I get the error "list indices must be integers or slices, not list". When I remove the item["admins"]["data"]["name"], I don't get the error message.
Any suggestions would be appreciated !!

You need to access list. The data node contains a list so you need to access index 0 then access the key value pair.
for item in feed:
row = [item["name"],item["id"], item["email"], item["privacy"],item["updated_time"],item["admins"]["data"][0]["name"]]

data maps to a list with size one so you could do item["admins"]["data"][0]["name"]
Although this could be done much easier with row = item.values()

Related

Python function to extract specific values from complex JSON logs data

I am trying to write a Python function (for use in a Google Cloud Function) that extracts specific values from JSON logs data. Ordinarily, I do this using the standard method of sorting through keys:
my_data['key1'], etc.
This JSON data, however is quite different, since it appears to have the data I need as lists inside of dictionaries. Here is a sample of the logs data:
{
"insertId": "-mgv16adfcja",
"logName": "projects/my_project/logs/cloudaudit.googleapis.com%2Factivity",
"protoPayload": {
"#type": "type.googleapis.com/google.cloud.audit.AuditLog",
"authenticationInfo": {
"principalEmail": "email#email.com"
},
"authorizationInfo": [{
"granted": true,
"permission": "resourcemanager.projects.setIamPolicy",
"resource": "projects/my_project",
"resourceAttributes": {
"name": "projects/my_project",
"service": "cloudresourcemanager.googleapis.com",
"type": "cloudresourcemanager.googleapis.com/Project"
}
},
{
"granted": true,
"permission": "resourcemanager.projects.setIamPolicy",
"resource": "projects/my_project",
"resourceAttributes": {
"name": "projects/my_project",
"service": "cloudresourcemanager.googleapis.com",
"type": "cloudresourcemanager.googleapis.com/Project"
}
}
],
"methodName": "SetIamPolicy",
"request": {
"#type": "type.SetIamPolicyRequest",
"policy": {
"bindings": [{
"members": [
"serviceAccount:my-test-
sa #my_project.iam.gserviceaccount.com "
],
"role": "projects/my_project/roles/PubBuckets"
},
{
"members": [
"serviceAccount:my-test-sa-
2 #my_project.iam.gserviceaccount.com "
],
"role": "roles/owner"
},
{
"members": [
"serviceAccount:my-test-sa-3#my_project.iam.gserviceaccount.com",
"serviceAccount:my-test-sa-4#my_project.iam.gserviceaccount.com"
]
}
My goal with this data is to extract the "role":"roles/editor" and the associated "members." So in this case, I would like to extract service accounts my-test-sa-3, 4, and 5, and print them.
When the JSON enters my cloud function I do the following:
pubsub_message = base64.b64decode(event['data']).decode('utf-8')
msg = json.loads(pubsub_message)
print(msg)
And I can get to other data that I need, e.g., project id-
proj_id = msg['resource']['labels']['project_id']
But I cannot get into the lists within the dictionaries effectively. The deepest I can currently get is to the 'bindings' key.
I have additionally tried restructuring and flattening output as a list:
policy_request =credentials.projects().getIamPolicy(resource=proj_id, body={})
policy_response = policy_request.execute()
my_bindings = policy_response['bindings']
flat_list = []
for element in my_bindings:
if type(element) is list:
for item in element:
flat_list.append(item)
else:
flat_list.append(element)
print('Here is flat_list: ', flat_list)
I then use an if statement to search the list, which returns nothing. I can't use indices, because the output will change consistently, so I need a solution that can extract the values by a key, value approach if at all possible.
Expected Output:
Role: roles/editor
Members:
sa-1#gcloud.com
sa2#gcloud.com
sa3#gcloud.com
and so on
Appreciate any help.

Only getting string while iterating through json data

JSON:
{
"status": "success",
"data": {
"9": {
"1695056": {
"id": "1695056",
[...]
},
"csevents": {
"2807": {
"id": "2807",
"startdate": "2019-01-24 18:45:00",
"service_texts": [],
"eventTemplate": "1"
},
"2810": {
"id": "2810",
"startdate": "2019-01-31 18:45:00",
"service_texts": [],
"eventTemplate": "1"
}
}
},
"1695309": {
"id": "1695309",
[...]
},
"csevents": {
"3601": {
"id": "3601",
"startdate": "2019-05-17 18:45:00",
"service_texts": [],
"eventTemplate": "1"
}
I try to get the members from "csevents" ("2807", "2810", 3601") with python. Problem is that i don't know the IDs in "9" ("1695056", "1695309") while coding.
So i tried to iterate through "9" and then through "csevents" but if i iterate through "9" i only get a string so i can't iterate through "csevents" anymore.
Python:
for whatever in json_object['data']['9']:
for id in whatever['csevents']:
print(id)
So that doesn't work. Does anybody know how I can solve that?
Thanks
Had to clean up your JSON string to get it to work, but looking at your solution is seems like you're iterating directly from your dict, what you should be using is .items() or .values():
for key, value in json_object['data']['9'].items():
# We can use .keys() here since we only need the IDs from csevents
csevent_keys = list(value['csevents'].keys())
print(csevent_keys)
# Output
['2807', '2810']
['3601']

Getting items from an api using django

I am trying to get the amount value from the available field when I retrieve a blance from Stripe. I have the following response:
{
"available": [
{
"amount": 10302,
"currency": "cad",
"source_types": {
"card": 10302
}
}
],
"livemode": false,
"object": "balance",
"pending": [
{
"amount": 0,
"currency": "cad",
"source_types": {
"card": 0
}
}
]
}
I am trying to get the available amount, so I wrote the following:
available = balance['available']
as a response I am getting the following:
[<StripeObject at 0x110d45a98> JSON: {
"amount": 10302,
"currency": "cad",
"source_types": {
"card": 10302
}
}]
But how can I get access to the 'amount' part?
I tried:
amount = available['amount']
So I am receiving:
TypeError at /en/accounts/profile/
list indices must be integers or slices, not str
as an error.
balance['available'] contains a dictionary ({}) inside of a list ([]). Therefore, the dictionary is stored as the first element of the list, and has to be accessed using available[0]. You can get the value that corresponds to the 'amount' key by typing available[0]['amount'].

Python TypeError "list indices must be integers, not str"

trying to convert the json to csv, but why doesn't this work?
The following error appears:
x['Emotions']['Confidence'][0], TypeError: list indices must be
integers, not str
for person in output_json["Record"]:
csv_data = person["Person"]
for x in csv_data:
f = csv.writer(open('/tmp/test.csv', 'wb+'))
f.writerow(["FrameNumber", "FrameTimePosition", "Gender", "Emotions_Type1", "Emotions_Confidence1",
"Emotions_Type2", "Emotions_Confidence2", "Emotions_Type3", "Emotions_Confidence3",
"AgeRange_High", "AgeRange_low"])
print(x['FrameNumber'])
print(x['FrameTimePosition'])
print(x['Gender']['Value'])
f.writerow([x['FrameNumber'],
x['FrameTimePosition'],
x['Gender']['Value'],
x['Emotions']['Confidence'][0],
x['Emotions']['Type'][0],
x['Emotions']['Confidence'][1],
x['Emotions']['Type'][1],
x['Emotions']['Confidence'][2],
x['Emotions']['Type'][2],
x['AgeRange']['High'],
x['AgeRange']['Low']])
The following Json, I already follow the output format, but I don't know why it's not working
{
"Record": [
{
"Person": [
{
"FrameNumber": 1,
"FrameTimePosition": "0:00:01",
"Gender": {
"Confidence": 99.86161041259766,
"Value": "Male"
},
"Emotions": [
{
"Confidence": 83.7345199584961,
"Type": "HAPPY"
},
{
"Confidence": 3.3157408237457275,
"Type": "CONFUSED"
},
{
"Confidence": 1.5936851501464844,
"Type": "CALM"
}
],
...
}
],
...
}
]
}
This is happening because you're trying to get a list value by it's key.
You're probably are thinking is a dictionary (similar to an object {} in JSON) when it's a list (array[], in JSON).
I suggest you to check the types in your JSON, specially for the keys that appears in the error
x['Emotions']['Confidence'][0]
Your x['Emotions'] probably is a array an not a object in your base JSON.
Edit after the JSON
x['Emotions'] is an array (list in python), what I think you probably want wiith this line is to get the values with key 'Confidence', so you gonna need to invert the order, like this:
x['Emotions'][0]['Confidence']
Here you getting the first element of the list with the key 'Emotions',
getting a dict like that:
{
"Confidence": 83.7345199584961,
"Type": "HAPPY"
}
and, from this element, the 'Confidence' property.
Hope it helps!

Issues decoding Collections+JSON in Python

I've been trying to decode a JSON response in Collections+JSON format using Python for a while now but I can't seem to overcome a small issue.
First of all, here is the JSON response:
{
"collection": {
"href": "http://localhost:8000/social/messages-api/",
"items": [
{
"data": [
{
"name": "messageID",
"value": 19
},
{
"name": "author",
"value": "mike"
},
{
"name": "recipient",
"value": "dan"
},
{
"name": "pm",
"value": "0"
},
{
"name": "time",
"value": "2015-03-31T15:04:01.165060Z"
},
{
"name": "text",
"value": "first message"
}
]
}
],
"version": "1.0",
"links": []
}
}
And here is how I am attempting to extract data:
response = urllib2.urlopen('myurl')
responseData = response.read()
jsonData = json.loads(responseData)
test = jsonData['collection']['items']['data']
When I run this code I get the error:
list indices must be integers, not str
If I use an integer, e.g. 0, instead of a string it merely shows 'data' instead of any useful information, unlike if I were to simply output 'items'. Similarly, I can't seem to access the data within a data child, for example:
test = jsonData['collection']['items'][0]['name']
This will argue that there is no element called 'name'.
What is the proper method of accessing JSON data in this situation? I would also like to iterate over the collection, if that helps.
I'm aware of a package that can be used to simplify working with Collections+JSON in Python, collection-json, but I'd rather be able to do this without using such a package.

Categories

Resources