Issue with building JSON format. Choose between dict and collections? - python

I'm building json format and the expected is as below:
{
accounts:[ {
"acctnum": "acct1",
"key2":"value2"
"key3": []
"summary" : {
//nested dict
}
}
] //if we have 1 account for given customer
}
If we have more than one account for customer:
{
accounts:[ {
"acctnum": "acct1", // for acct1
"key2":"value2"
"key3": []
"summary" : {
//nested dict
}
},
{
"acctnum": "acct2", //for acct2
"key2":"value3"
"key3": []
"summary" : {
//nested dict
}
}
]
}
After building the dictionary with required attributes for acct1, my code towards end is (and have question if I should be using collections module):
acctlist = []
acctlist = results //results is dict for acct1 (with nested dict)
print(acctlist)
accounts = {}
accounts["accounts"] = acctlist
j = json.dumps(accounts, indent=4)
print(j)
But the actual json format comes out as:
{
accounts: {
"acctnum": "acct1",
"key2":"value2"
"key3": []
"summary1" : {
//nested dict
}
}
}

Your print statement likely answers your question. Is it a list?
acctlist = []
acctlist = results //results is dict for acct1 (with nested dict)
print(acctlist)
I suspect you meant to do acctlist.append(results)

Related

changing JSON value with other JSON in Python

on a nested JSON object, I would like to modify values and adding a JSON Object.
Assume a JSON Object like this:
{
"key1": "value1",
"key2": {
"key2_1": "value2_2 ",
"key2_2": {
"key2_2_1 ": "value2_2_1"
},
"key2_3": "value2_3",
"key2_4": {
"key2_4_1": [{
"key2_4_1_1a": "value2_4_1_1a",
"key2_4_1_2a": "value2_4_1_2a"
}, {
"key2_4_1_1b": "value2_4_1_1b",
"key2_4_1_2b": "value2_4_1_2b"
}]
}
},
"key3": {
"key3_1": "value3_2 ",
"key3_2": {
"key3_2_1 ": "value3_2_1"
},
"key3_3": "value3_3",
"key3_4": {
"key3_4_1": {
"key3_4_1_1": "value3_4_1_1"
}
}
}
}
now the JSON will be recursive iterated to search for a specific value.
The replacement value can be a string
repl = 'MyString'
a dict string
repl = '''{"MyKey": [{"MyKey1": "MyValye1"},{"MyKey2": "MyValye2"}]}'''
or a list
repl = '''[{"MyKey1": "MyValye1"},{"MyKey2": "MyValye2"}]'''
so after I found the key where the replacement to add, I would like to replace the existing value for the given key.
eg for the string:
a[key] = repl
How I can do this for dict or list replacements?
The result could be depending on the replacement variable, the string eg in "key2_1", the dict in "key2_2_1" or the list in "key2_3". The keys where string,dict or list are inserted are examples.
{
"key1": "value1",
"key2": {
"key2_1": "MyString",
"key2_2": {
"key2_2_1 ": {"MyKey": [{"MyKey1": "MyValye1"},{"MyKey2": "MyValye2"}]}
},
"key2_3": [{"MyKey1": "MyValye1"},{"MyKey2": "MyValye2"}],
"key2_4": {
"key2_4_1": [{
"key2_4_1_1a": "value2_4_1_1a",
"key2_4_1_2a": "value2_4_1_2a"
}, {
"key2_4_1_1b": "value2_4_1_1b",
"key2_4_1_2b": "value2_4_1_2b"
}]
}
}
}
i have a search function:
def searchNreplace(data, search_val, replace_val):
if isinstance(data, list):
return [searchNreplace(listd, search_val, replace_val) for listd in data]
if isinstance(data, dict):
return {dictkey: searchNreplace(dictvalue, search_val, replace_val) for dictkey, dictvalue in data.items()}
return replace_val if data == search_val else data
print(searchNreplace(data, "key3", repl))
If you really don't struggle with finding a key, you can use json library to parse your string to object and just assign it as str.
import json
repl = """{"MyKey": [{"MyKey1": "MyValye1"},{"MyKey2": "MyValye2"}]}"""
a[key] = json.loads(repl)
After that you can dump content back to file
with open("my_file", "w+") as f:
json.dump(a, f)

Get item in dictionary inside list from JSON - Python

I need to get the name information, inside the "object" list.
In this example I need this information (10.0.0.19)
"sourceNetworks":{
"objects":[
{
"type":"Host",
"overridable":false,
"id":"005056BF-7C6E-0ed3-0000-012884911113",
"name":"**10.0.0.19**"
}
]
}
I can get any information that is not in the "objects" lists with the command example_json[['metadata']['accessPolicy']['name']
and I get the "mb-test-01" information correctly from the json, but I don't know the syntax to get the items inside the "object" list.
to create this json I use in GET request this way
example_json = requests.get(f"https://{hostname}/api/fmc_config/v1/domain/{uuid}/policy/accesspolicies/{acp_id}/accessrules?expanded=true",headers=header_acp, verify=False).json()
follow the full json.
{
"metadata":{
"ruleIndex":1,
"section":"Mandatory",
"category":"--Undefined--",
"accessPolicy":{
"type":"AccessPolicy",
"name":"mb-test-01",
"id":"005056BF-7C6E-0ed3-0000-012884914323"
},
"timestamp":1635219651530,
"domain":{
"name":"Global",
"id":"e276abec-e0f2-11e3-8169-6d9ed49b625f",
"type":"Domain"
}
},
"links":{
"self":"https://fmcrestapisandbox.cisco.com/api/fmc_config/v1/domain/e276abec-e0f2-11e3-8169-6d9ed49b625f/policy/accesspolicies/005056BF-7C6E-0ed3-0000-012884914323/accessrules/005056BF-7C6E-0ed3-0000-000268434442"
},
"enabled":true,
"action":"ALLOW",
"type":"AccessRule",
"id":"005056BF-7C6E-0ed3-0000-000268434442",
"sourceNetworks":{
"objects":[
{
"type":"Host",
"overridable":false,
"id":"005056BF-7C6E-0ed3-0000-012884911113",
"name":"10.0.0.19"
}
]
},
"destinationNetworks":{
"objects":[
{
"type":"Host",
"overridable":false,
"id":"005056BF-7C6E-0ed3-0000-012884911491",
"name":"192.168.0.39"
}
]
},
"logBegin":false,
"logEnd":false,
"variableSet":{
"name":"Default-Set",
"id":"76fa83ea-c972-11e2-8be8-8e45bb1343c0",
"type":"VariableSet"
},
"logFiles":false,
"enableSyslog":false,
"vlanTags":{
},
"sendEventsToFMC":false,
"name":"rule-1"
}
Presumably you want to retrieve all "name"s under "objects" keys so you could use a recursive function:
def get_name(d):
for k,v in d.items():
if k=='objects':
for i in v:
yield i.get('name')
elif isinstance(v, dict):
yield from get_name(v)
names = list(get_name(data))
Output:
['10.0.0.19', '192.168.0.39']

How do I return an upper field in a JSON with python?

So, I need some help returning an ID having found a certain string. My JSON looks something like this:
{
"id": "id1"
"field1": {
"subfield1": {
"subrield2": {
"subfield3": {
"subfield4": [
"string1",
"string2",
"string3"
]
}
}
}
}
"id": "id2"
"field1": {
"subfield1": {
"subrield2": {
"subfield3": {
"subfield4": [
"string4",
"string5",
"string6"
]
}
}
}
}
}
Now, I need to get the ID from a certain string, for example:
For "string5" I need to return "id2"
For "string2" I need to return "id1"
In order to find these strings I have used objectpath python module like this: json_Tree.execute('$..subfield4'))
After doing an analysis on a huge amount of strings, I need to return the ones that are meeting my criterias. I have the strings that I need (for example "string3"), but now I have to return the IDs.
Thank you!!
Note: I don't have a lot of experience with coding, I just started a few months ago to work on a project in Python and I have been stuck on this for a while
Making some assumptions about the actual structure of the data as being:
[
{
"id": "id1",
"subfield1": {
"subfield2": {
"subfield3": {
"subfield4": [
"string1",
"string2",
"string3"
]
}
}
}
}
// And so on
]
And assuming that each string1, string2 etc. is in only one id, then you can construct this mapping like so:
data: List[dict] # The json parsed as a list of dicts
string_to_id_mapping = {}
for record in data:
for string in record["subfield1"]["subfield2"]["subfield3"]["subfield4"]:
string_to_id_mapping[string] = record["id"]
assert string_to_id_mapping["string3"] == "id1"
If each string can appear in multiple ids then the following will catch all of them:
from collections import defaultdict
data: List[dict] # The json parsed as a list of dicts
string_to_id_mapping = defaultdict(set)
for record in data:
for string in record["subfield1"]["subfield2"]["subfield3"]["subfield4"]:
string_to_id_mapping[string].add(record["id"])
assert string_to_id_mapping["string3"] == {"id1"}

Is it possible to order JSON object of Key Value Pairs when keys change and values are more key value pairs.

In python, I'm having trouble figuring out how to output the JSON object (expressed below) as a string wherein the contents of Baseball are ordered based on "key1" (descending). When I receive the JSON (from the datasources) it's got the players out of order. Ultimately, my code needs to order the players, and then pass it along to the next function ordered. Please assume that I cannot modify the format of the JSON to be/have arrays as the consuming function can't handle that (as it's currently written).
Example JSON:
{
"DataSource1":{
"Baseball":{
"Sean":{
"key1":"10",
},
"Gene":{
"key1":"100",
},
"Alan":{
"key1":"1",
}
}
},
"DataSource2":{
"Baseball":{
"Bob_Smith":{
"key1":"1"
},
"Adam_Filmore":{
"key1":"100"
},
"Joe_Allen":{
"key1":"10"
}
}
}
"DataSource3":{
"Baseball":{
"Jake":{
"key1":"10"
},
"Huck":{
"key1":"1"
},
"Eric":{
"key1":"100"
}
}
}
}
Example of how I would like JSON to output:
{
"DataSource1":{
"Baseball":{
"Alan":{
"key1":"1",
},
"Sean":{
"key1":"10",
},
"Gene":{
"key1":"100",
}
}
},
"DataSource2":{
"Baseball":{
"Bob_Smith":{
"key1":"1"
},
"Joe_Allen":{
"key1":"10"
},
"Adam_Filmore":{
"key1":"100"
}
}
}
"DataSource3":{
"Baseball":{
"Huck":{
"key1":"1"
},
"Jake":{
"key1":"10"
},
"Eric":{
"key1":"100"
}
}
}
}
Use sorted() to establish the sort order you want, then store the results in a collections.OrderedDict.
Try this:
import json
from collections import OrderedDict
with open('data.json') as f:
data = json.load(f)
for data_source in data:
data[data_source]["Baseball"] = OrderedDict(
sorted(data[data_source]["Baseball"].items(),
key=lambda x: x[1]["key1"]))
with open('new_data.json', 'w') as f:
json.dump(data, f, indent=4)

Update Json value in python

I am trying to specify a name for my google spreadsheet api. This is done in the 'title' key value. I have tried with the below but it adds a new key to the existing json. Is there a way to get to the "title": "" and update that value with the new_date item?
prev_date = datetime.date.today()-datetime.timedelta(1)
new_date = str(prev_date.isoformat())
res = {
"requests": [
{
"addSheet": {
"properties": {
"title": ""
}
}
}
]
}
res['title'] = new_date
print (res)
This is the output:
{'requests': [{'addSheet': {'properties': {'title': ''}}}], 'title': '2016-12-29'}
This is what I would like it to be:
{'requests': [{'addSheet': {'properties': {'title': '2016-12-29'}}}]}
From the structure you mentioned, the title key that you need to modify is more nested than what you are providing with.
You need to make the following change:
prev_date = datetime.date.today()-datetime.timedelta(1)
new_date = str(prev_date.isoformat())
res = {
"requests": [
{
"addSheet": {
"properties": {
"title": ""
}
}
}
]
}
res['requests'][0]['addSheet']['properties']['title'] = new_date
print (res)
Where:
'requests' value is a list
0 is the first item in the list (and the only item)
'addSheet' is the key in the dictionary that is the value of the item in the list in the 0 index
'properties' is the key in the above dictionary
'title' is the key in the above dictonary, and the one you need upon your request
You are incorrectly indexing your JSON object and adding a new key named 'title' in the root of the object, while you are trying to update the value inside the array. In your case, you should be accessing res['requests'][0]['addSheet']['properties']['title'] = new_date
I now realize I can pass my variables directly in the json.
prev_date = datetime.date.today()-datetime.timedelta(1)
new_date = str(prev_date.isoformat())
req = {
"requests": [
{
"addSheet": {
"properties": {
"title": new_date
}
}

Categories

Resources