How to replace specific parameter in JSON file with KeyValue in python? - python

In my JSON file how do I replace specific parameter value with key value pair combination?
In the below JSON I want to replace document and code values with by referring dict json sample.
JSON file:
[
{
"_id": "211123",
"_metadata": {
"version": {
"document": "CUS",
"service": "1"
},
"rider": [
{
"code": "01"
}
]
}
},
{
"_id": "211123",
"_metadata": {
"version": {
"document": "POL",
"service": "1"
},
"rider": [
{
"code": "02"
}
]
}
}
]
Referall JSON:
document:
{
"_metadata.version.document.CUS" : "Customer",
"_metadata.version.document.POL" : "Policy"
}
rider:
{
"rider.code.01" : "RIDER01",
"rider.code.02" : "RIDER02"
}
Example:
In the first JSON record, document has CUS value and it should be replaced with Customer.
If code has 01 as value it should be replaced with RIDER01.

Your question is unclear but if I got it right, here is what you are looking for:
import json
json_text = '''
[
{
"_id": "211123",
"_metadata": {
"version": {
"document": "CUS",
"service": "1"
},
"rider": [
{
"code": "01"
}
]
}
},
{
"_id": "211123",
"_metadata": {
"version": {
"document": "POL",
"service": "1"
},
"rider": [
{
"code": "02"
}
]
}
}
]
'''
documents = {
'CUS': 'Customer',
'POL': 'Policy'
}
riders = {
'01': 'RIDER01',
'02': 'RIDER02'
}
json_dict = json.loads(json_text)
for _id in json_dict:
document = _id['_metadata']['version']['document']
if document in documents:
_id['_metadata']['version']['document'] = documents[document]
for i, rider in enumerate(_id['_metadata']['rider']):
code = rider['code']
if code in riders:
rider['code'] = riders[code]
json_text = json.dumps(json_dict)
If your JSON text is in a file called file.json, you can use the following code instead:
import json
from pathlib import Path
documents = {
'CUS': 'Customer',
'POL': 'Policy'
}
riders = {
'01': 'RIDER01',
'02': 'RIDER02'
}
json_file = Path('file.json')
json_dict = json.loads(json_file.read_text())
for _id in json_dict:
document = _id['_metadata']['version']['document']
if document in documents:
_id['_metadata']['version']['document'] = documents[document]
for i, rider in enumerate(_id['_metadata']['rider']):
code = rider['code']
if code in riders:
rider['code'] = riders[code]
json_file.write_text(json.dumps(json_dict, indent=4))
I hope it helps.

This will be helpful
import json
document = {"_metadata.version.document.CUS" : "Customer","_metadata.version.document.POL" : "Policy" }
jsons = {"rider.code.01" : "RIDER01","rider.code.02" : "RIDER02" }
with open('jsonfile.json','r') as f:
json_input = json.load(f)
dlist = [x.split('.') for x in document.keys()]
jlist = [['_metadata']+k for k in [x.split('.') for x in jsons.keys()]]
for js in json_input:
for d in dlist:
if js['_metadata']['version']['document'] == d[-1]:
js['_metadata']['version']['document']= document['.'.join(d)]
break
for j in jlist:
if js['_metadata']['rider'][0]['code'] == j[-1]:
js['_metadata']['rider'][0]['code'] = jsons['.'.join(j[1:])]
break
with open('output_json.json','w') as f:
json.dump(json_input, f)

Related

How to get certain elements using jsonpath + Python?

I have a file named source.json, the content is
{
"msg": "OK",
"result": {
"data": {
"articles": [
{
"idtArticle": "CF00002",
"promotionService": {
"bundleSales": [
{
"code": "201900001"
},
{
"code": "201900002"
}
]
}
},
{
"idtArticle": "CF00003",
"promotionService": {
"bundleSales": [
{
"code": "201900001"
},
{
"code": "201900003"
}
]
}
}
]
}
}
}
I have Python code as following:
import json
import jsonpath
json_source = 'source.json'
with open(json_source, encoding='utf-8') as f:
root = json.loads(f.read())
if __name__ == "__main__":
result = jsonpath.jsonpath(root, """$..articles[?(#.idtArticle == "CF00002")]""")
print(result)
The code works and I can get the article whose idtArticle is CF00002, but how to get the article list whose code(or one of the 2 codes) is 201900001?
Appreciate all the helps!
jsonpath does not support projections so I would do what you want in simple python.
import json
json_source = 'source.json'
with open(json_source, encoding='utf-8') as f:
root = json.loads(f.read())
if __name__ == "__main__":
articles = root['result']['data']['articles']
result = []
for article in articles:
bundleSales = article['promotionService']['bundleSales']
for bundleSale in bundleSales:
if bundleSale['code'] == "201900001":
result.append(article['idtArticle'])
print(result)
You can test it with an extended example:
{
"msg": "OK",
"result": {
"data": {
"articles": [
{
"idtArticle": "CF00002",
"promotionService": {
"bundleSales": [
{
"code": "201900001"
},
{
"code": "201900002"
}
]
}
},
{
"idtArticle": "CF00003",
"promotionService": {
"bundleSales": [
{
"code": "201900001"
},
{
"code": "201900003"
}
]
}
},
{
"idtArticle": "CF00004",
"promotionService": {
"bundleSales": [
{
"code": "201900002"
},
{
"code": "201900003"
}
]
}
}
]
}
}
}
It prints ['CF00002', 'CF00003'].

Accessing nested json objects using python

I am trying to interact with an API and running into issues accessing nested objects. Below is sample json output that I am working with.
{
"results": [
{
"task_id": "22774853-2b2c-49f4-b044-2d053141b635",
"params": {
"type": "host",
"target": "54.243.80.16",
"source": "malware_analysis"
},
"v": "2.0.2",
"status": "success",
"time": 227,
"data": {
"details": {
"as_owner": "Amazon.com, Inc.",
"asn": "14618",
"country": "US",
"detected_urls": [],
"resolutions": [
{
"hostname": "bumbleride.com",
"last_resolved": "2016-09-15 00:00:00"
},
{
"hostname": "chilitechnology.com",
"last_resolved": "2016-09-16 00:00:00"
}
],
"response_code": 1,
"verbose_msg": "IP address in dataset"
},
"match": true
}
}
]
}
The deepest I am able to access is the data portion which returns too much.... ideally I am just trying access as_owner,asn,country,detected_urls,resolutions
When I try to access details / response code ... etc I will get a KeyError. My nested json goes deeper then other Q's mentioned and I have tried that logic.
Below is my current code snippet and any help is appreciated!
import requests
import json
headers = {
'Content-Type': 'application/json',
}
params = (
('wait', 'true'),
)
data = '{"target":{"one":{"type": "ip","target": "54.243.80.16", "sources": ["xxx","xxxxx"]}}}'
r=requests.post('https://fakewebsite:8000/api/services/intel/lookup/jobs', headers=headers, params=params, data=data, auth=('apikey', ''))
parsed_json = json.loads(r.text)
#results = parsed_json["results"]
for item in parsed_json["results"]:
print(item['data'])
You just need to index correctly into the converted JSON. Then you can easily loop over a list of the keys you want to fetch, since they are all in the "details" dictionary.
import json
raw = '''\
{
"results": [
{
"task_id": "22774853-2b2c-49f4-b044-2d053141b635",
"params": {
"type": "host",
"target": "54.243.80.16",
"source": "malware_analysis"
},
"v": "2.0.2",
"status": "success",
"time": 227,
"data": {
"details": {
"as_owner": "Amazon.com, Inc.",
"asn": "14618",
"country": "US",
"detected_urls": [],
"resolutions": [
{
"hostname": "bumbleride.com",
"last_resolved": "2016-09-15 00:00:00"
},
{
"hostname": "chilitechnology.com",
"last_resolved": "2016-09-16 00:00:00"
}
],
"response_code": 1,
"verbose_msg": "IP address in dataset"
},
"match": true
}
}
]
}
'''
parsed_json = json.loads(raw)
wanted = ['as_owner', 'asn', 'country', 'detected_urls', 'resolutions']
for item in parsed_json["results"]:
details = item['data']['details']
for key in wanted:
print(key, ':', json.dumps(details[key], indent=4))
# Put a blank line at the end of the details for each item
print()
output
as_owner : "Amazon.com, Inc."
asn : "14618"
country : "US"
detected_urls : []
resolutions : [
{
"hostname": "bumbleride.com",
"last_resolved": "2016-09-15 00:00:00"
},
{
"hostname": "chilitechnology.com",
"last_resolved": "2016-09-16 00:00:00"
}
]
BTW, when you fetch JSON data using requests there's no need to use json.loads: you can access the converted JSON using the .json method of the returned request object instead of using its .text attribute.
Here's a more robust version of the main loop of the above code. It simply ignores any missing keys. I didn't post this code earlier because the extra if tests make it slightly less efficient, and I didn't know that keys could be missing.
for item in parsed_json["results"]:
if not 'data' in item:
continue
data = item['data']
if not 'details' in data:
continue
details = data['details']
for key in wanted:
if key in details:
print(key, ':', json.dumps(details[key], indent=4))
# Put a blank line at the end of the details for each item
print()

Convert float string to float in json

I have a json(test.json) file with the below data. I have around 10000 records. I need to convert value from string to float write in the new file(test1.json). How can I do do this from Python?
{
"name":"test001",
"cat":"test",
"loc":"x loc",
"ings":[
{
"name":"rrrrrr",
"value":"13.0"
},
{
"name":"hhhh",
"value":"18.0"
}
],
"nums":[
{
"name":"kkkk",
"value":"82.05"
},
{
"name":"uuuuu",
"value":"53.55"
}
]
},
{
"name":"test002",
"cat":"test1",
"loc":"y loc",
"ings":[
{
"name":"trtrtr",
"value":"11.0"
},
{
"name":"wewew",
"value":"19.0"
}
],
"nums":[
{
"name":"iuyt",
"value":"122.05"
},
{
"name":"oiui",
"value":"15.5"
}
]
}
resulting json file(test1.json) should be like below...
{
"name":"test001",
"cat":"test",
"loc":"x loc",
"ings":[
{
"name":"rrrrrr",
"value":13.0
},
{
"name":"hhhh",
"value":18.0
}
],
"nums":[
{
"name":"kkkk",
"value":82.05
},
{
"name":"uuuuu",
"value":53.55
}
]
},
{
"name":"test002",
"cat":"test1",
"loc":"y loc",
"ings":[
{
"name":"trtrtr",
"value":11.0
},
{
"name":"wewew",
"value":19.0
}
],
"nums":[
{
"name":"iuyt",
"value":122.05
},
{
"name":"oiui",
"value":15.5
}
]
}
You can provide an object_hook to the json.loads method which will allow you to modify any object (dicts) found within the json:
import json
json_data = """
[{
"name":"test001",
"cat":"test",
"loc":"x loc",
"ings":[
{
"name":"rrrrrr",
"value":"13.0"
},
{
"name":"hhhh",
"value":"18.0"
}
],
"nums":[
{
"name":"kkkk",
"value":"82.05"
},
{
"name":"uuuuu",
"value":"53.55"
}
]
},
{
"name":"test002",
"cat":"test1",
"loc":"y loc",
"ings":[
{
"name":"trtrtr",
"value":"11.0"
},
{
"name":"wewew",
"value":"19.0"
}
],
"nums":[
{
"name":"iuyt",
"value":"122.05"
},
{
"name":"oiui",
"value":"15.5"
}
]
}]
"""
def as_float(obj):
"""Checks each dict passed to this function if it contains the key "value"
Args:
obj (dict): The object to decode
Returns:
dict: The new dictionary with changes if necessary
"""
if "value" in obj:
obj["value"] = float(obj["value"])
return obj
if __name__ == '__main__':
l = json.loads(json_data, object_hook=as_float)
print (json.dumps(l, indent=4))
This results in what you want:
[
{
"loc": "x loc",
"ings": [
{
"name": "rrrrrr",
"value": 13.0
},
{
"name": "hhhh",
"value": 18.0
}
],
"name": "test001",
"nums": [
{
"name": "kkkk",
"value": 82.05
},
{
"name": "uuuuu",
"value": 53.55
}
],
"cat": "test"
},
{
"loc": "y loc",
"ings": [
{
"name": "trtrtr",
"value": 11.0
},
{
"name": "wewew",
"value": 19.0
}
],
"name": "test002",
"nums": [
{
"name": "iuyt",
"value": 122.05
},
{
"name": "oiui",
"value": 15.5
}
],
"cat": "test1"
}
]
To write to a file instead:
with open("out.json", "w+") as out:
json.dump(l, out, indent=4)
You would need to recursively traverse the data and convert anything that looks like a float to a float:
def fix_floats(data):
if isinstance(data,list):
iterator = enumerate(data)
elif isinstance(data,dict):
iterator = data.items()
else:
raise TypeError("can only traverse list or dict")
for i,value in iterator:
if isinstance(value,(list,dict)):
fix_floats(value)
elif isinstance(value,str):
try:
data[i] = float(value)
except ValueError:
pass
It should do the trick:
my_data = [
{ "name" : "rrrrrr",
"value" : "13.0" },
{ "name" : "hhhh",
"value" : "18.0" },
]
fix_floats(my_data)
>>> my_data
[{'name': 'rrrrrr', 'value': 13.0}, {'name': 'hhhh', 'value': 18.0}]
If you have a single or specific key value object, you can reiterate the value containing alphabetical strings or numerical strings, then map and check against their type with string.isnumeric():
dict = { 'a':'100', 'b':'200', 'c':'300', 'd':'four_hundred', 'e':'500' }
dict_parse = {k: int(v) if v.isnumeric() else v for k, v in dict.items()}
>>> dict_parse
{ 'a': 100, 'b': 200, 'c': 300, 'd':'four_hundred', 'e':500}
when dealing with float numbers amend the if statement to replace decimal point, you can apply same principal to negative numbers:
dict = { 'a':'10.0', 'b':'20.12', 'c':'300.3', 'd':'four_hundred', 'e':'500' }
dict_parse = {k: float(v) if v.replace(".", "").isnumeric() else v for k, v in dict.items()}
>>> dict_parse
{ 'a': 10.0, 'b': 20.12, 'c': 300.3, 'd':'four_hundred', 'e':500}

Unable to store or print json data in exact same format

I am having a json data as :
{
"settings" : {
"number_of_shards" : 1
},
"mappings" : {
"_default_":{
"_timestamp" : {
"enabled" : true,
"store" : true
}
}
}
}
I am able to write a python code to store it , my python looks like:
import json
ES = {}
settings = []
mappings = []
_default_ = []
_timestamp = []
#settings.append({"number_of_shards" : "1"})
#ES["settings"] = settings
m={}
c={}
_timestamp.append({"enabled" : "true", "store" : "true"})
m["_timestamp"]=_timestamp
_default_.append(m)
c["_default_"]=_default_
mappings.append(c)
ES["mappings"] = mappings
settings.append({"number_of_shards" : "1"})
ES["settings"] = settings
print json.dumps(ES,indent=2, separators=(',', ': '))
the above code runs fine but it prints the things as :
{
"mappings": [
{
"_default_": [
{
"_timestamp": [
{
"enabled": "true",
"store": "true"
}
]
}
]
}
],
"settings": [
{
"number_of_shards": "1"
}
]
}
I am a little hazzy on json stuff.. what am i missing ??? Any help would be highly appreciated
You should use dictionaries, not arrays, anyway all you code can be written like this (since ES is just a python object it can be mapped to JSON directly, without any manipulations):
#!/usr/bin/python
import json
ES = {
"settings": {
"number_of_shards" : "1"
},
"mappings": {
"_default_": {
"_timestamp_": {
"enabled" : "true",
"store" : "true"
}
}
}
}
print json.dumps(ES,indent=2, separators=(',', ': '))
If you want to add some keys and values to it:
ES["some_other_key"] = {"some_other_sub_key" : "whatever"}

How to print data into a specific json format in python

How can I print the following data
55550000000
175600000000
55290000000
143100000000
55050000000
Like this in python
{
value: 55550000000
},
{
value: 175600000000
},
{
value: 55290000000
},
{
value: 143100000000
}
My python code is, i guess i am pretty close
def sample():
cpu_sample = cclient.samples.list(meter_name ='cpu', limit = 5)
for each in cpu_sample:
timetamp = each.timestamp
volume = each.counter_volume
volume_int = int(volume)
data1 = json.dumps({'value': volume_int}, sort_keys=True, indent=4, separators=(',',':'))
print data1
this code returns the needed format but without any commas
{
"value":55550000000
}
{
"value":175600000000
}
{
"value":55290000000
}
{
"value":143100000000
}
{
"value":55050000000
}
You can put all values into one list and print it using json.dumps.
In order to avoid [ and ] around the list, you can strip the first and last lines:
import json
data = [55550000000, 175600000000, 55290000000, 143100000000, 55050000000]
print json.dumps([{'value': item} for item in data], indent=0)[2:-2]
Output:
{
"value": 55550000000
},
{
"value": 175600000000
},
{
"value": 55290000000
},
{
"value": 143100000000
},
{
"value": 55050000000
}

Categories