Appending a list inside of a JSON - Python 2.7 - python

My JSON dict looks like this:
{
"end": 1,
"results": [
{
"expired": false,
"tag": "search"
},
{
"span": "text goes here"
}
],
"totalResults": 1
}
which is the product of this line:
tmp_response['results'].append({'span':"text goes here"})
My goal is to get the "span" key into the "results" list. This is necessary for when totalResults > 1.
{
"end": 1,
"results": [
{
"expired": false,
"tag": "search",
"span": "text goes here"
},
],
"totalResults": 1
}
I've tried several methods, for example with use 'dictname.update', but this overwrites the existing data in 'results'.

tmp_response['results'][0]['span'] = "text goes here"
or, if you really wanted to use update:
tmp_response['results'][0].update({'span':"text goes here"})
but note that is an unnecessary creation of a dict.

Here is one more solution if you want you can use below code.
>>> tmp_response = {"end": 1,"results": [{"expired": False,"tag": "search"},{"span": "text goes here"}],"totalResults": 1}
>>> tmp_response['results'][0] = dict(tmp_response['results'][0].items() + {'New_entry': "Ney Value"}.items())
>>> tmp_response
{'totalResults': 1, 'end': 1, 'results': [{'tag': 'search', 'expired': False, 'New_entry': 'Ney Value'}, {'span': 'text goes here'}]}
>>>

Related

Is there a way to get the particular Values from JSON Array using robot or Python code?

JSON OUTPUT:
${response}= [
{
"Name":"7122Project",
"checkBy":[
{
"keyId":"NA",
"target":"1232"
}
],
"Enabled":false,
"aceess":"123"
},
{
"Name":"7122Project",
"checkBy":[
{
"keyId":"_GU6S3",
"target":"123"
}
],
"aceess":"11222",
"Enabled":false
},
{
"Name":"7122Project",
"checkBy":[
{
"keyId":"-1lLUy",
"target":"e123"
}
],
"aceess":"123"
}
]
Need to get the keyId values from json without using hardcoded index using robot?
I did
${ID}= set variable ${response[0]['checkBy'][0]['keyId']}
But I need to check the length get all keyID values and store the values that dose not contain NA
How can I do check length and use for loop using robot framework?
I suppose you can have more elements in checkBy arrays, like so:
response = [
{
"Name":"7122Project",
"checkBy": [
{
"keyId": "NA",
"target": "1232"
}
],
"Enabled": False,
"aceess": "123"
},
{
"Name": "7122Project",
"checkBy": [
{
"keyId": "_GUO6g6S3",
"target": "123"
}
],
"aceess": "11222",
"Enabled": False
},
{
"Name": "7122Project",
"checkBy": [
{
"keyId": "-1lLlZOUy",
"target": "e123"
},
{
"keyId": "test",
"target": "e123"
}
],
"aceess": "123"
}
]
then you can key all keyIds in Python with this code:
def get_key_ids(response):
checkbys = [x["checkBy"] for x in response]
key_ids = []
for check_by in checkbys:
for key_id in check_by:
key_ids.append(key_id["keyId"])
return key_ids
for the example above, it will return: ['NA', '_GUO6g6S3', '-1lLlZOUy', 'test_NA'].
You want to get both ids with NA and without NA, so perhaps you can change the function a bit:
def get_key_ids(response, predicate):
checkbys = [x["checkBy"] for x in response]
key_ids = []
for check_by in checkbys:
for key_id in check_by:
if predicate(key_id["keyId"]):
key_ids.append(key_id["keyId"])
return key_ids
and use it like so:
get_key_ids(response, lambda id: id == "NA") # ['NA']
get_key_ids(response, lambda id: id != "NA") # ['_GUO6g6S3', '-1lLlZOUy', 'test_NA']
get_key_ids(response, lambda id: "NA" in id) # ['NA', 'test_NA']
get_key_ids(response, lambda id: "NA" not in id) # ['_GUO6g6S3', '-1lLlZOUy']
Now it's just a matter of creating a library and importing it into RF. You can get inspiration in the official documentation.
But I need to check the length get all keyID values and store the values that dose not contain NA
I don't completely understand what you are up to. Do you mean length of keyId strings, like "NA" and its length of 2, or the number of keyIds in the response?
How can I do check length and use for loop using robot framework?
You can use keyword Should Be Equal * from BuiltIn library. Some examples of for loops could be found in the user guide here.
Now you should have all the parts you need to accomplish your task, you can try to put it all together.

JSON Parsing in Python - help extracting dictionaries inside a list

I've searched and there's a similar problem here but the solution states to fix the json. I really cant fix the json produced as its from a REST API.
{
"__metadata": {
"uri": "http://website:6405/biprws/v1/cmsquery?page=1&pagesize=50"
},
"first": {
"__deferred": {
"uri": "http://website:6405/biprws/v1/cmsquery?page=1&pagesize=50"
}
},
"last": {
"__deferred": {
"uri": "http://website:6405/biprws/v1/cmsquery?page=1&pagesize=50"
}
},
"entries": [
{
"SI_ID": 31543,
"SI_NAME": "Some Client",
"SI_PARENTID": 31414,
"SI_PATH": {
"SI_FOLDER_NAME1": "COR OPS",
"SI_FOLDER_ID1": 31414,
"SI_FOLDER_OBTYPE1": 1,
"SI_FOLDER_NAME2": "CLIENT",
"SI_FOLDER_ID2": 28178,
"SI_FOLDER_OBTYPE2": 1,
"SI_NUM_FOLDERS": 2
}
}
]
}
I need to be able to get the folder names from SI_PATH, but that is where I am having issues. I can access "entries" fine as the whole json is considered as a dict, but the problem is after. If I get "entries", its just a list with a len of 1
import json
data = json.load(open('file.json'))
print(type(data))
print(data['entries])
print(type(data['entries']))
Sample output below:
<class 'dict'>
<class 'list'>
[{'SI_ID': 31543, 'SI_NAME': 'Some Client', 'SI_PARENTID': 31414, 'SI_PATH': {'SI_FOLDER_NAME1': 'COR OPS', 'SI_FOLDER_ID1': 31414, 'SI_FOLDER_OBTYPE1': 1, 'SI_FOLDER_NAME2': 'CLIENT', 'SI_FOLDER_ID2': 28178, 'SI_FOLDER_OBTYPE2': 1, 'SI_NUM_FOLDERS': 2}}]
I can use pandas to put the 'entries' onto a DataFrame and pull in the SI_PATH values, but not sure how to access each of them.
f = pd.DataFrame(data['entries'])
print(f['SI_PATH'].values)
Output of this:
[{'SI_FOLDER_NAME1': 'COR OPS', 'SI_FOLDER_ID1': 31414, 'SI_FOLDER_OBTYPE1': 1, 'SI_FOLDER_NAME2': 'CLIENT', 'SI_FOLDER_ID2': 28178, 'SI_FOLDER_OBTYPE2': 1, 'SI_NUM_FOLDERS': 2}]
But unsure as to how to access the items individual from this point. If possible, really want to stick with just importing json.
Since there is only one item in the list that is data['entries']:
print(data['entries'][0]['SI_ID'])
Prints:
31543
since it is a list of dict, why not
for items in data['entries']:
print(items.get("SI_ID"))

Pull key from json file when values is known (groovy or python)

Is there any way to pull the key from JSON if the only thing I know is the value? (In groovy or python)
An example:
I know the "_number" value and I need a key.
So let's say, known _number is 2 and as an output, I should get dsf34f43f34f34f
{
"id": "8e37ecadf4908f79d58080e6ddbc",
"project": "some_project",
"branch": "master",
"current_revision": "3rtgfgdfg2fdsf",
"revisions": {
"43g5g534534rf34f43f": {
"_number": 3,
"created": "2019-04-16 09:03:07.459000000",
"uploader": {
"_account_id": 4
},
"description": "Rebase"
},
"dsf34f43f34f34f": {
"_number": 2,
"created": "2019-04-02 10:54:14.682000000",
"uploader": {
"_account_id": 2
},
"description": "Rebase"
}
}
}
With Groovy:
def json = new groovy.json.JsonSlurper().parse("x.json" as File)
println(json.revisions.findResult{ it.value._number==2 ? it.key : null })
// => dsf34f43f34f34f
Python 3: (assuming that data is saved in data.json):
import json
with open('data.json') as f:
json_data = json.load(f)
for rev, revdata in json_data['revisions'].items():
if revdata['_number'] == 2:
print(rev)
Prints all revs where _number equals 2.
using dict-comprehension:
print({k for k,v in d['revisions'].items() if v.get('_number') == 2})
OUTPUT:
{'dsf34f43f34f34f'}

update array in mongodb with new item and value

I am trying to update the array: ['media_details'] with a local image path after the image has been downloaded. However using $push just added the local_url on top.
This is what ['media_details'] looks like:
"image_details": [
{
"processed": true,
"position": 0,
"seconds": "46",
"src_url": "https://xxxxx/1.jpg",
"image_fname": "1.jpg",
},
{
"processed": true,
"position": 1,
"seconds": "55",
"src_url": "https://xxxxx/2.jpg",
"image_fname": "2.jpg",
},
my code then downloads the image from the src_url and I want to add the local image url to the ['media_details'].
job = mongo.db.JobProcess
job.update({'_id': db_id},
{'$push': {
'image_details': {
'local_url': img_local_file,
}
}})
This adds the local_url to the top of the ['media_details'] - like so:
{'local_url': '/bin/static/5432ec0f-ea53-4fe1-83e4-f78166d1b9a6/1.jpg'},
{'local_url': '/bin/static/5432ec0f-ea53-4fe1-83e4-f78166d1b9a6/2.jpg'},
{'processed': True, 'position': 0, 'seconds': '46', 'src_url': 'https://xxxxx1.jpg', 'image_fname': '1.jpg'}
what I want it to do is:
"image_details": [
{
"processed": true,
"position": 0,
"seconds": "46",
"src_url": "https://xxxxx/1.jpg",
"image_fname": "1.jpg",
"local_url": "/bin/static/5432ec0f-ea53-4fe1-83e4-f78166d1b9a6/1.jpg"
},
but which command ($set, $push, $addToSet) is best suited for updating this? and how do I implement it?
You need to update the image_details array item using the positional operator $. You will need a query that can uniquely identify the array item, perhaps src_url:
job.update({$and:[
{"_id": db_id},
{"image_details.src_url": img_src_url }
]},
{$set :{"image_details.$.local_url": img_local_file },
{multi:false})
You need to use positional update operator
job.updateOne({
'_id': db_id,
'image_details.src_url': yourUrl,
}, {
$set: {
'image_details.$.local_url': img_local_file
});

Parsing json with python3

Newbie python programmer here, I have the following json response:
[
{
"type": "Incursion",
"state": "mobilizing",
"influence": 1,
"has_boss": true,
"faction_id": 500019,
"constellation_id": 20000739,
"staging_solar_system_id": 30005054,
"infested_solar_systems": [
30005050,
30005051,
30005052,
30005053,
30005054,
30005055
]
},
{
"type": "Incursion",
"state": "established",
"influence": 0,
"has_boss": false,
"faction_id": 500019,
"constellation_id": 20000035,
"staging_solar_system_id": 30000248,
"infested_solar_systems": [
30000244,
30000245,
30000246,
30000247,
30000248,
30000249,
30000250,
30000251,
30000252,
30000253
]
},
{
"type": "Incursion",
"state": "mobilizing",
"influence": 0,
"has_boss": false,
"faction_id": 500019,
"constellation_id": 20000161,
"staging_solar_system_id": 30001101,
"infested_solar_systems": [
30001097,
30001098,
30001099,
30001100,
30001101,
30001102
]
},
{
"type": "Incursion",
"state": "established",
"influence": 0,
"has_boss": false,
"faction_id": 500019,
"constellation_id": 20000647,
"staging_solar_system_id": 30004434,
"infested_solar_systems": [
30004425,
30004426,
30004427,
30004428,
30004429,
30004430,
30004431,
30004432,
30004433,
30004434,
30004435
]
},
{
"type": "Incursion",
"state": "established",
"influence": 0.061500001698732376,
"has_boss": false,
"faction_id": 500019,
"constellation_id": 20000570,
"staging_solar_system_id": 30003910,
"infested_solar_systems": [
30003904,
30003906,
30003908,
30003909,
30003910,
30003903
]
}
]
The original code was written to parse an XML reponse.
This is the code in question:
incursion_constellations = []
if (online):
inc = urllib2.urlopen('https://esi.tech.ccp.is/latest/incursions/')
else:
inc = file(r'incursions.json', 'r')
jinc = json.load(inc)
for j in jinc['items']:
incursion_constellations.append(str(j['constellation']['id_str']))
for s in all_stations:
cur.execute("SELECT constellationID FROM mapSolarSystems WHERE solarSystemID = " + str(s['ssid']))
res = cur.fetchone()
cid = str(res[0])
s['incursion'] = cid in incursion_constellations
The area I have having a hard time understanding is this: for j in jinc['items']:
I am getting this error:
Traceback (most recent call last):
File "./stations.py", line 201, in <module>
for j in jinc['items']:
TypeError: list indices must be integers, not str
Can anyone help me understand how to convert this into being able to parse the json response and retrieve the constellation_id and append it to a list?
Thanks in advance.
Change your original loop to:
for j in jinc:
incursion_constellations.append(str(j['constellation_id']))
But you need to be sure that constellation_id in json is the same id that was under ['constellation']['id_str'] previously
Seeing the [ and ] at the beginning and the end of the response, it seems like this json response is list, not a dict, just as your error is suggesting.
If it is a list, you should be using integer as index, instead of str, like you'd do in dict. Hence, your code should be something like
jinc[0]['constellation_id']
(I don't see where the ['constellation']['id_str'] part comes from)
whatever goes inside the [ and ] is in a list, and should be using an integer index. the ones in { and } are in dict, and should use str index.
to loop through it, just use range and len.
a similar question has been answered here.

Categories

Resources