API POST request in Julia - json

I am trying to convert some Python code to Julia. Here is the Python code:
url = "http://api.scb.se/OV0104/v1/doris/sv/ssd/START/BE/BE0101/BE0101G/BefUtvKon1749"
json = {
"query": [
{
"code": "Kon",
"selection": {
"filter": "item",
"values": [
"1",
"2"
]
}
},
{
"code": "ContentsCode",
"selection": {
"filter": "item",
"values": [
"000000LV"
]
}
}
],
"response": {
"format": "px"
}
}
r = requests.post(url=url, json=json)
Below is the Julia code, that is not working, with this error message:
syntax: { } vector syntax is discontinued around path:8
top-level scope at population_data.jl:8
using DataFrames, DataFramesMeta, HTTP, JSON3
url = "http://api.scb.se/OV0104/v1/doris/sv/ssd/START/BE/BE0101/BE0101G/BefUtvKon1749"
json = {
"query": [
{
"code": "Kon",
"selection": {
"filter": "item",
"values": [
"1",
"2",
"1+2"
]
}
},
{
"code": "ContentsCode",
"selection": {
"filter": "item",
"values": [
"000000LV"
]
}
}
],
"response": {
"format": "px"
}
}
r = HTTP.post(url, json)
My attempts to solve this are the following:
Convert the json variable to a string using """ around it.
Converting the JSON string to Julia data types, using JSON3.read()
Passing the converted JSON string to the POST request. This gives the following error:
IOError(Base.IOError("read: connection reset by peer (ECONNRESET)", -54) during request(http://api.scb.se/OV0104/v1/doris/sv/ssd/START/BE/BE0101/BE0101G/BefUtvKon1749)
None of it works, and I am not even sure that it is about the JSON format. It could be that I am passing the wrong parameters to the POST request. What should I do?

One way of solving this consists in building the parameters as native julia data structures, and use JSON to convert and use them as the body of your PUT request:
Dictionaries in julia are built using a syntax like Dict(key => value). Arrays are built using a standard syntax: [a, b, c]. The julia native data structure equivalent to your parameters would look like this:
params = Dict(
"query" => [
Dict("code" => "Kon",
"selection" => Dict(
"filter" => "item",
"values" => [
"1",
"2",
"1+2"
]),
),
Dict("code"=> "ContentsCode",
"selection" => Dict(
"filter" => "item",
"values" => [
"000000LV"
]),
),
],
"response" => Dict(
"format" => "px"
))
Then, you can use JSON.json() to build the JSON representation of it as a string and pass it to the HTTP request:
using HTTP
using JSON
url = "http://api.scb.se/OV0104/v1/doris/sv/ssd/START/BE/BE0101/BE0101G/BefUtvKon1749"
# send the request
r = HTTP.request("POST", url,
["Content-Type" => "application/json"],
JSON.json(params))
# retrieve the response body as a string
b = String(r.body)

Related

Looping through groovy object(List) using each{it} and pass the the elements into a json payload in Jenkins

I have a list containing the name of workspaces in groovy Jenkinsfile. I wrote an each() loop to iterate through the list and use the names in the endpoint below to get the workspace ID from the api response.
def getWorkspaceId() {
def result = []
Listworkspace.each{
def response = httpRequest(
customHeaders: [
[ name: "Authorization", value: "Bearer " + env.BEARER_TOKEN ],
[ name: "Content-Type", value: "application/vnd.api+json" ]
],
url: "https://app.terraform.io/api/v2/organizations/${TF_ORGNAME}/workspaces/$it
)
def data = new JsonSlurper().parseText(response.content)
println ("Workspace Id: " + data.data.id)
result << data.data.id
}
return result
}
After getting the IDs, I want to pass them as part of a json payload.
def buildPayload() {
def workspaceID = new JsonSlurper().parseText(getWorkspaceId())
workspaceID.each{
def payload = """
{
"data": {
"attributes": {
"is-destroy":false,
"message":
},
"type":"runs",
"relationships": {
"workspace": {
"data": [
{"id": "$it", "type": "workspaces"}
]
}
}
}
}
}
"""
return payload
}
Is there a way I can iterate through the list of IDs returned and append each json object for the key "data" after iteration. See the code below
"relationships": {
"workspace": {
"data": [
{"id": "id1", "type": "workspaces"},
{"id": "id2", "type": "workspaces"},
{"id": "id3", "type": "workspaces"}
]
When making the api call, it throws a 400 Bad request error. I tried to print the payload and I found out it attaches the whole list of IDs to the payload.
Any suggestion will be greatly appreciated. Thank you.
def buildPayload() {
def workspaceID = new JsonSlurper().parseText(getWorkspaceId())
workspaceID.each{
def payload = """
{
"data": {
"attributes": {
"is-destroy":false,
"message":
},
"type":"runs",
"relationships": {
"workspace": {
"data": [
[id1, id2, id3]
]
}
}
}
}
}
"""
return payload
}
I'd recommend using the JsonOutput class to make your life easier. In essence, as long as your getWorkspaceId() method is returning a list of ids, you can do something like this:
import groovy.json.JsonOutput
def buildPayload(def ids) {
def payload = [
data: [
attributes: [
"is-destroy": false,
"message" : "",
],
type: "runs",
relationships: [
workspace: [
data: ids.collect {
return [id: it, type: "workspaces"]
}
]
]
]
]
return JsonOutput.toJson(payload)
}
This will take each id in your ids list and build a map where each id is identified by its number and the type: workspaces key pair. This is all then included in the larger payload.

Json Extractor in JMeter

I am using JSON extractor in JMeter. Below is my Response Body. I am using the Json path expression to capture the value, which is working fine.
Apart from the above condition, I need to add one more condition.
If the "travelID" length is equal to 33, then only I need to get the BoundID.
Example : AAA-AB1234-AAABBB-2022-11-10-1111
Total length or count of the above travelID is 33, but sometime I used to get 31,32 also but I need to capture the Bound ID only when the length is 33. Is that feasible ? Please help on the same
PFB sample response body.
{
"data": {
"RenewalDetails": [
{
"ExpiryDetails": {
"duration": "xxxxx",
"destination": "XXX",
"from": "XXX",
"value": 2,
"segments": [
{
"valudeid": "xxx-xx6262-xxxyyy-1111-11-11-1111"
}
]
},
"Itemdetails": [
{
"BoundId": "xxx-1-xxx1-111111111111-1",
"isexpired": true,
"FamilyCode": "PREMIUM",
"availabilityDetails": [
{
"travelID": "AAA-AB1234-AAABBB-2022-11-10-1111",
"quota": "X",
"scale": "XXX",
"class": "X"
}
]
}
]
}
]
},
"warnings": [
{
"code": "xxxx",
"detail": "xxxxxxxx",
"title": "xxxxxxxx"
}
]
}
I don't think it's possible with JSON Extractor, I would rather suggest going for JSR223 PostProcessor and the following Groovy code:
def BoundId = new groovy.json.JsonSlurper().parse(prev.getResponseData())
.data.RenewalDetails[0].Itemdetails.find { itemDetail ->
itemDetail.availabilityDetails[0].travelID.length() == 33
}?.BoundId
vars.put('BoundId', BoundId ?: 'Not Found')
You will be able to refer extracted value as ${BoundId} later on where required.

JSON/Kotlin - handling JSON objects and arrays

First of all, I'm very new to JSON concept so sorry if my question is silly or very simple to answer.
I want to use Oxford Dictionary API for simple app which I'm writing in Kotlin, here is the response from API as JSON:
{
"metadata": {
"provider": "Oxford University Press"
},
"results": [
{
"id": "hello",
"language": "en",
"lexicalEntries": [
{
"entries": [
{
"etymologies": [
"early 19th century: variant of earlier hollo; related to holla"
],
"homographNumber": "000",
"senses": [
{
"definitions": [
"used as a greeting or to begin a telephone conversation"
],
"examples": [
{
"text": "hello there, Katie!"
}
],
"id": "m_en_gbus0460730.012",
"short_definitions": [
"used as greeting"
],
"subsenses": [
{
"definitions": [
"used to express surprise"
],
"examples": [
{
"text": "hello, what's all this then?"
}
],
"id": "m_en_gbus0460730.017",
"regions": [
"British"
],
"short_definitions": [
"used to express surprise"
]
},
{
"definitions": [
"used as a cry to attract someone's attention"
],
"examples": [
{
"text": "‘Hello below!’ he cried"
}
],
"id": "m_en_gbus0460730.018",
"short_definitions": [
"used attract attention"
]
},
{
"definitions": [
"used informally to express sarcasm or anger"
],
"examples": [
{
"text": "Hello! Did you even get what the play was about?"
}
],
"id": "m_en_gbus0460730.019",
"short_definitions": [
"used informally to express sarcasm or anger"
]
}
]
And now, I would like to extract only "definitions" from this JSON object but as you can see it is nested within other JSON arrays, my code so far looks like this:
var resultJSON = JSONObject(result)
var JSON_results = resultJSON.getJSONArray("results")
var JSON_lexical = JSON_results.getJSONObject(0).getJSONArray("lexicalEntries")
var JSON_entries = JSON_lexical.getJSONObject(0).getJSONArray("entries")
var JSON_senses = JSON_entries.getJSONObject(0).getJSONArray("senses")
var JSON_definitions = JSON_senses.getJSONObject(0).getJSONArray("definitions")
Log.i("JSON", JSON_definitions.getString(0))
I know that there needs to be a better way of doing this but I can't find how.
Kotlin actually makes it easier to map such responses with something called "data classes". So you can simply paste the JSON response in an online JSON to Kotlin Data Class Generator e.g. https://json2kotlin.com
It churns out .kt files like this:
data class Json4Kotlin_Base (
val metadata : Metadata,
val results : List<Results>
)
and thn you can simply pass on the response JSON to the Data class mapping like this:
val json = getJson() // your json value here
val topic = Gson().fromJson(json, Json4Kotlin_Base::class.java)
In case you're looking for GSON annotations in the generated models, chose the option when you generate those.
Here's a video tutorial for step by step process about it.
https://www.youtube.com/watch?v=n46WbgNoEnE
Try as follow
val justDefinitions = mutableListOf<String>()
JSON_senses.forEach {
val definitions = it.getJSONArray("definitions")
for (i in 0 until definitions.length()) { {
justDefinitions.add(it.getString(i))
}
}

JsonPath with Newtonsoft.JSON

I tried for nearly an hour different approaches, but I don't get it ;(
my JSON object is this:
"typeOfHair": {
"value": [
{
"code": "Dry Hair",
"values": [
{
"value": "DryHair",
"language": "en"
},
{
"value": "TrockenesHaar",
"language": "de"
}
]
},
{
"code": "Any Type of Hair",
"values": [
{
"value": "AnyTypeOfHair",
"language": "en"
},
{
"value": "JedenHaartyp",
"language": "de"
}
]
}
]
}
And my task is to get with Newtonsoft.JSON all values where the language is "de".
My current approach is:
JsonObject.SelectTokens("typeOfHair.value.values[?(#.language == 'de')].value").ToList()
Can someone help me with this?
Kind regards
You're very close. You need to account for the outer value array typeOfHair.value[] by using the JsonPATH wildcard operator [*]:
var values = JsonObject.SelectTokens("typeOfHair.value[*].values[?(#.language == 'de')].value")
// Convert from JValue to string
.Select(v => (string)v)
// Save in a list
.ToList();
And, the result is:
["TrockenesHaar","JedenHaartyp"]
Sample fiddle.
I know the OP specified JSONPath explicitly but for the sake of completeness below is how to achieve the same with LINQ to JSON:
var values = jObject["typeOfHair"]["value"]
.SelectMany(v => v["values"])
.Where(v => (string)v["language"] == "de")
.Select(v => (string)v["value"])
.ToList();
Demo: https://dotnetfiddle.net/1S4sT4

Get _id from MongoDB using Scala

For a given JSON how do I get the _id to use it as an id for inserting in another JSON?
Tried to get the ID as shown below but does not return correct results.
private def getModelRunId(): List[String] = {
val resultsCursor: List[DBObject] =
modelRunResultsCollection.find(MongoDBObject.empty, MongoDBObject(FIELD_ID -> 1)).toList
println("resultsCursor >>>>>>>>>>>>>>>>>> " + resultsCursor)
resultsCursor.map(x => (Json.parse(x.toString()) \ FIELD_ID).asOpt[String]).flatten
}
{
"_id": ObjectId("5269723bd516ec3a69f3639e"),
"modelRunId": ObjectId("5269723ad516ec3a69f3639d"),
"results": [
{
"ClaimId": "526971f5b5b8b9148404623a",
"pricingResult": {
"TxId": 0,
"ClaimId": "Large_Batch_1",
"Errors": [
],
"Disposition": [
{
"GroupId": 1,
"PriceAmt": 20,
"Status": "Priced Successfully",
"ReasonCode": 0,
"Reason": "RmbModel(PAM_DC_1):ProgramNode(Validation CPG):ServiceGroupNode(Medical Services):RmbTerm(RT)",
"PricingMethodologyId": 2,
"Lines": [
{
"Id": 1
}
]
}
]
}
},
If you want to find objectId's:
import com.mongodb.casbah.Imports._
collection.find(MongoDBObject(/*query*/)).map(_._id)
If you want to query by id:
collection.findOneByID(/*id*/)
I suppose you are using Casbah, the official Driver for Scala.
You just need to modify the map function :
resultsCursor.map { x => x.as[org.bson.types.ObjectId](FIELD_ID)}
Casbah does the deserialization from BSON to Scala object, so you don't have to do it yourself !