Trouble moving python requests to node.js requests - javascript

So I currently have the functioning code in python
import requests
import json
address = "*address here*"
viewkey = "*viewkey here*"
headers = {'content-type': 'application/json'}
url = "https://api.mymonero.com:8443/get_address_txs"
data = {"address":address,"view_key":viewkey}
data = json.dumps(data)
response = requests.post(url, data=data, headers=headers)
print(response.text)
And I tried to move to nodejs to integrate it with another program I have written
var request = require('request');
var options = {
url: 'https://api.mymonero.com:8443/get_address_txs',
headers: {'content-type': 'application/json'},
data: JSON.stringify({
address:"address",
viewkey:"viewkey"
})
};
request.post(options,function(error, response, body) {
console.log(body);
})
I assumed the code would be identical but clearly not I get an error from the server with the second segment of code. Please could someone help me migrate this?
Note: I know requests in python has a json attribute I have written it in python this way for clarity.
For the record the response I get from the javascript is:
{
"Error": "Problems parsing JSON"
}
When I get from python:
{
"total_received": "152840132538",
"scanned_height": 2589644,
"scanned_block_height": 1320308,
"start_height": 2586111,
...
}

Do not stringify your msg. That should be it.

In your json, in python the key is view_key, in javascript it's view key.
Also, the request library doesn't have a data key in it's options. You can use body to set the raw body. If you use json, the body will be the son representation of the dict you pass, and the Content-Type header is set for you .

Right I'm an accidental genius I have no idea why my current method wasn't working but the solution I came up with was:
var request = require('request');
var options = {
url: 'https://api.mymonero.com:8443/get_address_txs',
headers: {'content-type': 'application/json'},
json: {
"address":"*address*",
"view_key":"*viewkey*"
}
};
request.post(options,function(error, response, body) {
console.log(body);
})
No idea why it works but hey that's life thank you so much for your suggestions.

Related

Google Apps Script GraphQL API Call

I've been working with the Canvas REST API and ran into some limitations and was directed to their experimental GraphQL API. Given its experimental nature, they have little to no documentation on it. Despite its advantages for what I'm building, I can't find a whole lot on the internet either. As of right now, I can't even get a basic query to work.
function testsendgraphql() {
const url = "https://hsccsd.beta.instructure.com:443/api/graphql";
const payload = `
query {
course(id: 1234) {
{
name
}
}
}`;
const options = {
"method": "POST",
"headers": { "Content-Type": "application/json", "Authorization": "Bearer "+getcanvasaccesstoken() },
"body": payload
};
Logger.log(query);
apiresponse = UrlFetchApp.fetch(url,options);
var head = apiresponse.getAllHeaders();
var data = JSON.parse(apiresponse.getContentText());
Logger.log(data);
Logger.log(head);
}
Running the above gets a response code of 200 but gives the following message:
{errors=[{message=No query string was present}]}
Something with my formatting of the payload seems to be off. Any help would be greatly appreciated.
I recently had success with the following GraphQL query using Google Apps Script:
function test(query) {
var url = "https://gql.waveapps.com/graphql/public";
var options = {"headers": {"Authorization": "Bearer " + getAccessToken(),
"Content-Type": "application/json"
},
"payload": JSON.stringify({query}),
"method": "POST"
}
var response = UrlFetchApp.fetch(url, options);
Logger.log(response);
return;
}
where the query that was passed into the function was formatted as follows:
var query = "query { user { id defaultEmail } }";
You must JSON.stringify your query and post it as payload.
I had a similar error to yours, that there was no query string present. It may be because GraphQL is looking in the URL arguments for the query, not in the HTTP request payload.
For example, get rid of the payload and change your URL to:
var url = encodeURI("https://gql.waveapps.com/graphql/public?query=query{course(id:1234){{name}}}");
Or maybe
var url = encodeURI("https://gql.waveapps.com/graphql/public?query={course(id:1234){{name}}}");
This was brought to my attention by this answer.

Passing multipart form data from python to django server with both file and data

I have a Django server and a react frontend application. I hava an endpoint that receives both data and file object. The javascript version of the api client is working fine and it looks something like this.
const address = `${baseAddress}/${endpoint}`;
const multipartOptions = {
headers: {
'Content-Type': 'multipart/form-data',
'Content-Disposition': `attachment; filename=${filename}`,
'X-CSRFToken': getCSRFToken(),
},
};
const formData = new FormData();
formData.append('file', file);
const json = JSON.stringify(metadata);
const blob = new Blob([json], {
type: 'application/json',
});
formData.append('metadata', blob);
return axios.post(address, formData, multipartOptions);
So as you can see I am using a blob to add metadata to my form data and passing it to the server.
Printing the request.data in the server gives me something like this.
<QueryDict: {'file': [<InMemoryUploadedFile: admin_12183.zip (application/zip)>], 'metadata': [<InMemoryUploadedFile: blob (application/json)>]}>
So I can access both request.data.get('file') and request.data.get('metadata') on my django server.
Now I have to do something similar in python. I tried using requests to get the stuff right, but I don't get two separate keys in the QueryDict. The python code looks like this.
with open("file.zip", "rb") as fp:
with open("metadata.json", "rb") as meta:
file_headers = {
**headers,
'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryjzAXwA7GGcenPlPk',
}
data = {
"file": "",
}
files = {
'file': ("file.zip", fp, "application/zip"),
'metadata': ("blob", meta, "application/json"),
}
response = requests.post(f"{BASE_URL}/api/endpoint", data=data, files=files, headers=file_headers)
print(response.status_code)
If I do not send in both files and data at the same time, I get nothing in request.data. And if I send both of them, I am getting both of the data in a single key, that corresponds to whatever key I have in the data variable.
The server has this code in it
def post(self, request, *args, **kwargs):
file_obj = request.data.get('file')
metadata = request.data.get('metadata')
# both are empty if either one of files or data is not sent from the client
# if both are sent, then request.data has only one key, with everything inside of it
# works fine with the javascript code
I think I am missing something very small and trivial.
Please help.
Turns out I was adding a content-type in my header and that is what was causing all the issues. The working code looks like this
file_headers = {
**headers,
# make sure there is no content type in the header
}
files = {
'file': ("file.zip", shape, "application/zip"),
'metadata': ("blob", meta, "application/json"),
}
response = requests.post(f"{BASE_URL}/api/shapefiles", files=files, headers=file_headers)
print(response.text, response.status_code)

How to read stream responses generated by pm api sendRequest

Trying to run a postman (pm) api call to run a request from the test tab.
Getting back streams in response (logged in console as array containing integers).
Any idea as to how to read these streams.
Request:
pm.sendRequest({
url: myUrl,
method: 'GET',
header: {
'content-type': 'application/json'
}
}, function (err, res) {
console.log(res)
});
Response:
Object:{}
code:200
cookie:[]
header:[]
0:{}
1:{}
2:{}
3:{}
4:{}
5:{}
6:{}
id:"e5d5d6d6"
responseSize:55551
responseTime:263
status:"OK"
stream:{}
data:[]
0:123
1:10
2:32
3:32
4:34
5:115
6:119
7:97
8:103
9:103
10:101
11:114
12:34
13:32
14:58
15:32
16:34
17:50
18:46
19:48
20:34
21:44
22:10
23:32
24:32
25:34
Just use:
res.json()
This gives the response body in json format.
Usage:
pm.sendRequest('url', (err, res) => {console.log(res.json());}
You need to use toJSON() function on the Response object to serialize it to a human-readable format:
function (err, res) {
console.log(res.toJSON())
});
See the pm Sandbox API for further reference.
If response of below request is in XML format,
pm.sendRequest({
url: myUrl,
method: 'GET',
header: {
'content-type': 'application/json'
}
}, function (err, res) {
console.log(res)
});
I am trying to convert response using below code
var jsonObject = xml2Json(res);
It is giving error saying
JSONError | Unexpected token u in JSON at position 0
When I used that same function with testscript, It is converting XML to hsonObject
var jsonObject = xml2Json(responseBody);
This answer didn't work for me as my reply was a HTML page with embedded JS. I had to use pm.response.text() and painstakingly parse out the code I wanted by using .spit('\n') to get an array of lines, etc.

Node JS - Constructing an OAuth2 Request

Im trying to construct an OAuth2 request to the Box API. The example POST request they give as a guideline is a bit ambiguous to me as I am recently learning backend development. The example is as follows:
POST /token
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&
assertion=<JWT>&
client_id=<client_id>&
client_secret=<client_secret>
Official Docs:
https://box-content.readme.io/docs/app-auth
The way I attempted to do this is as follows:
var boxHeaders = {
'Content-Type': 'application/x-www-form-urlencoded'
};
var boxOptions = {
url: 'https://api.box.com/oauth2/token',
method: 'POST',
headers: boxHeaders,
form: {
'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion': boxtoken,
'client_id': 'myclientid',
'client_secret': 'myclientsecret'
}
};
request.post(boxOptions, function(err, response, body) {
console.log(body);
});
I get the following error:
{
"error":"invalid_request",
"error_description":"Invalid grant_type parameter or parameter missing"
}
Obviously the grant type is incorrect but I have no idea how to go about constructing the string based on the Box API example. If anyone can help and even expose me to some good articles or tutorials on how to do this, that would be great!
Thank you.
I just struggled with this myself. I was able to get this to work by moving everything you currently have in boxOptions.form into the request body.
For example:
var boxHeaders = {
'Content-Type': 'application/x-www-form-urlencoded'
};
var boxOptions = {
url: 'https://api.box.com/oauth2/token',
method: 'POST',
headers: boxHeaders
};
var form = {
grant_type:'urn:ietf:params:oauth:grant-type:jwt-bearer',
client_id: 'id',
client_secret: 'secret',
assertion: boxtoken
};
var request = https.request(boxOptions, function(response) {
// do stuff
});
request.write(querystring.stringify(form));
request.end();
Hope this helps. Unfortunately, I'm not familiar enough with the request library to provide an example using it.

malformed JSON string Error while passing JSON from AngularJS

I am trying to pass JSON string in ajax request. This is my code.
NewOrder = JSON.stringify (NewOrder);
alert (NewOrder);
var req = {
url: '/cgi-bin/PlaceOrder.pl',
method: 'POST',
headers: { 'Content-Type': 'application/json'},
data: "mydata="+ NewOrder
};
$http(req)
.success(function (data, status, headers, config) {
alert ('success');
})
.error(function (data, status, headers, config) {
alert (status);
alert (data);
alert ('Error')
});
alert (NewOrder) gives -
{"ItemList":[{"ItemName":"Quality Plus Pure Besan 500 GM","Quantity":1,"MRP":"28.00","SellPrice":"25.00"}],"CustomerID":1,"DeliverySlot":2,"PaymentMode":1}
Which seems to be a valid JSON string.
But in script side I am getting following error. in this line
my $decdata = decode_json($cgi->param('mydata'));
malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "(end of string)")
Can please someone help me why i am getting this error?
$cgi->param('myData') returns the query param string 'mydata', which in your case is not sent.
You're posting the json data in the request body of your http post payload, and not as a query/form param. In that case, you'd need some other function to read the contents of the request body in your server-side script.
which happens to be:
my $data = $query->param('POSTDATA');
as described in here: http://search.cpan.org/~lds/CGI.pm-3.43/CGI.pm#HANDLING_NON-URLENCODED_ARGUMENTS
Also you should remove the "mydata=" from your json in the body you post, because http request payload bodies do not have parameter names (they're for query/form-params only).
Your end code should be like this:
var req = {
url: '/cgi-bin/PlaceOrder.pl',
method: 'POST',
headers: { 'Content-Type': 'application/json'},
data: NewOrder
};
and the servers side:
my $decdata = decode_json($query->param('POSTDATA'));
I think it may be related to this issue: AngularJs $http.post() does not send data
Usually I would post data like this:
var req = {
url: '/cgi-bin/PlaceOrder.pl',
method: 'POST',
headers: { 'Content-Type': 'application/json'},
data: {"mydata" : NewOrder}
};
However I am assuming that you are expecting the data as request params from this:
my $decdata = decode_json($cgi->param('mydata'));
If that is the case then the linked SO question is what you are looking for.
Angular $http.post accepts two params as url and payload
var url = '/cgi-bin/PlaceOrder.pl';
var payLoad = {'myData' :JSON.stringify(NewOrder)};
$http.post(url, payLoad)
.success(function(data) {
console.log(success);
})
At the server side, while fetching the required json string from the request param and then desearlize the json as following:
$result = $cgi->param('myData');
my $decdata = decode_json($result);

Categories

Resources