how to send bson.M data in python - python-3.x

i have an Api function in Golang that receive a json data and good working with postman
but i want te call api with python3 but error in parse body
this is my golang code:
var approve bson.M
err := c.BodyParser(&approve)
and this is my data in patch api :
{
"result" : true
}
and this is my python script:
jsondata = bson.BSON.encode({'result': True})
options = CodecOptions(document_class=collections.OrderedDict)
#decoded_doc = bson.BSON(jsondata).decode(codec_options=options)
decoded_doc = bson.decode(jsondata, codec_options=options)
r = requests.patch(approvurl,data=decoded_doc,headers={'Content-Type':'application/json','Authorization':API_KEY,'Imei':'1234567890','phone':'123456789','email':'test#gmail.com'} )
and my backend in my golang throw this exeption :
expected { character for map value
and i compare json object in wirshark :
this is for postman:
enter image description here
and
this is for my python script
enter image description here
please help me to solve my problem in python script

I think what's happening is that you're passing a Python dict using requests.patch's data parameter, which expects a string. It looks like you want to send JSON, so you should use the json parameter (which adds the application/json Content-Type automatically).
Also, it looks like you're encoding a Python dict to BSON format, only to re-decode it back to a Python dict again. Unless I'm missing something, you shouldn't need to do that.
So your Python script can be changed to a single call to requests.patch:
r = requests.patch(
approvurl,
json={'result': True},
headers={'Authorization': API_KEY, ...},
)

my problem solved by added a new function that check agent :
userAgent := string(c.Context().UserAgent())
//print("userAgent=", userAgent)
if strings.HasPrefix(userAgent, "python-requests") {
eq := c.Body() //("result")
if string(eq) == "result=True" {
print("jsonBody is", string(eq))
id, _ := primitive.ObjectIDFromHex(c.Params("id"))
print("Approving started=", true)
tnx`

Related

How to test for Empty array value in Unirest json Response

I have the following code snipet used in Jira Script Runner cloud
String _userId
def result = get(graph_base_user_url + "?")
.header("Authorization","Bearer " + AuthToken )
.queryString("\$filter","mail eq '$userEmail'")
.asJson()
if (result.getStatus().toString() =="200")
{
**if (result.getBody().value){ // <<<<< is Value is not empty ???
_userId=result.getBody().value[0].id
}**
else
_userId="-1" // user does not exist
}
// user ID not found : error 404
if (result.getStatus().toString()=="404")
_userId="User not found"
This code is returning in the result.getBody() the following output
{"#odata.context":"https://graph.microsoft.com/v1.0/$metadata#users","value":[]}
What I am trying to achieve is to test if the value array of the response is empty or not and if not empty I need to fetch the first element item as value[0].Id, but I could not get it correctly
How can I define my code in BOLD above to perform my correct test ?
Error I get from my code is : " Value is not a property of JsonNode object
Thanks for help
regards
from official doc http://kong.github.io/unirest-java/#responses
String result = Unirest.get("http://some.json.com")
.asJson()
.getBody()
.getObject()
.getJSONObject("car")
.getJSONArray("wheels")
.get(0)
so, something like this should work for you:
def a = result.getBody().getObject().getJSONArray("value")
if(a.length()>0) _userId = a.get(0).get("id")

How do I pass a variable into a payload

So I have an endpoint that I am trying to integrate in Python which accepts a POST request and according to the API documentation, the payload is to be formatted this way:
payload = "{\r\n\"serviceCode\" : \"V-TV\",\r\n\"type\" : \"DSTV\",\r\n\"smartCardNo\" : \"10441003943\"\r\n}\r\n\r\n\r\n\r\n\r\n"
I want the values of type and smartCardNo to be dynamic, i.e I am going to get the values from a form in the frontend and pass it to the backend but I am finding it difficult to do so.
If I format the payload this way(which of course allows ease of passing variable):
{
"serviceCode": "V-TV",
"type": "DSTV",
"smartCardNo" : "10441003943"
}
I get this error:
{'required_fields': ['The service code field is required.'], 'message': 'Service Code is not supplied', 'status': '301'}
Could anyone tell me how I can pass the values for type and smartCardNo dynamically in the fist format(the format specified in the documentation)....any help will be greatly appreciated.
you can simply use the .format()
dict_values = {
"serviceCode": "V-TV",
"type": "DSTV",
"smartCardNo" : "10441003943"
}
payload = """{{"serviceCode":"{serviceCode}","type":"{mytype}","smartCardNo":"{smartCardNo}"}}""".format(
serviceCode = dict_values["serviceCode"],
mytype = dict_values["type"],
smartCardNo = dict_values["smartCardNo"]
)
output:
'{"serviceCode":"V-TV","type":"DSTV","smartCardNo":"10441003943"}'
If you really need the same format as in your payload example, simple use:
payload = "{{\r\n\"serviceCode\" : \"{serviceCode}\",\r\n\"type\" : \"{mytype}\",\r\n\"smartCardNo\" : \"{smartCardNo}\"\r\n}}\r\n\r\n\r\n\r\n\r\n".format(
serviceCode = dict_values["serviceCode"],
mytype = dict_values["type"],
smartCardNo = dict_values["smartCardNo"]
)
and your output will be:
'{\r\n"serviceCode" : "V-TV",\r\n"type" : "DSTV",\r\n"smartCardNo" : "10441003943"\r\n}\r\n\r\n\r\n\r\n\r\n'

How can i simplify checking if a value exist in Json doc

Here is my scenario, i am parsing via javascript a webpage and then post the result to an restApi to store the json in a db. The code works fine as long as all fields i defined in my script are send. Problem is over time they website might change names for fields and that would cause my code to crash.
Originally i used code like this
const mySchool = new mls.School();
mySchool.highSchoolDistrict = data["HIGH SCHOOL DISTRICT"].trim();
mySchool.elementary = data.ELEMENTARY.trim();
mySchool.elementaryOther = data["ELEMENTARY OTHER"].trim();
mySchool.middleJrHigh = data["MIDDLE/JR HIGH"].trim();
mySchool.middleJrHighOther = data["MIDDLE/JR HIGH OTHER"].trim();
mySchool.highSchool = data["HIGH SCHOOL"].trim();
mySchool.highSchoolOther = data["HIGH SCHOOL OTHER"].trim();
newListing.school = mySchool;
but when the element does not exist it complains about that it can not use trim of undefined. So to fix this i came up with this
if (data["PATIO/PORCH"]) {
newExterior.patioPorch = data["PATIO/PORCH"].trim();
}
this works but i am wondering if there is a more global approach then to go and check each field if it is defined ?
You could leverage a sort of helper function to check first if the item is undefined, and if not, return a trim()-ed version of the string.
var data = Array();
data["HIGH SCHOOL DISTRICT"] = " 123 ";
function trimString(inputStr) {
return (inputStr != undefined && typeof inputStr == "string") ? inputStr.trim() : undefined;
}
console.log(trimString(data["HIGH SCHOOL DISTRICT"]));
console.log(trimString(data["ELEMENTARY OTHER"]));

JSON encode in Slim framework

I am having problems sending a JSON encoded array to my view.
So I am doing this in my route
$data['values'] = array('name'=>'John');
$data['values'] = json_encode($data['values']);
return $this->view->render($res, 'githubpresentation.html', $data);
And in my view, in the script tag I do this
var values = "{{values}}" ;
console.log(values);
values = JSON.parse(values);
console.log(values);
The first console.log, before the JSON.parse outputs this:
{"name":"John"}
And when I do the JSON.parse I get an error, of course
Unexpected token & in JSON at position 1
Now I could do some sort of replace of the &quot, but do I really need to? Shouldn't I be able to send a JSON from the server?
This is related to the default escaping strategy. You can fix it by using the js one:
var values = "{{values|e('js')}}" ;
console.log(values);
values = JSON.parse(values);
console.log(values);
Output:
{"name":"John"}
Object {name: "John"}

node.js - Is there any proper way to parse JSON with large numbers? (long, bigint, int64)

When I parse this little piece of JSON:
{ "value" : 9223372036854775807 }
This is what I get:
{ hello: 9223372036854776000 }
Is there any way to parse it properly?
Not with built-in JSON.parse. You'll need to parse it manually and treat values as string (if you want to do arithmetics with them there is bignumber.js) You can use Douglas Crockford JSON.js library as a base for your parser.
EDIT2 ( 7 years after original answer ) - it might soon be possible to solve this using standard JSON api. Have a look at this TC39 proposal to add access to source string to a reviver function - https://github.com/tc39/proposal-json-parse-with-source
EDIT1: I created a package for you :)
var JSONbig = require('json-bigint');
var json = '{ "value" : 9223372036854775807, "v2": 123 }';
console.log('Input:', json);
console.log('');
console.log('node.js bult-in JSON:')
var r = JSON.parse(json);
console.log('JSON.parse(input).value : ', r.value.toString());
console.log('JSON.stringify(JSON.parse(input)):', JSON.stringify(r));
console.log('\n\nbig number JSON:');
var r1 = JSONbig.parse(json);
console.log('JSON.parse(input).value : ', r1.value.toString());
console.log('JSON.stringify(JSON.parse(input)):', JSONbig.stringify(r1));
Output:
Input: { "value" : 9223372036854775807, "v2": 123 }
node.js bult-in JSON:
JSON.parse(input).value : 9223372036854776000
JSON.stringify(JSON.parse(input)): {"value":9223372036854776000,"v2":123}
big number JSON:
JSON.parse(input).value : 9223372036854775807
JSON.stringify(JSON.parse(input)): {"value":9223372036854775807,"v2":123}
After searching something more clean - and finding only libs like jsonbigint, I just wrote my own solution. Is not the best, but it solves my problem. For those that are using Axios you can use it on transformResponse callback (this was my original problem - Axios parses the JSON and all bigInts cames wrong),
const jsonStr = `{"myBigInt":6028792033986383748, "someStr":"hello guys", "someNumber":123}`
const result = JSON.parse(jsonStr, (key, value) => {
if (typeof value === 'number' && !Number.isSafeInteger(value)) {
let strBig = jsonStr.match(new RegExp(`(?:"${key}":)(.*?)(?:,)`))[1] // get the original value using regex expression
return strBig //should be BigInt(strBig) - BigInt function is not working in this snippet
}
return value
})
console.log({
"original": JSON.parse(jsonStr),
"handled": result
})
A regular expression is difficult to get right for all cases.
Here is my attempt, but all I'm giving you is some extra test cases, not the solution. Likely you will want to replace a very specific attribute, and a more generic JSON parser (that handles separating out the properties, but leaves the numeric properties as strings) and then you can wrap that specific long number in quotes before continuing to parse into a javascript object.
let str = '{ "value" : -9223372036854775807, "value1" : "100", "strWNum": "Hi world: 42 is the answer", "arrayOfStrWNum": [":42, again.", "SOIs#1"], "arrayOfNum": [100,100,-9223372036854775807, 100, 42, 0, -1, 0.003] }'
let data = JSON.parse(str.replace(/([:][\s]*)(-?\d{1,90})([\s]*[\r\n,\}])/g, '$1"$2"$3'));
console.log(BigInt(data.value).toString());
console.log(data);
you can use this code for change big numbers to strings and later use BigInt(data.value)
let str = '{ "value" : -9223372036854775807, "value1" : "100" }'
let data = JSON.parse(str.replace(/([^"^\d])(-?\d{1,90})([^"^\d])/g, '$1"$2"$3'));
console.log(BigInt(data.value).toString());
console.log(data);

Resources