How can I add if statements to a json dictionary in Python - python

Is it possible to change a json dictionary payload with if statements?
I have 4 types that say have IDs 1,2,3,4 so I need some sort of select switch code.
The original code is:
payload = {
"added": [
{
"assingedTargets": [
{
"sequencing": 1,
"name": assigned_target_name,
"id": assigned_target_id
}
],
"type": {
"protocol": {
"isDefaultProtocol": True,
"name": "tcp",
"id": 3,
"label": "tcp"
},
"name": target_type,
"id": int(1)
},
"name":"DDITargetGroup5"
}
]
}
What I would like to do is:
payload = {
"added": [
{
"assingedTargets": [
{
"sequencing": 1,
"name": assigned_target_name,
"id": assigned_target_id
}
],
"type": {
"protocol": {
"isDefaultProtocol": True,
"name": "tcp",
"id": 3,
"label": "tcp"
},
if target_type: == "direct dial"
"name": target_type,
"id": int(1)
elif target_type == "private Wire"
"name": target_type
"id": int(2)
},
"name":"DDITargetGroup5"
}
]
}
I get the error:
if target_type: == "direct dial"
^
SyntaxError: invalid syntax
Process finished with exit code 1

If there are just two options, you could use the ternary operator
{
...
"name": target_type,
"id": 1 if target_type == 'direct dial' else 2,
...
}
However, it comes with a cost of readability, so you should consider whether wouldn't be better to separate the conditional statement from the dict.

You can't just plop a conditional statement into a json object. Instead you should create a variable to store the id value (id_val) and use a conditional before you make the object to set its value based on the value of target_type. Then set the dictionary to have the values of those variables (see below).
id_val = 0
if target_type == 'direct dial':
id_val = 1
elif target_type == 'private Wire':
id_val = 2
payload = { "added": [ { "assingedTargets": [ { "sequencing": 1, "name": assigned_target_name, "id": assigned_target_id } ], "type": { "protocol": { "isDefaultProtocol": True, "name": "tcp", "id": 3, "label": "tcp" }, "name": target_type, "id": id_val }, "name":"DDITargetGroup5" } ] }

Related

How to read fields without numeric index in JSON

I have a json file where I need to read it in a structured way to insert in a database each value in its respective column, but in the tag "customFields" the fields change index, example: "Tribe / Customer" can be index 0 (row['customFields'][0]) in a json block, and in the other one be index 3 (row['customFields'][3]), so I tried to read the data using the name of the row field ['customFields'] ['Tribe / Customer'], but I got the error below:
TypeError: list indices must be integers or slices, not str
Script:
def getCustomField(ModelData):
for row in ModelData["data"]["squads"][0]["cards"]:
print(row['identifier'],
row['customFields']['Tribe / Customer'],
row['customFields']['Stopped with'],
row['customFields']['Sub-Activity'],
row['customFields']['Activity'],
row['customFields']['Complexity'],
row['customFields']['Effort'])
if __name__ == "__main__":
f = open('test.json')
json_file = json.load(f)
getCustomField(json_file)
JSON:
{
"data": {
"squads": [
{
"name": "TESTE",
"cards": [
{
"identifier": "0102",
"title": "TESTE",
"description": " TESTE ",
"status": "on_track",
"priority": null,
"assignees": [
{
"fullname": "TESTE",
"email": "TESTE"
}
],
"createdAt": "2020-04-16T15:00:31-03:00",
"secondaryLabel": null,
"primaryLabels": [
"TESTE",
"TESTE"
],
"swimlane": "TESTE",
"workstate": "Active",
"customFields": [
{
"name": "Tribe / Customer",
"value": "TESTE 1"
},
{
"name": "Checkpoint",
"value": "GNN"
},
{
"name": "Stopped with",
"value": null
},
{
"name": "Sub-Activity",
"value": "DEPLOY"
},
{
"name": "Activity",
"value": "TOOL"
},
{
"name": "Complexity",
"value": "HIGH"
},
{
"name": "Effort",
"value": "20"
}
]
},
{
"identifier": "0103",
"title": "TESTE",
"description": " TESTE ",
"status": "on_track",
"priority": null,
"assignees": [
{
"fullname": "TESTE",
"email": "TESTE"
}
],
"createdAt": "2020-04-16T15:00:31-03:00",
"secondaryLabel": null,
"primaryLabels": [
"TESTE",
"TESTE"
],
"swimlane": "TESTE",
"workstate": "Active",
"customFields": [
{
"name": "Tribe / Customer",
"value": "TESTE 1"
},
{
"name": "Stopped with",
"value": null
},
{
"name": "Checkpoint",
"value": "GNN"
},
{
"name": "Sub-Activity",
"value": "DEPLOY"
},
{
"name": "Activity",
"value": "TOOL"
},
{
"name": "Complexity",
"value": "HIGH"
},
{
"name": "Effort",
"value": "20"
}
]
}
]
}
]
}
}
You'll have to parse the list of custom fields into something you can access by name. Since you're accessing multiple entries from the same list, a dictionary is the most appropriate choice.
for row in ModelData["data"]["squads"][0]["cards"]:
custom_fields_dict = {field['name']: field['value'] for field in row['customFields']}
print(row['identifier'],
custom_fields_dict['Tribe / Customer'],
...
)
If you only wanted a single field you could traverse the list looking for a match, but it would be less efficient to do that repeatedly.
I'm skipping over dealing with missing fields - you'd probably want to use get('Tribe / Customer', some_reasonable_default) if there's any possibility of the field not being present in the json list.

Accessing nested value in loop in json using python

I want to fetch the value of each api3 in this json object where each array has api3 value.
{
"count": 10,
"result": [
{
"type": "year",
"year": {
"month": {
"api1": {
"href": "https://Ap1.com"
},
"api2": {
"href": "FETCH-CONTENT"
},
"api3": {
"href": "https://Ap3.com"
},
"api4": {
"href": "https://Ap4.com"
}
},
"id": "sdvnkjsnvj",
"summary": "summeryc",
"type": "REST",
"apiId": "mlksmfmksdfs",
"idProvider": {
"id": "sfsmkfmskf",
"name": "Apikey"
},
"tags": []
}
},
{
"type": "year1",
"year": {
"month": {
"api1": {
"href": "https://Ap11.com"
},
"api2": {
"href": "FETCH-CONTENT-1"
},
"api3": {
"href": "https://Ap13.com"
},
"api4": {
"href": "https://Ap14.com"
}
},
"id": "sdvnkjsnvj",
"summary": "summeryc",
"type": "REST",
"apiId": "mlksmfmksdfs",
"idProvider": {
"id": "sfsmkfmskf",
"name": "Apikey"
},
"tags": []
}
},
I am able to get the whole json object and first value inside it.
with open('C:\python\examplee.json','r+') as fr:
data = json.load(fr)
print(data["result"])
Thank you in advance for helping me figuring this.
For each element in list of result key, get the value for the nested dictionary within item
print([item['year']['month']['api3'] for item in data['result']])
The output will be [{'href': 'https://Ap3.com'}, {'href': 'https://Ap13.com'}]
Or if you want to get the href value as well
print([item['year']['month']['api3']['href'] for item in data['result']])
The output will be
['https://Ap3.com', 'https://Ap13.com']
So your whole code will look like
data = {}
with open('C:\python\examplee.json','r+') as fr:
data = json.load(fr)
print([item['year']['month']['api3']['href'] for item in dct['result']])
Looks like your JSON schema is static so you can just use this:
print([x['year']['month']['api3']['href'] for x in data['result']])
will return you:
['https://Ap3.com', 'https://Ap13.com']

Create dynamic json object in python

I have a dictionary which is contain multiple keys and values and the values also contain the key, value pair. I am not getting how to create dynamic json using this dictionary in python. Here's the dictionary:
image_dict = {"IMAGE_1":{"img0":"IMAGE_2","img1":"IMAGE_3","img2":"IMAGE_4"},"IMAGE_2":{"img0":"IMAGE_1", "img1" : "IMAGE_3"},"IMAGE_3":{"img0":"IMAGE_1", "img1":"IMAGE_2"},"IMAGE_4":{"img0":"IMAGE_1"}}
My expected result like this :
{
"data": [
{
"image": {
"imageId": {
"id": "IMAGE_1"
},
"link": {
"target": {
"id": "IMAGE_2"
},
"target": {
"id": "IMAGE_3"
},
"target": {
"id": "IMAGE_4"
}
}
},
"updateData": "link"
},
{
"image": {
"imageId": {
"id": "IMAGE_2"
},
"link": {
"target": {
"id": "IMAGE_1"
},
"target": {
"id": "IMAGE_3"
}
}
},
"updateData": "link"
},
{
"image": {
"imageId": {
"id": "IMAGE_3"
},
"link": {
"target": {
"id": "IMAGE_1"
},
"target": {
"id": "IMAGE_2"
}
}
},
"updateData": "link"
} ,
{
"image": {
"imageId": {
"id": "IMAGE_4"
},
"link": {
"target": {
"id": "IMAGE_1"
}
}
},
"updateData": "link"
}
]
}
I tried to solve it but I didn't get expected result.
result = {"data":[]}
for k,v in sorted(image_dict.items()):
for a in sorted(v.values()):
result["data"].append({"image":{"imageId":{"id": k},
"link":{"target":{"id": a}}},"updateData": "link"})
print(json.dumps(result, indent=4))
In Python dictionaries you can't have 2 values with the same key. So you can't have multiple targets all called "target". So you can index them. Also I don't know what this question has to do with dynamic objects but here's the code I got working:
import re
dict_res = {}
ind = 0
for image in image_dict:
lin_ind = 0
sub_dict = {'image' + str(ind): {'imageId': {image}, 'link': {}}}
for sub in image_dict[image].values():
sub_dict['image' + str(ind)]['link'].update({'target' + str(lin_ind): {'id': sub}})
lin_ind += 1
dict_res.update(sub_dict)
ind += 1
dict_res = re.sub('target\d', 'target', re.sub('image\d', 'image', str(dict_res)))
print dict_res

Parsing JSON with python- list indices must be integer not str

I am beginner at python and am trying to parse the following JSON. I am not able to find out how to get the artist name and title of the song.
{
"status": {
"msg": "Success",
"code": 0,
"version": "1.0"
},
"metadata": {
"music": [
{
"external_ids": {
"isrc": "USSM10603618",
"upc": "888880170897"
},
"play_offset_ms": 8920,
"external_metadata": {
"spotify": {
"album": {
"id": "0JLv6iVbeiy4Dh2eIw6FKI"
},
"artists": [
{
"id": "6vWDO969PvNqNYHIOW5v0m"
}
],
"track": {
"id": "3qSMg1lhn4jDwWlI9xCVyK"
}
},
"itunes": {
"album": {
"id": 464320979
},
"artists": [
{
"id": 1419227
}
],
"track": {
"id": 464321089
}
},
"deezer": {
"album": {
"id": 72429
},
"artists": [
{
"id": 145
}
],
"genres": [
{
"id": 132
}
],
"track": {
"id": 551232
}
}
},
"title": "Listen (From the Motion Picture \"Dreamgirls\")",
"duration_ms": "217786",
"album": {
"name": "B'Day Deluxe Edition"
},
"acrid": "4660601066a3153acf15eabe2868572b",
"genres": [
{
"name": "Pop"
}
],
"artists": [
{
"name": "Beyoncé"
}
]
}
],
"timestamp_utc": "2015-07-27 10:35:28"
},
"result_type": 0
}
My code is :
json_r=json.loads(res)
print(json_r)
for i in json_r:
song_name=json_r.metadata['music']['title']
print song_name
artist=json_r['metadata']['music']['artists']['name']
s_t_id=json_r['metadata']['music']['external_metadata']['spotify']['track']['id']
s_a_id=json_r['metadata']['music']['external_metadata']['spotify']['artists']['id']
I am getting the following error:
list indices must be integer not str
Please help
Their is a much more simpler way of doing this:
import json
from pprint import pprint
with open('D:/data.json') as data_file:
data = json.load(data_file)
pprint(data)
Try the above code this will print your file in terms of a dictionary.
Then you can simpley access it's element by using it's key indexes to
access it's value something like this :
print data['status']['msg']
print data['metadata']['music'][0]['album']['name']
Just make sure that which element you are trying to access, wether it's a list or dictionary, as in case of list [] you might need to use indexes , as explained in second example.
See this data:
"artists": [
{
"id": "6vWDO969PvNqNYHIOW5v0m"
}
],
"track": {
"id": "3qSMg1lhn4jDwWlI9xCVyK"
}
your "artists" data is a list, that's why you cannot access it like ["artists"]["id"], but ["artists"][0]["id"] will work.
See below example for a clearer picture:
In [1]: a = [{"hello": "world"}, "yes I am"]
In [2]: a["hello"]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-2-817deb35df57> in <module>()
----> 1 a["hello"]
TypeError: list indices must be integers, not str
In [3]: a[0]
Out[3]: {'hello': 'world'}
In [4]: a[0]["hello"]
Out[4]: 'world'
In [5]: a[1]
Out[5]: 'yes I am'
Since "a" is a list, accessing its element can be done by index, ie. a[0], a[1]...
and a[0] is a dictionary {"hello": "world"}, so dictionary value can be accessed by first accessing its index 0, then the key "hello", as like a[0]["hello"].

Unable to pull data from json using python

I have the following json
{
"response": {
"message": null,
"exception": null,
"context": [
{
"headers": null,
"name": "aname",
"children": [
{
"type": "cluster-connectivity",
"name": "cluster-connectivity"
},
{
"type": "consistency-groups",
"name": "consistency-groups"
},
{
"type": "devices",
"name": "devices"
},
{
"type": "exports",
"name": "exports"
},
{
"type": "storage-elements",
"name": "storage-elements"
},
{
"type": "system-volumes",
"name": "system-volumes"
},
{
"type": "uninterruptible-power-supplies",
"name": "uninterruptible-power-supplies"
},
{
"type": "virtual-volumes",
"name": "virtual-volumes"
}
],
"parent": "/clusters",
"attributes": [
{
"value": "true",
"name": "allow-auto-join"
},
{
"value": "0",
"name": "auto-expel-count"
},
{
"value": "0",
"name": "auto-expel-period"
},
{
"value": "0",
"name": "auto-join-delay"
},
{
"value": "1",
"name": "cluster-id"
},
{
"value": "true",
"name": "connected"
},
{
"value": "synchronous",
"name": "default-cache-mode"
},
{
"value": "true",
"name": "default-caw-template"
},
{
"value": "blah",
"name": "default-director"
},
{
"value": [
"blah",
"blah"
],
"name": "director-names"
},
{
"value": [
],
"name": "health-indications"
},
{
"value": "ok",
"name": "health-state"
},
{
"value": "1",
"name": "island-id"
},
{
"value": "blah",
"name": "name"
},
{
"value": "ok",
"name": "operational-status"
},
{
"value": [
],
"name": "transition-indications"
},
{
"value": [
],
"name": "transition-progress"
}
],
"type": "cluster"
}
],
"custom-data": null
}
}
which im trying to parse using the json module in python. I am only intrested in getting the following information out of it.
Name Value
operational-status Value
health-state Value
Here is what i have tried.
in the below script data is the json returned from a webpage
json = json.loads(data)
healthstate= json['response']['context']['operational-status']
operationalstatus = json['response']['context']['health-status']
Unfortunately i think i must be missing something as the above results in an error that indexes must be integers not string.
if I try
healthstate= json['response'][0]
it errors saying index 0 is out of range.
Any help would be gratefully received.
json['response']['context'] is a list, so that object requires you to use integer indices.
Each item in that list is itself a dictionary again. In this case there is only one such item.
To get all "name": "health-state" dictionaries out of that structure you'd need to do a little more processing:
[attr['value'] for attr in json['response']['context'][0]['attributes'] if attr['name'] == 'health-state']
would give you a list of of matching values for health-state in the first context.
Demo:
>>> [attr['value'] for attr in json['response']['context'][0]['attributes'] if attr['name'] == 'health-state']
[u'ok']
You have to follow the data structure. It's best to interactively manipulate the data and check what every item is. If it's a list you'll have to index it positionally or iterate through it and check the values. If it's a dict you'll have to index it by it's keys. For example here is a function that get's the context and then iterates through it's attributes checking for a particular name.
def get_attribute(data, attribute):
for attrib in data['response']['context'][0]['attributes']:
if attrib['name'] == attribute:
return attrib['value']
return 'Not Found'
>>> data = json.loads(s)
>>> get_attribute(data, 'operational-status')
u'ok'
>>> get_attribute(data, 'health-state')
u'ok'
json['reponse']['context'] is a list, not a dict. The structure is not exactly what you think it is.
For example, the only "operational status" I see in there can be read with the following:
json['response']['context'][0]['attributes'][0]['operational-status']

Categories