I have an API whose response is json like this:
{
"a":1,
"b":2,
"c":[
{
"d":4,
"e":5,
"f":{
"g":6
}
}
]
}
How can I write a python program which will give me the keys ['d','e','g']. What I tried is:
jsonData = request.json() #request is having all the response which i got from api
c = jsonData['c']
for i in c.keys():
key = key + str(i)
print(key)
Function which return only keys which aren't containing dictionary as their value.
jsonData = {
"a": 1,
"b": 2,
"c": [{
"d": 4,
"e": 5,
"f": {
"g": 6
}
}]
}
def get_simple_keys(data):
result = []
for key in data.keys():
if type(data[key]) != dict:
result.append(key)
else:
result += get_simple_keys(data[key])
return result
print get_simple_keys(jsonData['c'][0])
To avoid using recursion change line result += get_simple_keys(data[key])to result += data[key].keys()
Try this,
dct = {
"a":1,
"b":2,
"c":[
{
"d":4,
"e":5,
"f":{
"g":6
}
}
]
}
k=dct["c"][0]
for key in k.keys():
print key
Related
I am trying to write a piece of code where it filters out the values RSI, MOM, MOM_RSI within the Json file and filters by Status. I want to keep the values that has a Status of ACTIVE and get rid of the one that have a status of PAUSED. I have a working code for it from the issue:link. But I want to make it cleaner but attempting to configure the filters within the filtered_data dictionary but its not working. How would I be able to fix it?
Working:
def reading():
with open('data.json') as f:
data = json.load(f)
result = {}
for filter_key in data.keys():
for d in data[filter_key]:
if d['Status'] == 'ACTIVE':
try:
result[filter_key].append(d)
except KeyError:
result[filter_key] = [d]
Not Working Code:
def reading():
with open('data.json') as f:
data = json.load(f)
required_names = {key for filter_key in data.keys() for key in data[filter_key]}
filtered_data = {
key: value
for key, value in data.keys()
if key['Status'] in required_names
}
return data
reading()
Expected Output:
{
"RSI": [
{
"TradingPair": "BTCUSD",
"Status": "ACTIVE",
}
],
"MOM_RSI":[
{
"TradingPair": "BTCUSDT",
"Status": "ACTIVE",
}
]
}
JSON File:
{
"RSI": [
{
"TradingPair": "BTCUSD",
"Status": "ACTIVE",
}
],
"MOM":[
{
"TradingPair": "BCHUSDT",
"Status": "PAUSED",
}
],
"MOM_RSI":[
{
"TradingPair": "BTCUSDT",
"Status": "ACTIVE",
}
]
}
Using inline loops to filter should do the trick for you
for key in data.keys():
data[key] = [x for x in data[key] if x['Status'] == 'ACTIVE']
# in case of empty data, remove the key
data = {k: v for k, v in data.items() if v != []}
{
"Product": [{
"a": "e3ae148d8bc2c5fe366c38da"
},
{
"b": "d211c6e7ed5bd8b4e9316a74085"
},
{
"c": "74be4f1b3b0fa5af77287780"
},
{
"d": "89856f4f139a84c98fb98b8b39c32e2"
},
{
"e": "7bd784e7d3b8490ed614345989a5"
},
{
"f": "d169f6a4a932841b12bdf8ccded57"
}
]
}
Use JsonSlurper,
File file = new File('abc')
String fileContent = file.text
def slurper = new groovy.json.JsonSlurper()
def result = slurper.parseText(fileContent)
println result.Product[0].a //etc.
...
Here is my sample json data:
{
"id": "67362003",
"a": {
"b": {
"3": 2,
"43": 30,
"c": "jack",
"d": "trail",
"e": [
{
"f": {
"g": "Father",
"h": "Mother"
}
}
],
"p": [
{
"q": {
"r": "Aunt",
"s": "Uncle"
}
}
]
}
}
}
Wrote a method, objpath which will get the each input from user-config: like [root:id, root:a:b:e[0]] and returns each path as ['id] at first call.. and for second call.. it returns ['a']['b']['e'][0] which I can able to read and print in my code of wrapper.
I am able to print print (obj['a']['b']['e'][0]) this manner.. In that, objpath method will return '['a']['b']['e'][0]' part as string. So, here how can I convert it to obj['a']['b']['e'][0] format.. It may be simple, I tried multiple ways.. But somehow it's breaking with type of string/list/dict... Below is my python-wrapper to do same
file_json = 'config_lib/sample.json'
lf = open(file_json, 'r')
obj = json.loads(lf.read())
skeys = ["root:id", "root:a:b:e[0]"]
for skey in skeys:
returns = JsonParser(obj, skey)
# Its returning string.
print type(returns) # <type 'str'>
print (returns) # *['id']* at first itereation, *['a']['b']['e'][0]* at second iteration
print (obj[returns]) # how to print the obj value here ??? I am not getting
I need to print obj['a']['b']['e'][0] and obj['id']
Can anyone please suggest a solution.
By converting the string to json-object resolved the issue..
print ("Returned value is:", eval('obj' + returns))
Please help with parse CSV to JSON from 2 CSV Files in groovy
For example :
CSV1:
testKey,status
Name001,PASS
Name002,PASS
Name003,FAIL
CSV2:
Kt,Pd
PT-01,Name001
PT-02,Name002
PT-03,Name003
PT-04,Name004
I want to input in "testlist" data from CSV2.val[1..-1],CSV1.val[1..-1]
Result should be like :
{
"testExecutionKey": "DEMO-303",
"info": {
"user": "admin"
},
"tests": [
{
"TestKey": "PT-01",
"status": "PASS"
},
{
"TestKey": "PT-02",
"status": "PASS"
},
{
"TestKey": "PT-03",
"status": "FAIL"
}
]
code without this modification (from only 1 csv):
import groovy.json.*
def kindaFile = '''
TestKey;Finished;user;status
Name001;PASS;
Name002;PASS;
'''.trim()
def keys
def testList = []
//parse CSV
kindaFile.splitEachLine( /;/ ){ parts ->
if( !keys )
keys = parts
else{
def test = [:]
parts.eachWithIndex{ val, ix -> test[ keys[ ix ] ] = val }
testList << test
}
}
def builder = new JsonBuilder()
def root = builder {
testExecutionKey 'DEMO-303'
info user: 'admin'
tests testList
}
println JsonOutput.prettyPrint(JsonOutput.toJson(root))
Your sample JSON doesn't match the CSV definition. It looks lile you're using fields [1..-1] from CSV 1, as you stated, but fields [0..-2] from CSV 2. As you only have 2 fields in each CSV that's the equivalent of csv1[1] and csv2[0]. The example below uses [0..-2]. Note that if you always have exactly two fields in your input files then the following code could be simplified a little. I've given a more generic solution that can cope with more fields.
Load both CSV files into lists
File csv1 = new File( 'one.csv')
File csv2 = new File( 'two.csv')
def lines1 = csv1.readLines()
def lines2 = csv2.readLines()
assert lines1.size() <= lines2.size()
Note the assert. That's there as I noticed you have 4 tests in CSV2 but only 3 in CSV1. To allow the code to work with your sample data, it iterates through through CSV1 and adds the matching data from CSV2.
Get the field names
fieldSep = /,[ ]*/
def fieldNames1 = lines1[0].split( fieldSep )
def fieldNames2 = lines1[0].split( fieldSep )
Build the testList collection
def testList = []
lines1[1..-1].eachWithIndex { csv1Line, lineNo ->
def mappedLine = [:]
def fieldsCsv1 = csv1Line.split( fieldSep )
fieldsCsv1[1..-1].eachWithIndex { value, fldNo ->
String name = fieldNames1[ fldNo + 1 ]
mappedLine[ name ] = value
}
def fieldsCsv2 = lines2[lineNo + 1].split( fieldSep )
fieldsCsv2[0..-2].eachWithIndex { value, fldNo ->
String name = fieldNames2[ fldNo ]
mappedLine[ name ] = value
}
testList << mappedLine
}
Parsing
You can now parse the list of maps with your existing code. I've made a change to the way the JSON string is displayed though.
def builder = new JsonBuilder()
def root = builder {
testExecutionKey 'DEMO-303'
info user: 'admin'
tests testList
}
println builder.toPrettyString()
JSON Output
Running the above code, using your CSV1 and CSV 2 data, gives the JSON that you desire.
for CSV1:
testKey,status
Name001,PASS
Name002,PASS
Name003,FAIL
and CSV2:
Kt,Pd
PT-01,Name007
PT-02,Name001
PT-03,Name003
PT-05,Name002
PT-06,Name004
PT-07,Name006
result is:
{
"testExecutionKey": "DEMO-303",
"info": {
"user": "admin"
},
"tests": [
{
"status": "PASS",
"testKey": "PT-01"
},
{
"status": "PASS",
"testKey": "PT-02"
},
{
"status": "FAIL",
"testKey": "PT-03"
}
]
}
but I need exactly the same values for testKey (testKey from CSV1=Kt from CSV2)
{
"testExecutionKey": "DEMO-303",
"info": {
"user": "admin"
},
"tests": [
{
"testKey": "PT-02",
"status": "PASS"
},
{
"testKey": "PT-05",
"status": "PASS"
},
{
"testKey": "PT-03",
"status": "FAIL"
}
]
}
My end goal is to parse thru an unknown .json file stored on my laptop and get the key names (not the values only key names) using Groovy in SoapUI.
I want to parse an unknown JSON file stored in my computer and get its keys (name of the keys, not the values). I can do 2 things separately:
I am able to read the local JSON using the following code I found online:
def JSON_URL = "file:///C:/Users/xxx/example.json"
URL url = new URL(JSON_URL)
InputStream urlStream = null
try {
urlStream = url.openStream()
BufferedReader reader = new BufferedReader(new Inpu tStreamReader(urlStream))
JsonSlurper js1 = new JsonSlurper()
Object result = js1.parse(reader)
log.info "==> readJSONfile2 result of read: "+result
} catch (Exception e) {
log.info e
}
And if I have the URL, I am able to parse it and get keys like so:
// getting the response
def resp1 = context.expand('${testStepName#response}')
// parsing the set context
def js1 = new JsonSlurper().parseText(resp1)
def keys = js1.entrySet() as List
log.info "==> runTreatmentPlan keys list is: "+keys
log.info "==> runTreatmentPlan keys size is: "+keys.size()
But I am unable to get the keys if the JSON is local to my machine ie unable to combine both the codes. I get error when I do:
Object result = js1.parseText(reader)
I am new to groovy and SoapUI and json - a total newbie and this is my first question. I am really scared because I have seen that some people are kinda rough towards other newbies if the question is basic. I promise, I did google a lot, and I am sure the experienced people might find my question stupid as well, but I am really stuck. I am unable to combine both pieces of code. I kinda feel that I will some how have to use the response from #1 code, but I don't know how.
Can someone help me please?
==== Updating with the JSON structure:
{
"Key0": [
{
"Key1": "Value1",
"Key2": "Value2",
"Key3": "Value3",
"Key4": {
"subKey1": "subValue1"
},
"Key5": {
"subKey1": "subValue1",
"subKey2": "subValue2",
"subKey3": "subValue3",
"subKey4": "subValue4"
},
"Key6": "2016-07-11T17:52:59.000Z",
"Key7": [
{
"subKey1": "subValue1",
"subKey2": "subValue2"
},
{
"subKey1": "subValue1",
"subKey2": "subValue2"
},
{
"subKey1": "subValue1",
"subKey2": "subValue2"
},
{
"subKey1": "subValue1",
"subKey2": "subValue2"
}
]
},
{
"Key1": "Value1",
"Key2": "Value2",
"Key3": "Value3",
"Key4": {
"subKey1": "subValue1"
},
"Key5": {
"subKey1": "subValue1",
"subKey2": "subValue2",
"subKey3": "subValue3",
"subKey4": "subValue4"
},
"Key6": "2016-07-11T17:52:59.000Z",
"Key7": [
{
"subKey1": "subValue1",
"subKey2": "subValue2"
},
{
"subKey1": "subValue1",
"subKey2": "subValue2"
},
{
"subKey1": "subValue1",
"subKey2": "subValue2"
},
{
"subKey1": "subValue1",
"subKey2": "subValue2"
}
]
}
]
}
Given your input, this code:
import groovy.json.JsonSlurper
def traverse
traverse = { tree, keys = [], prefix = '' ->
switch (tree) {
case Map:
tree.each { k, v ->
def name = prefix ? "${prefix}.${k}" : k
keys << name
traverse(v, keys, name)
}
return keys
case Collection:
tree.eachWithIndex { e, i -> traverse(e, keys, "${prefix}[$i]") }
return keys
default :
return keys
}
}
def content = new JsonSlurper().parse( new File( 'sample.json' ) )
traverse(content).each { println it }
Yields this output:
Key0
Key0[0].Key1
Key0[0].Key2
Key0[0].Key3
Key0[0].Key4
Key0[0].Key4.subKey1
Key0[0].Key5
Key0[0].Key5.subKey1
Key0[0].Key5.subKey2
Key0[0].Key5.subKey3
Key0[0].Key5.subKey4
Key0[0].Key6
Key0[0].Key7
Key0[0].Key7[0].subKey1
Key0[0].Key7[0].subKey2
Key0[0].Key7[1].subKey1
Key0[0].Key7[1].subKey2
Key0[0].Key7[2].subKey1
Key0[0].Key7[2].subKey2
Key0[0].Key7[3].subKey1
Key0[0].Key7[3].subKey2
Key0[1].Key1
Key0[1].Key2
Key0[1].Key3
Key0[1].Key4
Key0[1].Key4.subKey1
Key0[1].Key5
Key0[1].Key5.subKey1
Key0[1].Key5.subKey2
Key0[1].Key5.subKey3
Key0[1].Key5.subKey4
Key0[1].Key6
Key0[1].Key7
Key0[1].Key7[0].subKey1
Key0[1].Key7[0].subKey2
Key0[1].Key7[1].subKey1
Key0[1].Key7[1].subKey2
Key0[1].Key7[2].subKey1
Key0[1].Key7[2].subKey2
Key0[1].Key7[3].subKey1
Key0[1].Key7[3].subKey2
import groovy.json.JsonSlurper
/**
* sample.json present in C:/tools/
* { "foo": "bar", "baz": 123 }
*/
def content = new JsonSlurper().parse( new File( 'C:/tools/sample.json' ) )
assert content.keySet() == ['baz', 'foo'] as Set
UPDATE:
After looking at the actual json structure and the issues with the version of Groovy in SOAPUI, below would be a viable option to get all the keys in a specific format:
import groovy.json.JsonSlurper
def textFromFile = new File('/path/to/example.json').text
def content = new JsonSlurper().parseText(textFromFile)
def getAllKeys(Map item) {
item.collect { k, v ->
v instanceof Map ? convertToString(v).collect { "${k}.$it" } : k
}.flatten()
}
assert getAllKeys(content) == [
'Key1', 'Key2', 'Key3',
'Key4.subKey1', 'Key5.subKey1', 'Key5.subKey2',
'Key5.subKey3', 'Key5.subKey4',
'Key6', 'Key7'
]