Comparing Json data. Python 3 - json

I have the following Json file and I need to compare data to see how many times each value repeat itself. The problem is, I have no idea about handling Json. I don't want the answer to my exercise, I want to know how to access the data. Json:
{
"tickets": [
{
"ticket_id": 0,
"timestamp": "2016/05/26 04:47:02",
"file_hash": "c9d4e03c5632416f",
"src_ip": "6.19.128.119",
"dst_ip": "145.231.76.44"
},
{
"ticket_id": 1,
"timestamp": "2017/05/28 16:14:22",
"file_hash": "ce8a056490a3fd3c",
"src_ip": "100.139.125.30",
"dst_ip": "145.231.76.44"
},
{
"ticket_id": 2,
"timestamp": "2015/08/23 03:27:10",
"file_hash": "d17f572496f48a11",
"src_ip": "67.153.41.75",
"dst_ip": "239.168.56.243"
},
{
"ticket_id": 3,
"timestamp": "2016/02/26 14:01:33",
"file_hash": "3b28f2abc966a386",
"src_ip": "6.19.128.119",
"dst_ip": "137.164.166.84"
},
]
}

If this is a string representation of the object, first you need to set a variable and parse the string to have object you can work with.
jsonString = "{...your json string...}"
Then parse the string,
import json
jsonObject = json.loads(jsonString)
To access the data within it's like any other js object. Example :
jsonObject.tickets[0].timestamp
would return "2016/05/26 04:47:02"
tickets is the key within the jsonObject, 0 is the index of the first object in the list of tickets.

You can use the built-in "json" library to parse your file into an object:
import json
f = open('myfile.json','r')
tickets = json.loads(f.read())
This will return a "tickets" object. How you "compare" (or what exactly you compare) is up to you.

Related

Using only the values of JSON data that is unmarshalled

I'm looking to take a list of ids and add them to a slice. However if I don't custom unmarshall the data, I cannot get to the values of the ids and it is just an array of JSON objects. And if I do custom unmarshall the data I want, I am told that I cannot append that slice-like array of data because it has a custom type from the structs I used to unmarshall.
I would prefer to only make the request once to get both the "data" and "meta" information from a rest API, I then unmarshall that data into the following:
{Data:[{Ids:39647} {Ids:39648} {Ids:39649} {Ids:39650} {Ids:39651} {Ids:39652} {Ids:39653} {Ids:39654} {Ids:39655} {Ids:39656} {Ids:39657} {Ids:39658} {Ids:39659} {Ids:39660} {Ids:39661} {Ids:39662} {Ids:39663} {Ids:39664} {Ids:39665} {Ids:39666} {Ids:39667} {Ids:39668} {Ids:39669} {Ids:39670} {Ids:39671} {Ids:39672} {Ids:39673}] Meta:{Metadata:{CurrentPage:3 TotalPages:656}}}
I would like to get the Ids in a slice like so:
[39647 39649 39650 ...]
Preferably without having to marshall and then unmarshall again, but beggars can't be choosers. This would then need to be of slice type []int so that I can append it to another slice and use all standard library slice things with it.
Edit: It was requested I add the basic JSON Structure to the question.
"data": [
{
"id": 38926
},
{
"id": 38927
},
//... and so on.
],
"meta": {
"pagination": {
"total": 163795,
"current_page": 3,
"total_pages": 81898
}
}
}
If you just want to get a straight slice of int-"id",without unmarshalling the whole JSON, you could use a JSON parser library to do that, ex-https://github.com/tidwall/gjson.
package main
import "github.com/tidwall/gjson"
json := `{
"data":[
{
"id":38926
},
{
"id":38927
}
],
"meta":{
"pagination":{
"total":163795,
"current_page":3,
"total_pages":81898
}
}
}`
func main() {
value := gjson.Get(json, "data.#.id")
println(value.Array()) // etc
}

Gatling JSON Feeder Unique POST Bodies

I have a JSON file that contains a JSON Array
test.json
[
{ "Name": "Bob" },
{ "Age": "37" },
{ "DOB": "12/01/1985"}
]
I would like to test each respective element in the JSON array against an endpoint to observe the performance of the system against unique payloads
currently I have
testService.scala
val payload = jsonFile("test.json").circular
val httpProtocol = http
.baseURL("http://test.com")
.headers(Map("Content-Type" -> "application/json"))
val scn = scenario("Test Service")
.feed(payload)
.exec(http("test_request")
.post("/v1/test")
.queryParam("key", "123")
.body()
I am not able to pass each respective child from the payload in the .body() as a JSON
The Gatling Docs say that the JSON Feeder loads the each element of the Array into a record collection
https://gatling.io/docs/2.3/session/feeder/
i.e:
record1: Map("id" -> 19434, "foo" -> 1)
record2: Map("id" -> 19435, "foo" -> 2)
and set the body to .body(StringBody("""[{"id": ${id}}]"""))
The issue is I have different keys (Name,Age,DOB) and I'd like each one to be a different request sent.
.body(StringBody("""[{"KEY_NAME_HERE": ${KEY_NAME_HERE}}]"""))
How do I achieve this?
This is how i am doing:-
company_users.json.json
[
{
"env":"dev",
"userName": "a#test.com",
"password": "Qwerty!12345678"
},
{
"env":"sit",
"userName": "b#test.com",
"password": "Qwerty!12345678"
},
{
"env":"uat",
"userName": "c#test.com",
"password": "Qwerty!12345678"
},
{
"env":"prod",
"userName": "d#test.com",
"password": "Qwerty!12345678"
}
]
Working Code Snippet:
val jsonFileFeederCompany = jsonFile("data/company_users.json").circular
val get_company_user_token = http("Get Company Tokens")
.post(gwt_token_url)
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.body(StringBody(
"""{
"env": "${env}",
"userName": "${userName}",
"password": "${password}"
}"""
)).asJson
.check(status.is(200))
.check(jsonPath("$.jwtToken").saveAs("jwtToken"))
val getCompanyUsersGwtToken = scenario("Create Company GWT token Scenario")
.feed(GetTokenRequest.jsonFileFeederCompany)
.exec(GetTokenRequest.get_company_user_token).exitHereIfFailed
This will read each array[position] from json and replace the values in request, to fetch security tokens from different env.
Hope this helps.
Regards,
Vikram Pathania
In your case JSONs from that array are loaded one by one, and since each first level key from that JSON will be saved as session attribute then users in your simulation end up with just 1 of 3 attributes depending which JSON was used. This way you can't (or to be precise can't easily) build body string. In that simple case it would be better to have JSONs with same fields, so you can rely on them when building request payload. Fe. you can place payload key and value in separate fields:
[
{
"key":"Name",
"value":"Bob"
},
{
"key":"Age",
"value":"37"
},
{
"key":"DOB",
"value":"12/01/1985"
},
]
This way for each user in simulation you will have two attributes key and value so you will be able to construct payload like:
.body(StringBody("""{"${key}": "${value}"}"""))
Of course this will work only in that simple case you described and with string-only values in JSONs. If your final goal is to make something more complex please provide real-life example.

Process a list of map to get a value of a key in the map

I have a list of map (parsed from json output of a rest request) like
[[Mobile:9876543210, Name:ABCD], [Mobile:8765432109, Name:EFGH], [Mobile:7654321098, Name:IJKL], [Mobile:6543210987, Name:MNOP]]
Original JSON was like
{
"data": [{
"Name": "ABCD",
"Mobile": "9876543210"
},
{
"Name": "EFGH",
"Mobile": "8765432109"
},
{
"Name": "IJKL",
"Mobile": "7654321098"
},
{
"Name": "MNOP",
"Mobile": "6543210987"
}
]
}
I want to get the mobile value from the name
Tried some things but just not working out.
Trying this in JMETER JSR223 post processor using Groovy.
You should be able to get the Mobile based on Name.
Below code fetches the Mobile 8765432109 when Name is EFGH from the OP's data. Similarly you can change the value of Name to get the right Mibile.
//Pass jsonString value to below parseText method
def json = new groovy.json.JsonSlurper().parseText(jsonString)
def result = json.data.find { it.Name == 'EFGH' }.Mobile
println result
You can quickly try online Demo
Here is an example Groovy code to fetch Name:Mobile pairs from the original JSON response (use the code in the JSR223 PostProcessor)
def json = new groovy.json.JsonSlurper().parse(prev.getResponseData())
json.data.each {entry ->
entry.each {k, v -> log.info("${k}:${v}")}
}
Demo:
References:
Groovy: Parsing and producing JSON
Groovy Is the New Black

How to add "data" and "paging" section on JSON marshalling

I know i can customize the JSON response registering JSON marshallers to Domain entities, even i can create profiles with names for different responses.
This is done filling an array that later will be marshalled like:
JSON.registerObjectMarshaller(myDomain) {
def returnArray = [:]
returnArray['id'] = it.id
returnArray['name'] = it.name
returnArray['price'] = it.price
return returnArray
}
What i want is to alter the way it gets marshalled to have two sections like
{
"paging": {
"total": 100
},
"data": [
{
"id": 1,
"description": "description 1",
}
},
...
]
}
I assume i have to implemetn a custom JSON Marshaller but i don't know how to use it for a specific response instead of wide application.
EDIT: I assume i'll need a custom RENDERER apart from the marshaller. Is this one that i don't know how to use for specific response.
What about a simple:
def json = new JSON([ paging: [ total: myArray.totalCount ], data: myArray ])
Your domain objects will be converted with the marshaller you have set up while your paging data will simply be transformed into JSON.

Can someone provide me an example on how to convert this data format to JSON?

How do i convert json text file to..
var nested_obj = { pic: "jaedongImage", name: "ananth", team: "evil geniuses", server: "NA" };
My text file as below..
{
"data": [
{
"pic": "jaedongImage,"
"name": "ananth",
"team": "evil geniuses",
"server": "N/A"
}
]
}
It's unclear what you're asking, but: The JSON depicts an object with one property, data, which refers to an array. The array has one entry, which is the object you wanted. From your initial code sample, it looks like you're using JavaScript, so: Assuming you're receiving text (a string) in JSON format, you would parse it using JSON.parse, and then get at that object via data[0]:
var obj = JSON.parse(text);
var pic = obj.data[0];