i got empty value when print json key in lua code - json

this is the json response plus "\x00" in the end from server :
{
"STATUS": [{
"STATUS":"S",
"When":1470180059,
"Code":11,
"Msg":"Summary",
"Description":"nsgminer 0.9.2"
}],"SUMMARY": [{
"Elapsed":2061,
"MHS av":0.00,
"Found Blocks":0,
"Getworks":76,
"Accepted":0,
"Rejected":0,
"Hardware Errors":0,
"Utility":0.00,
"Discarded":209,
"Stale":0,
"Get Failures":3,
"Local Work":293,
"Remote Failures":0,
"Network Blocks":14,
"Total MH":0.0000,
"Work Utility":0.00,
"Difficulty Accepted":0.00000000,
"Difficulty Rejected":0.00000000,
"Difficulty Stale":0.00000000,
"Best Share":0
}],
"id":1
}\x00
i want to use the json in lua code :
local output = stdnse.output_table()
local json_string = tostring(result:sub(1, -2))
local pos, value = json.parse(json_string)
output["Description"] = value["STATUS"][0]["Description"]
return output
when i print it out, i got null value

i solve that with covert json to string and convert string into json table
local pos, value = json.parse(tostring(json_string))
output["Description"] = value["STATUS"][1]["Description"]

Related

How do I deserlize a cypress JSON request

I am trying to assert on the response body. However, I get the following response:
{\r\n "physicalID": "Physical file updated",\r\n "fileData": null,\r\n }
I would like to deserialize it and assert on a JSON object
This is not a question related to Cypress itself, the response you are getting is not a valid JSON string so you are unable to parse the response and assert on it. The only thing i could assist with is how to parse this particular string, you can however get a totally different string as a response from another endpoint. for now, considering this was the string you needed to parse to assert on :
// Remove \r\n
let x = '{\r\n "physicalID": "Physical file updated",\r\n "fileData": null,\r\n }'
x= x.replace(/[\r\n]+/g, ""); // "{ "physicalID": "Physical file updated", "fileData": null, }"
//Remove the last ','
x = x.slice(0,x.lastIndexOf(',')) + x.slice(x.lastIndexOf(',')+1) //"{ "physicalID": "Physical file updated", "fileData": null }"
// Now parse it
x = JSON.parse(x);

Python dictionary converts single slash to double slash

I am trying to send data using requests trying to send the payload from my side which requires date to be formatted like "\/Date(1532010600000)\/"
I am trying to make a custom payload which is to be sent using requests:
payload = {
"GW_MeetingID": "1231324654654",
"AltID": "This is ALT ID",
"MeetingSubject": company,
"MeetingComment": "",
"RoomID": "xxxxx",
"TimeZoneId": "Dateline Standard Time",
"Organizer": organiser,
"Start": "\\/Date(1532010600000)\\/"
}
here the key should be "\/Date(1532010600000)\/" rather than "\\", using extra "\" as escape character. When i am trying to print this payload, it is showing value of start keys with "\\" which the api I am trying to send response to, doesn't accept. It only accepts 'Start' key as "\/Date(1532010600000)\/"
The solution that I have tried are using .encode('utf-8') and then decoding it using .decode('unicode_escape'). But still the dictionary had same response with "\\"
How can I make this payload to contain "\" in Start key?
import json
import requests
payload = {
"GW_MeetingID": "1231324654654",
"AltID": "This is ALT ID",
"MeetingSubject": company,
"MeetingComment": "",
"RoomID": "e3e63148-5e4f-426e-98de-dec1687c9930",
"TimeZoneId": "Dateline Standard Time",
"Organizer": organiser,
"Start": "\\/Date(1532010600000)\\/"
}
print (payload)
# print (json.dumps(payload))
# a = (ast.literal_eval(payload))
headers = {'Content-Type': 'application/json'}
r = requests.post(url, data=json.dumps(payload), headers=headers)
print (r.text)

Emit Python embedded object as native JSON in YAML document

I'm importing webservice tests from Excel and serialising them as YAML.
But taking advantage of YAML being a superset of JSON I'd like the request part of the test to be valid JSON, i.e. to have delimeters, quotes and commas.
This will allow us to cut and paste requests between the automated test suite and manual test tools (e.g. Postman.)
So here's how I'd like a test to look (simplified):
- properties:
METHOD: GET
TYPE: ADDRESS
Request URL: /addresses
testCaseId: TC2
request:
{
"unitTypeCode": "",
"unitNumber": "15",
"levelTypeCode": "L",
"roadNumber1": "810",
"roadName": "HAY",
"roadTypeCode": "ST",
"localityName": "PERTH",
"postcode": "6000",
"stateTerritoryCode": "WA"
}
In Python, my request object has a dict attribute called fields which is the part of the object to be serialised as JSON. This is what I tried:
import yaml
def request_presenter(dumper, request):
json_string = json.dumps(request.fields, indent=8)
return dumper.represent_str(json_string)
yaml.add_representer(Request, request_presenter)
test = Test(...including embedded request object)
serialised_test = yaml.dump(test)
I'm getting:
- properties:
METHOD: GET
TYPE: ADDRESS
Request URL: /addresses
testCaseId: TC2
request: "{
\"unitTypeCode\": \"\",\n
\"unitNumber\": \"15\",\n
\"levelTypeCode": \"L\",\n
\"roadNumber1\": \"810\",\n
\"roadName\": \"HAY\",\n
\"roadTypeCode\": \"ST\",\n
\"localityName\": \"PERTH\",\n
\"postcode\": \"6000\",\n
\"stateTerritoryCode\": \"WA\"\n
}"
...only worse because it's all on one line and has white space all over the place.
I tried using the | style for literal multi-line strings which helps with the line breaks and escaped quotes (it's more involved but this answer was helpful.) However, escaped or multiline, the result is still a string that will need to be parsed separately.
How can I stop PyYaml analysing the JSON block as a string and make it just accept a block of text as part of the emitted YAML? I'm guessing it's something to do with overriding the emitter but I could use some help. If possible I'd like to avoid post-processing the serialised test to achieve this.
Ok, so this was the solution I came up with. Generate the YAML with a placemarker ahead of time. The placemarker marks the place where the JSON should be inserted, and also defines the root-level indentation of the JSON block.
import os
import itertools
import json
def insert_json_in_yaml(pre_insert_yaml, key, obj_to_serialise):
marker = '%s: null' % key
marker_line = line_of_first_occurrence(pre_insert_yaml, marker)
marker_indent = string_indent(marker_line)
serialised = json.dumps(obj_to_serialise, indent=marker_indent + 4)
key_with_json = '%s: %s' % (key, serialised)
serialised_with_json = pre_insert_yaml.replace(marker, key_with_json)
return serialised_with_json
def line_of_first_occurrence(basestring, substring):
"""
return line number of first occurrence of substring
"""
lineno = lineno_of_first_occurrence(basestring, substring)
return basestring.split(os.linesep)[lineno]
def string_indent(s):
"""
return indentation of a string (no of spaces before a nonspace)
"""
spaces = ''.join(itertools.takewhile(lambda c: c == ' ', s))
return len(spaces)
def lineno_of_first_occurrence(basestring, substring):
"""
return line number of first occurrence of substring
"""
return basestring[:basestring.index(substring)].count(os.linesep)
embedded_object = {
"unitTypeCode": "",
"unitNumber": "15",
"levelTypeCode": "L",
"roadNumber1": "810",
"roadName": "HAY",
"roadTypeCode": "ST",
"localityName": "PERTH",
"postcode": "6000",
"stateTerritoryCode": "WA"
}
yaml_string = """
---
- properties:
METHOD: GET
TYPE: ADDRESS
Request URL: /addresses
testCaseId: TC2
request: null
after_request: another value
"""
>>> print(insert_json_in_yaml(yaml_string, 'request', embedded_object))
- properties:
METHOD: GET
TYPE: ADDRESS
Request URL: /addresses
testCaseId: TC2
request: {
"unitTypeCode": "",
"unitNumber": "15",
"levelTypeCode": "L",
"roadNumber1": "810",
"roadName": "HAY",
"roadTypeCode": "ST",
"localityName": "PERTH",
"postcode": "6000",
"stateTerritoryCode": "WA"
}
after_request: another value

Can JSON String format be converted to Actual format using groovy?

I have the following JSON String format getting from external source:-
What kind of format is this actually?
{
id=102,
brand=Disha,
book=[{
slr=EFTR,
description=Grammer,
data=TYR,
rate=true,
numberOfPages=345,
maxAllowed=12,
currentPage=345
},
{
slr=EFRE,
description=English,
data=TYR,
rate=true,
numberOfPages=345,
maxAllowed=12,
currentPage=345
}]
}
I want to convert this into actual JSON format like this: -
{
"id": "102",
"brand": "Disha",
"book": [{
"slr": "EFTR",
"description": "Grammer",
"data": "TYR",
"rate": true,
"numberOfPages": 345,
"maxAllowed": "12",
"currentPage": 345
},
{
"slr": "EFRE",
"description": "English",
"data": "TYR",
"rate": true,
"numberOfPages": 345,
"maxAllowed": "12",
"currentPage": 345
}]
}
Is this achievable using groovy command or code?
Couple of things:
You do not need Groovy Script test step which is currently there as step3
For step2, Add a 'Script Assertion` with given below script
Provide step name for nextStepName in the script below for which you want to add the request.
//Provide the test step name where you want to add the request
def nextStepName = 'step4'
def setRequestToStep = { stepName, requestContent ->
context.testCase.testSteps[stepName]?.httpRequest.requestContent = requestContent
}
//Check the response
assert context.response, 'Response is empty or null'
setRequestToStep(nextStepName, context.response)
EDIT: Based on the discussion with OP on the chat, OP want to update existing request of step4 for a key and its value as step2's response.
Using samples to demonstrate the change input and desired outputs.
Let us say, step2's response is:
{
"world": "test1"
}
And step4's existing request is :
{
"key" : "value",
"key2" : "value2"
}
Now, OP wants to update value of key with first response in ste4's request, and desired is :
{
"key": {
"world": "test1"
},
"key2": "value2"
}
Here is the updated script, use it in Script Assertion for step 2:
//Change the key name if required; the step2 response is updated for this key of step4
def keyName = 'key'
//Change the name of test step to expected to be updated with new request
def nextStepName = 'step4'
//Check response
assert context.response, 'Response is null or empty'
def getJson = { str ->
new groovy.json.JsonSlurper().parseText(str)
}
def getStringRequest = { json ->
new groovy.json.JsonBuilder(json).toPrettyString()
}
def setRequestToStep = { stepName, requestContent, key ->
def currentRequest = context.testCase.testSteps[stepName]?.httpRequest.requestContent
log.info "Existing request of step ${stepName} is ${currentRequest}"
def currentReqJson = getJson(currentRequest)
currentReqJson."$key" = getJson(requestContent)
context.testCase.testSteps[stepName]?.httpRequest.requestContent = getStringRequest(currentReqJson)
log.info "Updated request of step ${stepName} is ${getStringRequest(currentReqJson)}"
}
setRequestToStep(nextStepName, context.request, keyName)
We can convert the invalid JSON format to valid JSON format using this line of code:-
def validJSONString = JsonOutput.toJson(invalidJSONString).toString()

Python3 json output values to file line by line only if other fields are greater than value

I have retrieved remote json using urllib.request in python3 and would like to to dump, line by line, the value of the IP addresses only (ie. ip:127.0.0.1 would be 127.0.0.1, next line is next IP) if it matches certain criteria. Other key values include a score (one integer value per category) and category (one or more string values possible).
I want to check if the score is higher than, say 10, AND the category number equals a list of one OR more values. If it fits the params, I just need those IP addresses added line by line to a text file.
Here is how I retrieve the json:
ip_fetch = urllib.request.urlopen('https://testonly.com/ip.json').read().decode('utf8')
I have the json module loaded, but don't know where to go from here.
Example of json data I'm working with, more than one category:
"127.0.0.1" : {
"Test" : "10",
"Prod" : "20"
},
I wrote a simple example that should show you how to iterate trough json objects and how to write to a file:
import json
j = json.loads(test)
threshold = 10
validCategories = ["Test"]
f=open("test.txt",'w')
for ip, categories in j.items():
addToList = False
for category, rank in categories.items():
if category in validCategories and int(rank) >= threshold:
addToList = True
if addToList:
f.write("{}\n".format(ip))
f.close()
I hope that helps you to get started. For testing I used the following json-string:
test = """
{
"127.0.0.1" : {
"Test" : "10",
"Prod" : "20"
},
"127.0.0.2" : {
"Test" : "5",
"Prod" : "20"
},
"127.0.0.3" : {
"Test" : "5",
"Prod" : "5",
"Test2": "20"
}
}
"""