Django get value from JSON data - python

I am trying to play with an open fda API. So far everything works well. Issue is coming for nested JSON data.
Here is my Json data:
{
"seriousnessother": "1",
"reportduplicate": {
"duplicatenumb": "US-BRISTOL-MYERS SQUIBB COMPANY-BMS-2017-086135",
"duplicatesource": "BRISTOL MYERS SQUIBB"
},
"safetyreportversion": "1",
"receiptdate": "20170927",
"duplicate": "1",
"seriousnessdeath": "1",
"receivedate": "20170927",
"patient": {
"reaction": [
{
"reactionmeddrapt": "Death",
"reactionmeddraversionpt": "20.1",
"reactionoutcome": "5"
},
{
"reactionmeddrapt": "Product use in unapproved indication",
"reactionmeddraversionpt": "20.1",
"reactionoutcome": "6"
}
],
"patientsex": "1",
"drug": [
{
"drugstartdateformat": "102",
"medicinalproduct": "OPDIVO",
"drugindication": "COLORECTAL CANCER",
"drugcharacterization": "1",
"drugadministrationroute": "065",
"drugenddateformat": "102",
"drugseparatedosagenumb": "1",
"drugstructuredosageunit": "032",
"openfda": {
"manufacturer_name": [
"E.R. Squibb & Sons, L.L.C."
],
"unii": [
"31YO63LBSN"
],
"product_type": [
"HUMAN PRESCRIPTION DRUG"
],
"spl_set_id": [
"f570b9c4-6846-4de2-abfa-4d0a4ae4e394"
],
"route": [
"INTRAVENOUS"
],
"generic_name": [
"NIVOLUMAB"
],
"brand_name": [
"OPDIVO"
],
"product_ndc": [
"0003-3772",
"0003-3734",
"0003-3774"
],
"pharm_class_epc": [
"Programmed Death Receptor-1 Blocking Antibody [EPC]"
],
"substance_name": [
"NIVOLUMAB"
],
"spl_id": [
"2d33126d-5115-459e-bcaf-d0ace4fbe94e"
],
"pharm_class_moa": [
"Programmed Death Receptor-1-directed Antibody Interactions [MoA]"
],
"application_number": [
"BLA125554"
],
"nui": [
"N0000191259",
"N0000191260"
],
"package_ndc": [
"0003-3734-13",
"0003-3772-11",
"0003-3774-12"
]
},
"drugstructuredosagenumb": "1",
"drugintervaldosageunitnumb": "2",
"drugstartdate": "20160907",
"actiondrug": "5",
"activesubstance": {
"activesubstancename": "NIVOLUMAB"
},
"drugintervaldosagedefinition": "803",
"drugauthorizationnumb": "125554",
"drugrecurreadministration": "3",
"drugdosagetext": "1 DF, Q2WK",
"drugenddate": "20161222",
"drugadditional": "3"
}
]
},
"occurcountry": "US",
"reporttype": "1",
"companynumb": "US-BRISTOL-MYERS SQUIBB COMPANY-BMS-2017-086135",
"safetyreportid": "14015990",
"sender": {
"senderorganization": "FDA-Public Use",
"sendertype": "2"
},
"transmissiondate": "20171128",
"fulfillexpeditecriteria": "1",
"transmissiondateformat": "102",
"receiptdateformat": "102",
"receiver": {
"receiverorganization": "FDA",
"receivertype": "6"
},
"serious": "1",
"receivedateformat": "102",
"primarysource": {
"reportercountry": "US",
"qualification": "5"
},
"primarysourcecountry": "US"
}
Here is my view to call this data and convert to Django data.
json_data = open('/users/downloads/drug-bad.json').read()
response = json.loads(json_data)
a=0
b=0
for data in response['results']:
#try:
seriousnessother = data.get('seriousnessother')
reportduplicate_duplicatenumb = data['reportduplicate'].get('duplicatenumb')
reportduplicate_duplicatesource = data['reportduplicate'].get('duplicatesource')
safetyreportversion = data.get('safetyreportversion')
receiptdate = data.get('receiptdate')
duplicate = data.get('duplicate')
seriousnessdeath = data.get('seriousnessdeath')
receivedate = data.get('receivedate')
patient_reaction_reactionmeddrapt = data['patient']['reaction'].get('reactionmeddrapt')
patient_reaction_reactionmeddraversionpt = data['patient']['reaction'].get('reactionmeddraversionpt')
patient_reaction_reactionoutcome = data['patient']['reaction'].get('reactionoutcome')
patient_patientsex = data['patient'].get('patientsex')
patient_drug_medicinalproduct = data['patient']['drug'].get('medicinalproduct')
patient_drug_drugindication = data['patient']['drug'].get('drugindication')
patient_drug_drugcharacterization = data['patient']['drug'].get('drugcharacterization')
patient_drug_drugadministrationroute = data['patient']['drug'].get('drugadministrationroute')
patient_drug_drugseparatedosagenumb = data['patient']['drug'].get('drugseparatedosagenumb')
patient_drug_drugstructuredosageunit = data['patient']['drug'].get('drugstructuredosageunit')
patient_drug_openfda_manufacturer_name = data['patient']['drug']['openfda']['manufacturer'].get('name')
patient_drug_openfda_unii = data['patient']['drug']['openfda'].get('unii')
patient_drug_openfda_product_type = data['patient']['drug']['openfda']['product'].get('type')
patient_drug_openfda_spl_set_id = data['patient']['drug']['openfda']['spl']['set'].get('id')
patient_drug_openfda_route = data['patient']['drug']['openfda'].get('route')
patient_drug_openfda_generic_name = data['patient']['drug']['openfda']['generic'].get('name')
patient_drug_openfda_brand_name = data['patient']['drug']['openfda']['brand'].get('name')
patient_drug_openfda_product_ndc = data['patient']['drug']['openfda']['product'].get('ndc')
patient_drug_openfda_pharm_class_epc = data['patient']['drug']['openfda']['pharm']['class'].get('epc')
patient_drug_openfda_substance_name = data['patient']['drug']['openfda']['substance'].get('name')
patient_drug_openfda_spl_id = data['patient']['drug']['openfda']['spl'].get('id')
patient_drug_openfda_pharm_class_moa = data['patient']['drug']['openfda']['pharm']['class'].get('moa')
patient_drug_openfda_application_number = data['patient']['drug']['openfda']['application'].get('number')
patient_drug_openfda_nui = data['patient']['drug']['openfda'].get('nui')
patient_drug_openfda_package_ndc = data['patient']['drug']['openfda']['package'].get('ndc')
patient_drug_drugstructuredosagenumb = data['patient']['drug'].get('drugstructuredosagenumb')
patient_drug_drugintervaldosageunitnumb = data['patient']['drug'].get('drugintervaldosageunitnumb')
patient_drug_drugstartdate = data['patient']['drug'].get('drugstartdate')
patient_drug_actiondrug = data['patient']['drug'].get('actiondrug')
patient_drug_activesubstance_activesubstancename = data['patient']['drug']['activesubstance'].get('activesubstancename')
patient_drug_drugintervaldosagedefinition = data['patient']['drug'].get('drugintervaldosagedefinition')
patient_drug_drugauthorizationnumb = data['patient']['drug'].get('drugauthorizationnumb')
patient_drug_drugrecurreadministration = data['patient']['drug'].get('drugrecurreadministration')
patient_drug_drugdosagetext = data['patient']['drug'].get('drugdosagetext')
patient_drug_drugenddate = data['patient']['drug'].get('drugenddate')
patient_drug_drugadditional = data['patient']['drug'].get('drugadditional')
occurcountry = data.get('occurcountry')
reporttype = data.get('reporttype')
companynumb = data.get('companynumb')
safetyreportid = data.get('safetyreportid')
sender_senderorganization = data['sender'].get('senderorganization')
sender_sendertype = data['sender'].get('sendertype')
fulfillexpeditecriteria = data.get('fulfillexpeditecriteria')
receiver_receiverorganization = data['receiver'].get('receiverorganization')
receiver_receivertype = data['receiver'].get('receivertype')
serious = data.get('serious')
primarysource_reportercountry = data['primarysource'].get('reportercountry')
primarysource_qualification = data['primarysource'].get('qualification')
primarysourcecountry = data.get('primarysourcecountry')
I am getting following error:
patient_reaction_reactionmeddrapt = data['patient']['reaction'].get('reactionmeddrapt')
AttributeError: 'list' object has no attribute 'get'
Note that there are many data in response result. It could be that one of result does not have patient field. But as get method should return None if it does not exist.
I want either the field value or None.
It works for simple Json data but error comes when there are array/list inside array/list.

Since reaction is list you should do something like this:
reactions = data['patient']['reaction']
if reactions and isinstance(reactions, list):
for reaction in reactions:
patient_reaction_reactionmeddrapt = reaction.get('reactionmeddrapt')
else:
patient_reaction_reactionmeddrapt = data['patient']['reaction'].get('reactionmeddrapt')
instead of simple:
patient_reaction_reactionmeddrapt = data['patient']['reaction'].get('reactionmeddrapt')
data['patient']['reaction'] in your code return list objects. So you need to iterate over it to get reactionmeddrapt for each list element.

Given your input json:
"patient": {
"reaction": [
{
"reactionmeddrapt": "Death",
"reactionmeddraversionpt": "20.1",
"reactionoutcome": "5"
},
{
"reactionmeddrapt": "Product use in unapproved indication",
"reactionmeddraversionpt": "20.1",
"reactionoutcome": "6"
}
],
The data value for "reactions" is a list. Also as I understand it, you want to get the "reactionmeddrapt" attribute value or None if you don't have a data value for "patient".
You could do something like this:
try:
reactions = data['patient']['reaction']
except KeyError:
return None
if reactions and isinstance(reactions, list):
# Assuming you want to iterate over the list
for reaction in reactions:
reactionmeddrapt = reaction.get('reactionmeddrapt')

Related

How can I iterate through a dictionary and use context managers in Python?

The dictionary I am trying to iterate through has the following structure:
d = {
"main_key_1": {
"name": "Name1",
"context": "Context1",
"message": "Message1",
"date": "Date1",
"reference": "Reference1"
},
"main_key_2": {
"name": "Name2",
"context": "Context2",
"message": "Message2",
"date": "Date2",
"reference": "Reference2"
}
}
This is the way I tried to iterate:
for item in d.items():
from_context = f"from {item[1]['context']}"
with context('given a descriptor'):
with context(from_context):
with before.all:
self.descriptor = item[1]['message']
with context('that contains a date'):
with it('recognizes the date'):
adapter = MessageToDatetAdapter(self.descriptor)
result = adapter.is_a_date()
expect(result).to(equal(True))
with it('extracts the date data'):
adapter = MessageToDatetAdapter(self.descriptor)
result = adapter.adapt()
expect(result['date']).to(equal(item[1]['date']))
expect(result['reference']).to(item[1]['reference'])
The first iteration would be something like below:
with context('given a descriptor'):
with context('from Context1'):
with before.all:
self.descriptor = 'Message1'
with context('that contains a date'):
with it('recognizes the date'):
adapter = MessageToDatetAdapter(self.descriptor)
result = adapter.is_a_date()
expect(result).to(equal(True))
with it('extracts the date data'):
adapter = MessageToDatetAdapter(self.descriptor)
result = adapter.adapt()
expect(result['date']).to('Date1')
expect(result['reference']).to('Reference1')
However, it seems like this is not correct. It looks like I cannot iterate through all the dictionary items.

Add json data recursively to json object python

I have this initial json which I made in this piece of code:
menu_structure = []
menu_root = cursor.fetchall()
for menu_item in menu_root:
menu_structure.append({"name": menu_item[1]})
get_tree_branch(lang=lang, id_parent=menu_item[0], parent_name=menu_item[1], menu_structure=menu_structure,
cursor=cursor)
JSON 1
[
{
"name": "Fish",
"children": [
{
"name": "Fish of two waters"
},
{
"name": "Sea water fish"
},
{
"name": "Fresh water fish"
}
]
},
{
"name": "Seafood"
}
]
I made a sql petition to see if Fish of two waters has a children, if it has a children then I only receive a string with the name of children and I want to add the children to the json object like this:
JSON 2
[
{
"name": "Fish",
"children": [
{
"name": "Fish of two waters",
"children": [
{
"name": "Test fish"
}]
},
{
"name": "Sea water fish"
},
{
"name": "Fresh water fish"
}
]
},
{
"name": "Seafood"
}
]
To do that in my python code I do this:
def get_tree_branch(lang: str, id_parent: int, menu_structure, cursor):
sql_query = "select ps_category.id_category, name from ps_category Right Join ps_category_lang On " \
"ps_category.id_category = ps_category_lang.id_category Right Join ps_lang on " \
"ps_category_lang.id_lang = ps_lang.id_lang where ps_category.is_root_category = 0 " \
"AND ps_category.id_parent like %s AND ps_lang.lang_name = %s"
sql_params = (id_parent, lang)
cursor.execute(query=sql_query, args=sql_params)
menu_branch = cursor.fetchall()
if menu_branch:
menu_structure[len(menu_structure) - 1]["children"] = []
for menu_item in menu_branch:
menu_structure[len(menu_structure) - 1]["children"].append({"name": menu_item[1]})
get_tree_branch(lang=lang, id_parent=menu_item[0], menu_structure=menu_structure, cursor=cursor)
else:
return
But that code instead does this json:
JSON 3
[
{
"name": "Fish",
"children": [
{
"name": "Test fish"
},
{
"name": "Sea water fish"
},
{
"name": "Fresh water fish"
}
]
},
{
"name": "Seafood"
}
]
Any suggestions on how to create a json object like the JSON 2?
For those interested I did this, hope it helps
def get_tree_menu(lang: int):
test_db = init_database()
cursor = test_db.cursor()
menu_structure = []
sql_query = """select c.id_category, cl.name from ps_category_lang as cl
left join ps_category c on cl.id_category = c.id_category
where c.is_root_category = 1 AND cl.id_lang = %s AND c.active = 1
order by c.position asc"""
cursor.execute(query=sql_query, args=lang)
menu_root = cursor.fetchall()
id_category = 0
name = 1
for menu_item in menu_root:
menu_structure.append({"name": menu_item[name]})
get_tree_branch(lang=lang, id_parent=menu_item[id_category], parent_name=menu_item[name],
menu_structure=menu_structure, cursor=cursor)
cursor.close()
close_database(test_db=test_db)
return menu_structure
def get_tree_branch(lang: int, id_parent: int, parent_name: str, menu_structure, cursor):
sql_query = """select c.id_category, cl.name from ps_category_lang as cl
left join ps_category c on cl.id_category = c.id_category
where c.is_root_category = 0 AND c.id_parent = %s AND cl.id_lang = %s AND c.active = 1
order by c.position asc"""
sql_params = (id_parent, lang)
cursor.execute(query=sql_query, args=sql_params)
menu_branch = cursor.fetchall()
id_category = 0
name = 1
if menu_branch:
for menu_item in menu_branch:
menu_structure = create_json_structure(json_object=menu_structure, search_value=parent_name,
child_name=menu_item[name])
get_tree_branch(lang=lang, id_parent=menu_item[id_category], parent_name=menu_item[name],
menu_structure=menu_structure, cursor=cursor)
else:
return
def create_json_structure(json_object: any, search_value: str, child_name: str):
"""Recursively search for values of key in JSON tree and add a child to the JSON element."""
if isinstance(json_object, dict):
for key, value in json_object.items():
if isinstance(value, (dict, list)):
create_json_structure(json_object=value, search_value=search_value, child_name=child_name)
else:
if value == search_value:
try:
json_object["children"].append({
"parentName": search_value,
"name": child_name
})
except KeyError:
json_object["children"] = []
json_object["children"].append({
"parentName": search_value,
"name": child_name
})
break
elif isinstance(json_object, list):
for item in json_object:
create_json_structure(json_object=item, search_value=search_value, child_name=child_name)
return json_object

Better way of grabbing elements from JSON object?

This program takes input from a web socket in the form of a JSON object that represents the order book of multiple bitcoin exchanges combined. I have modified the example by deleting the other bids and asks from the first section. The first bid and first ask are all I need to grab.
{
"payload": {
"asks": [
[
8329.01,
0.19875089,
"gemini"
],
],
"bids": [
[
8330.55,
16.04230494,
"market1"
],
],
"currency": "usd",
"lastpublished": 1579970355700,
"lastupdated": 1579970355660,
"market_making": {
"asks": [
[
8344.88,
0.57580068,
"bittrex"
],
[
8336.48,
2,
"bitstamp"
],
[
8330.56,
0.18606522,
"market1"
],
[
8329.01,
0.19875089,
"gemini"
]
],
"bids": [
[
8325.271,
0.0766122,
"bittrex"
],
[
8325.51,
1.1984,
"bitstamp"
],
[
8329,
13.07297146,
"gemini"
],
[
8330.55,
16.04230494,
"market1"
]
]
},
"pair": "btcusd",
"timestamps": {
"bitstamp": [
1579970355573,
1579970355573
],
"bittrex": [
1579970354809,
1579970355010
],
"gemini": [
1579970355374,
1579970355376
],
"market1": [
1579970354799,
1579970354799
]
}
},
"recipient": "orderbook.sfox.btcusd",
"sequence": 2,
"timestamp": 1579970355757434509
}
When making my program I couldn't get json.loads() to return a list or dict, instead I could only get a string result. My code right now just finds the slice where both of these elements should be, but that seems inefficient, and causes issues when the message isn't as I expect.
async def main(uri):
async with websockets.connect(uri) as ws:
subscribe_msg = {
"type": "subscribe",
"feeds": ["orderbook.sfox.btcusd"],
}
await ws.send(json.dumps(subscribe_msg))
async for msg in ws:
#print(msg)
json.loads(msg)
if msg[2] == "s":
ask = float(msg[msg.find("asks") + 8 : msg.find(",", msg.find("asks")+8)])
asksize = float(msg[msg.find(",", msg.find("asks")+8)+1:
msg.find(",", msg.find(",", msg.find("asks")+8)+1)])
bid = float(msg[msg.find("bids") + 8 : msg.find(",", msg.find("bids")+8)])
bidsize = float(msg[msg.find(",", msg.find("bids")+8)+1:
msg.find(",", msg.find(",", msg.find("bids")+8)+1)])
time = msg[msg.find("timestamp") + 11 :msg.find(",",msg.find("timestamp") + 11)]
oppmonitor(bid, bidsize, ask, asksize)
print("Time", time, "Bid", bid, "Bid Size", bidsize, "Ask", ask, "Ask Size", asksize)
else:
print("Starting Message")
The program works I just need a more efficient way of getting the bid and ask. Preferably one that doesn't involve slicing the json object.

python flask mongodb insert data

how do i insert data to a specific user in python flask mongodb
{
"_id" : ObjectId("5e208aa1f86973bbd7db6e8a"),
"worker_name" : "user1",
"location" : "location1",
"detection" : [ ]
},
{
"_id" : ObjectId("5e208aa1f86973bbd7db6e8b"),
"worker_name" : "user2",
"location" : "location2",
"detection" : [ ]
}
above are my users, I want to insert some data in user1 detection list, below are my code i had tried
def face_detection():
face_module = mongo.db.face_modules
user = mongo.db.users
stream_link = request.form['stream_link']
location = request.form['location']
camera = request.form['camera']
result = {
"location": location,
"stream_url": stream_link,
"worker_name": "user1",
"date": "1/1/2020",
"hour": "9",
"minute": "10",
"second": "25"
}
if user.find({"worker_name": result['worker_name']}).count() > 0:
update_user = user.detection.insert(result)
output = "user updated"
return jsonify({'result': output})
Since the document already exists you need to update it rather than insert, Also as you wanted to insert something into an array it should be through $push, Plus instead of making two DB calls you can use find_one_and_update which will return updated document with this option :: return_document = ReturnDocument.AFTER or will return none incase of no matching document found. Based on that you can return the response. In general you would use insert or insert_one for inserting a new document to colleciton. I'm a bit new to pymongo, Please add the code to check error scenario from DB, Plus test this code & you're feel free to update this answer with any findings..
Try this :
def face_detection():
face_module = mongo.db.face_modules
user = mongo.db.users
stream_link = request.form['stream_link']
location = request.form['location']
camera = request.form['camera']
result = {
"location": location,
"stream_url": stream_link,
"worker_name": "user1",
"date": "1/1/2020",
"hour": "9",
"minute": "10",
"second": "25"
}
resp = user.find_one_and_update(
{"worker_name": result['worker_name']},
{ '$push': {'detection' : result} },
return_document = ReturnDocument.AFTER)
if resp :
return jsonify({'result': resp})
else :
return jsonify({'result': 'No document found'})

Recursively generate subset of list in python

I have a json file that looks something like the following:
[
{
"category1":"0120391123123"
},
[
{
"subcategory":"0120391123123"
},
[
{
"subsubcategory":"019301948109"
},
[
{
"subsubsubcategory":"013904123908"
},
[
{
"subsubsubsubcategory":"019341823908"
}
]
]
]
],
[
{
"subcategory2":"0934810923801"
},
[
{
"subsubcategory2":"09341829308123"
}
]
],
[
{
"category2":"1309183912309"
},
[
{
"subcategory":"10293182094"
}
]
]
]
I also have a list of categories that I would like to find in the original list. If the category exists in categoriesToFind, I would also like to find all subcategories and return those as well.
categoriesToFind = ['019301948109', '1309183912309']
finalCategories = []
def findCategories(currentList, isFirstIteration):
for x in currentList:
if type(x) is dict and (next(iter(x.values())) in categoriesToFind or not isFirstIteration):
finalCategories.append(next(iter(x.values())))
if len(currentList) < currentList.index(x) + 1:
findCategories(currentList[currentList.index(x) + 1], False)
findCategories(data, True)
I would want finalCategories to contain the following:
['019301948109', '013904123908', '019341823908', '1309183912309', '10293182094']
You can use recursion with a generator:
categoriesToFind = ['019301948109', '1309183912309']
d = [{'category1': '0120391123123'}, [{'subcategory': '0120391123123'}, [{'subsubcategory': '019301948109'}, [{'subsubsubcategory': '013904123908'}, [{'subsubsubsubcategory': '019341823908'}]]]], [{'subcategory2': '0934810923801'}, [{'subsubcategory2': '09341829308123'}]], [{'category2': '1309183912309'}, [{'subcategory': '10293182094'}]]]
def get_subcategories(_d, _flag):
flag = None
for i in _d:
if isinstance(i, dict):
_val = list(i.values())[0]
if _val in categoriesToFind or _flag:
yield _val
flag = True
else:
yield from get_subcategories(i, _flag or flag)
print(list(get_subcategories(d, False)))
Output:
['019301948109', '013904123908', '019341823908', '1309183912309', '10293182094']

Categories

Resources