Python - check if variable is == to json element and print - python

I have a json response with thousands of student information bits. It looks like this:
{
"users": [
{
"agents": [
{
"href": "private url here",
"sourcedId": "g560",
"type": "user"
}
],
"dateLastModified": "2016-10-24T15:24:00.000Z",
"demographics": {
"href": "private url here",
"sourcedId": "s557",
"type": "demographics"
},
"email": "example#example.com",
"familyName": "Smith",
"givenName": "John",
"identifier": "000000000",
"metadata": {
"ext_grade_level": "11"
},
"orgs": [
{
"href": "private URL here",
"sourcedId": "000000000000000000000000000000",
"type": "org"
},
{
"href": "private URL Here",
"sourcedId": "0000000000000000000000000000000000",
"type": "org"
},
{
"href": "private url here",
"sourcedId": "000000000000000000000000000",
"type": "org"
}
],
"role": "student",
"sourcedId": "s557",
"status": "active",
"username": "000000000"
},
{
That then repeats starting with "agents": [ for the next student, approximately 2,500 times. What I'm really looking to do is the following, I have "students_data" = students_data.json().
json1 = students_data['users']
stu_email = input("Enter a student email address here:")
if item in json1 == stu_email:
print(stu_email)
When I run that, nothing happens. It asks for an input and then just ends. No errors, no nothing. I have nothing to go off, other than it's obviously wrong. Also, if it did work, how would I then print the familyName, givenName, and identifier for the matching address?
The list nested in the dictionaries really messes me up, because the only way I know how to deal with lists is by indexing with [0] or [1] etc. however, that isn't an option in this case.
Also, I tried doing json1['email'] but I get the "TypeError: list indices must be integers or slices, not str" which I assume is because I'm skipping over the list.
Thanks for any help!

Json data can consist of dictionaries and lists nested within each other. Here we loop through the list student_data['users'] to look for the first student with a matching email.
student_email = input("Enter a student email address here:")
for student in students_data['users']:
if student['email'] == student_email:
print('found a match')
print(student)
break
else:
print('no match found')

Related

How to print a specific item from within a JSON file into python

I want to print a user from a JSON list into Python that I select however I can only print all the users. How do you print a specific user? At the moment I have this which prints all the users out in a ugly format
import json
with open('Admin_sample.json') as f:
admin_json = json.load(f)
print(admin_json['staff'])
The JSON file looks like this
{
"staff": [
{
"id": "DA7153",
"name": [
"Fran\u00c3\u00a7ois",
"Ullman"
],
"department": {
"name": "Admin"
},
"server_admin": "true"
},
{
"id": "DA7356",
"name": [
"Bob",
"Johnson"
],
"department": {
"name": "Admin"
},
"server_admin": "false"
},
],
"assets": [
{
"asset_name": "ENGAGED SLOTH",
"asset_type": "File",
"owner": "DA8333",
"details": {
"security": {
"cia": [
"HIGH",
"INTERMEDIATE",
"LOW"
],
"data_categories": {
"Personal": "true",
"Personal Sensitive": "true",
"Customer Sensitive": "true"
}
},
"retention": 2
},
"file_type": "Document",
"server": {
"server_name": "ISOLATED UGUISU",
"ip": [
10,
234,
148,
52
]
}
},
{
"asset_name": "ISOLATED VIPER",
"asset_type": "File",
"owner": "DA8262",
"details": {
"security": {
"cia": [
"LOW",
"HIGH",
"LOW"
],
"data_categories": {
"Personal": "false",
"Personal Sensitive": "false",
"Customer Sensitive": "true"
}
},
"retention": 2
},
},
]
I just can't work it out. Any help would be appreciated.
Thanks.
You need to index into the staff list, e.g.:
print(admin_json['staff'][0])
I suggest reading up a bit on dictionaries in Python. Dictionary values can be set to any object: in this case, the value of the staff key is set to a list of dicts. Here's an example that will loop through all the staff members and print their names:
staff_list = admin_json['staff']
for person in staff_list:
name_parts = person['name']
full_name = ' '.join(name_parts) # combine name parts into a string
print(full_name)
Try something like this:
import json
def findStaffWithId(allStaff, id):
for staff in allStaff:
if staff["id"] == id:
return staff
return {} # no staff found
with open('Admin_sample.json') as f:
admin_json = json.load(f)
print(findStaffWithId(admin_json['staff'], "DA7356"))
You can list all the users name with
users = [user["name"] for user in admin_json['staff']]
You have two lists in this JSON file. When you try to parse it, you'll be reach a list. For example getting the first staff id:
print(admin_json['staff'][0]['id'])
This will print:
DA7153
When you use "json.loads" this will simply converts JSON file to the Python dictionary. For further info:
https://docs.python.org/3/tutorial/datastructures.html#dictionaries

Return nested JSON item that has multiple instances

So i am able to return almost all data, except i am not able to capture something like this:
"expand": "schema"
"issues": [
{
"expand": "<>",
"id": "<>",
"self": "<>",
"key": "<>",
"fields": {
"components": [
{
"self": "<>",
"id": "1",
"name": "<>",
"description": "<>"
}
]
}
},
{
"expand": "<>",
"id": "<>",
"self": "<>",
"key": "<>",
"fields": {
"components": [
{
"self": "<>",
"id": "<>",
"name": "<>"
}
]
}
},
I want to return a list that contains both of the 'name's for 'components', i have tried using:
list((item['fields']['components']['name']) for item in data['issues'])
but i get a type error saying TypeError: list indices must be integers or slices, not str when i try to Print() the above line of code
Also, if i could get some explanation of what this type error means, and what "list" is trying to do that means that it is not a "str" that would be appreciated
EDIT:
url = '<url>'
r = http.request('GET', url, headers=headers)
data = json.loads(r.data.decode('utf-8'))
print([d['name'] for d in item['fields']['components']] for item in data['issues'])
As the commenter points out you're treating the list like a dictionary, instead this will select the name fields from the dictionaries in the list:
list((item['fields']['components'][i]['name'] for i, v in enumerate(item['fields']['components'])))
Or simply:
[d['name'] for d in item['fields']['components']]
You'd then need to apply the above to all the items in the iterable.
EDIT: Full solution to just print the name fields, assuming that "issues" is a key in some larger dictionary structure:
for list_item in data["issues"]: # issues is a list, so iterate through list items
for dct in list_item["fields"]["components"]: # each list_item is a dictionary
print(dct["name"]) # name is a field in each dictionary

unable to fetch json attribute in POST request

This Json is received as a POST request. Now
I want to get value of text key of each entry in actions array
I am using Python's Bottle to receive the request.
to fetch the value of required attribute, I did this
word = request.forms.get('[attachments][actions][0][text]')
But this doesn't print required value.
{
"attachments": [
{
"title": "XYZ",
"title_link": "EDWE",
"text": "dxjhvgebndm",
"fields": [
{
"title": "Food",
"value": "$20",
"short": true
}
],
"actions": [
{
"name": "chess",
"text": "Approve",
"type": "button",
"value": "chess",
"style": "primary"
},
{
"name": "maze",
"text": "Decline",
"style": "danger",
"type": "button",
"value": "maze"
},
{
"name": "war",
"text": "More details",
"style": "default",
"type": "button",
"value": "war",
"confirm": {
"title": "Are you sure?",
"text": "Would you like to see more details of your expense?",
"ok_text": "Yes",
"dismiss_text": "No"
}
}
],
"image_url": "",
"thumb_url": "https://i.imgsafe.org/cf40eef.png",
"footer": "fghj",
"footer_icon": "https://i.imgsafe.org/cf2e0eef.png",
"ts": 1475057533
}
]
}
Note: I am receiving complete JSON, the problem is in fetching correct attribute.
EDIT
Through this i am receiving POST request
import json
from bottle import route, run, request
import urllib
#route('/ocr_response', method='POST')
def ocr_response():
body = request.body.read()
word = request.forms.get('[attachments][actions][0][text]')
print word
print body
if __name__ == "__main__":
run(host='0.0.0.0', port=80, debug=True)
That's not how you access items in a dictionary at all.
Firstly, the JSON data is available via request.json. Secondly, I'm not sure what you're doing with that string you're passing to get, but you need to use normal dictionary/array syntax. And thirdly, attachments is a list just like actions, so you'd need to add an index there too.
request.json['attachments'][0]['actions'][0]['text']

Best way to parse sections of json in python3 to separate items in list

First off, I'm having trouble Googling this question since I don't know all of the terminology (so really, giving me the proper terms to use in my Google search would be just as useful in this question).
I have some JSON that I need to parse in python, put each JSON string in a list after its been parsed(List, not array for Python correct?) and then I am going to go through that list to push the JSON content back to my source.
So as of now, I can parse out a section of JSON that I want, but I am not sure how to then get down to just printing the section between brackets. For example, I want to get each section (brackets) in this block of code to be in a separate JSON line:
{
"components": [
{
"self": "MY URL",
"id": "ID",
"name": "NAME",
"description": "THIS IS DESC",
"isAssigneeTypeValid": false
},
{
"self": "MY URL 2",
"id": "ID",
"name": "name",
"isAssigneeTypeValid": false
},
{
"self": "URL 3",
"id": "ID",
"name": "NAME 3",
"description": "DESC",
"isAssigneeTypeValid": false
}
]
}
There is a lot more JSON in my file, but using this, I can get it down to just returning the text above.
datas = json.loads(data)
print(datas['components'])
So my question is how would I just print one block? Or access the first 'self' section?
Here's how you can iterate over that data, converting each dict in the "components" list back into JSON strings:
import json
data = '''
{
"components": [
{
"self": "MY URL",
"id": "ID",
"name": "NAME",
"description": "THIS IS DESC",
"isAssigneeTypeValid": false
},
{
"self": "MY URL 2",
"id": "ID",
"name": "name",
"isAssigneeTypeValid": false
},
{
"self": "URL 3",
"id": "ID",
"name": "NAME 3",
"description": "DESC",
"isAssigneeTypeValid": false
}
]
}
'''
datas = json.loads(data)
for d in datas['components']:
print(json.dumps(d))
output
{"self": "MY URL", "description": "THIS IS DESC", "id": "ID", "isAssigneeTypeValid": false, "name": "NAME"}
{"self": "MY URL 2", "id": "ID", "isAssigneeTypeValid": false, "name": "name"}
{"self": "URL 3", "description": "DESC", "id": "ID", "isAssigneeTypeValid": false, "name": "NAME 3"}
If you have a valid json document then you can simply iterate over the list of components. Assuming you name the file <id>.json then you can simply do:
datas = json.loads(data)
for component in datas['components']:
with open("{}.json".format(component['id']), 'w') as f:
json.dump(component, f)
When you read it in, a JSON is a Python dictionary, so you can use all functions that are valid for dictionaries.
In your case "components" is the key of the dictionary, whose value is a list. Each item in the list is an another dictionary.

python querying a json objectpath

I've a nested json structure, I'm using objectpath (python API version), but I don't understand how to select and filter some information (more precisely the nested information in the structure).
EG.
I want to select the "description" of the action "reading" for the user "John".
JSON:
{
"user":
{
"actions":
[
{
"name": "reading",
"description": "blablabla"
}
]
"name": "John"
}
}
CODE:
$.user[#.name is 'John' and #.actions.name is 'reading'].actions.description
but it doesn't work (empty set but in my JSON it isn't so).
Any suggestion?
Is this what you are trying to do?
import objectpath
data = {
"user": {
"actions": {
"name": "reading",
"description": "blablabla"
},
"name": "John"
}
}
tree = objectpath.Tree(data)
result = tree.execute("$.user[#.name is 'John'].actions[#.name is 'reading'].description")
for entry in result:
print entry
Output
blablabla
I had to fix your JSON. Also, tree.execute returns a generator. You could replace the for loop with print result.next(), but the for loop seemed more clear.
import objectpath import *
your_json = {"name": "felix", "last_name": "diaz"}
# This json path will bring all the key-values of your json
your_json_path='$.*'
my_key_values = Tree(your_json).execute(your_json_path)
# If you want to retrieve the name node...then specify it.
my_name= Tree(your_json).execute('$.name')
# If you want to retrieve a the last_name node...then specify it.
last_name= Tree(your_json).execute('$.last_name')
I believe you're just missing a comma in JSON:
{
"user":
{
"actions": [
{
"name": "reading",
"description": "blablabla"
}
],
"name": "John"
}
}
Assuming there is only one "John", with only one "reading" activity, the following query works:
$.user[#.name is 'John'].actions[0][#.name is 'reading'][0].description
If there could be multiple "John"s, with multiple "reading" activities, the following query will almost work:
$.user.*[#.name is 'John'].actions..*[#.name is 'reading'].description
I say almost because the use of .. will be problematic if there are other nested dictionaries with "name" and "description" entries, such as
{
"user": {
"actions": [
{
"name": "reading",
"description": "blablabla",
"nested": {
"name": "reading",
"description": "broken"
}
}
],
"name": "John"
}
}
To get a correct query, there is an open issue to correctly implement queries into arrays: https://github.com/adriank/ObjectPath/issues/60

Categories