Python REST API call equivalent in Node.js - javascript

I've been recently trying to communicate with the UniProt API. As I am starting with Node.js, I have some initial problems, namely:
I am trying to conver this python request:
import urllib,urllib2
url = 'http://www.uniprot.org/uploadlists/'
params = {
'from':'ACC',
'to':'P_REFSEQ_AC',
'format':'tab',
'query':'P13368 P20806 Q9UM73 P97793 Q17192'
}
data = urllib.urlencode(params)
request = urllib2.Request(url, data)
contact = "" # Please set your email address here to help us debug in case of problems.
request.add_header('User-Agent', 'Python %s' % contact)
response = urllib2.urlopen(request)
page = response.read(200000)
To node.js.
My attempt:
var params = {
'from':'ACC',
'to':'P_REFSEQ_AC',
'format':'json',
'query':'P13368 P20806 Q9UM73 P97793 Q17192'
}
var post_data = querystring.stringify(params);
var url = 'http://www.uniprot.org/uploadlists/'
var options = {
uri: url,
qs: post_data,
method: 'POST'
};
urllib.request(options, function (err, data, res) {
if (err) {
throw err; // you need to handle error
}
console.log(data.toString())
cb("test") // this doesnt currently matter
});
What am I doing wrong? Thank you.

Using node-rest-client can help you achieve what you are trying.
npm i node-rest-client --save
I believe you have a starter project for nodejs which contains package.json.
var Client = require('node-rest-client').Client;
var client = new Client();
var args = {
data: {
'from': 'ACC',
'to': 'P_REFSEQ_AC',
'format': 'json',
'query': 'P13368 P20806 Q9UM73 P97793 Q17192'
},
headers: {
"Content-Type": "application/json"//use the header that you need
}
};
client.post("http://www.uniprot.org/uploadlists/", args, function(data, response) {
// parsed response body as js object
console.log(data);
// raw response
console.log(response);
});

Related

Uploading Image to AWS presigned post URL using axios

I am trying to upload an image to an S3 bucket using a presigned URL generated using boto3 on Python. I have been using the example python code that was provided in the documentation and was successful (the image got correctly uploaded with the correct Content-Type). However, when trying to do this in Javascript for the purposes of our frontend application, I am really struggling to get it to work.
Here's the example dictionary returned by the backend:
{
"fields": {
"AWSAccessKeyId": "AKIAYS3VM3EBIFL7FKE5",
"key": "posts/623255a762fd9bdfbd13f91a",
"policy": "<very long string>",
"signature": "Qvc/sGBHk0uzirzIfR1YmE2kFlo="
},
"url": "https://hotspot-storage.s3.amazonaws.com/"
}
Here is the functioning Python code:
response = <json response object>
object_name = 'playground/example_profile_group.png'
response['fields']['Content-Type'] = "image/png"
# Demonstrate how another Python program can use the presigned URL to upload a file
with open(object_name, 'rb') as f:
files = {'file': (object_name, f)}
http_response = requests.post(response['url'], data=response['fields'], files=files)
# If successful, returns HTTP status code 204
print(http_response)
print(http_response.text)
Here is the non-functioning Javascript code:
const data = response.data;
let payload = data.fields;
payload['Content-Type'] = 'image/jpeg';
const file = {
uri: previewPath,
name: previewPath,
type: 'image/jpeg',
};
payload.file = file;
const url = data.url;
console.log(payload, "MY PAYLOAD")
axios({
method: 'post',
headers: {'Content-Type': 'multipart/form-data'},
url: url,
data: payload,
})
.then(function (response) {
console.log(response.data, 'uploaded');
const data = response.data;
})
.catch(function (error) {
console.log(
'error uploading image',
error.response.data,
);
});
})
.catch(function (error) {
console.log(
'error getting media link',
error.response.data,
);
});
This is the error that keeps getting returned:
error uploading image <?xml version="1.0" encoding="UTF-8"?>
<Error><Code>MalformedPOSTRequest</Code><Message>The body of your POST request is not well-formed multipart/form-data.</Message><RequestId>Q0ES6P4QP75YVVED</RequestId><HostId>eowLxSJQD1xP1EfHPnzGSJzXVGpPjurIMhkdwAD22JMvi9zRoFGg6Bq+mnUt/Lu7DNPY80iBDMc=</HostId></Error>
I have been stuck on this for an absurd amount of time, and cannot tell what I am doing wrong. Any help would be very much appreciated.
In order to send a multipart/form-data request body, you'll need to use a FormData instance instead of a JavaScript object.
For example
const { url, fields } = response.data;
const payload = new FormData();
payload.append("file", file); // this is the file blob, eg from <input type="file">
payload.append("Content-Type", "image/jpeg");
// add all the other fields
Object.entries(fields).forEach(([ key, val ]) => {
payload.append(key, val);
});
// No need to manually set content-type header, your browser knows what to do
const { data: result } = await axios.post(url, payload);
console.log("uploaded", result);

not rendering page on request node.js

I have this front-end function:
var finalSelValue = ""
function changeFunc() {
var selectBox = document.getElementById("selectBox");
var selectedValue = selectBox.options[selectBox.selectedIndex].value;
finalSelValue = selectedValue
fetch('/adminFilter', {
method: 'POST',
headers: {'content-type': 'application/json'},
body: JSON.stringify({
finalSelValue
})
})
}
and then this on the backend:
router.post('/adminFilter', auth.ensureAuthenticated, auth.roleCheck('ADMIN'), (req, res) => {
console.log("filter " + req.body.finalSelValue)
var query = "select * from tkwdottawa where STATUS = '" + req.body.finalSelValue + "'"
ibmdb.open(DBCredentials.getDBCredentials(), function(err, conn) {
if (err) return console.log(err);
conn.query(query, function(err, rows) {
if (err) {
res.writeHead(404);
}
for (var i = 0; i < rows.length; i++) {
console.log(rows[i])
}
res.render('AdminDash', {
page_title: "AdminDash",
data: rows
});
conn.close(function() {
console.log('done adminFilter');
});
});
});
})
it is logging the new values properly, where the loop is, but it is not re-rendering the page with the new data! How do I fix this!
The issue might be because you have not fully configured your nodejs application. You should be aware that the render() method must have a templating engine that handles views to be available. You can just install one of the below templating engine i.e
Pug
EJS
Handlebars
from Npm repository.
Just use npm install [pug or ejs] i suggest this two because they have very easy learning curve
Another solution is to just use send() or sendFile() methods. This will send back the data to the client in this case the fetch request, then you can get the response from the .then callback.
and update the view from front end script.
Just a note
Render method is used with a templating engine and mostly is a server side rendering oriented approach

How can i send receipt data using Swift to Node.js server

I'm currently trying to verify IAP receipts of user subscriptions in iOS. At first i make a post request that gets me the receipt data from the receipt currently stored in Bundle.main.appStoreReceiptURL. I'm able to get use this receipt data in my server to verify the receipt which works pretty well. However this receipt data string is hard coded in Node which is specific to a certain user. How can i be able to send this receipt string to my server for any receipt depending on any user to be verified. Here is both my Swift and server code. Apple says in the documentation
To retrieve the receipt data, use the appStoreReceiptURL method of NSBundle to locate the app’s receipt, and then read the entire file. Send this data to your server—as with all interactions with your server, the details are your responsibility.
I would like to get the receipt data and send it to my server.
func getReceipt() {
if let receiptUrl = receiptUrl {
do {
let purchaseReceipt = try Data(contentsOf: receiptUrl)
self.validatePurchaseReceipt(pReceiptData: purchaseReceipt)
} catch {
let receiptRefreshRequest = SKReceiptRefreshRequest(receiptProperties: nil)
receiptRefreshRequest.delegate = self
receiptRefreshRequest.start()
}
}
}
func validatePurchaseReceipt(pReceiptData: Data) {
let base64encodedReceipt = pReceiptData.base64EncodedString()
let secretKey = "myAppstoreConnectSecretKey"
let requestReceiptDict = ["receipt-data": base64encodedReceipt, "password": secretKey]
guard JSONSerialization.isValidJSONObject(requestReceiptDict) else { return }
do {
let data = try JSONSerialization.data(withJSONObject: requestReceiptDict)
let validationString = "https://sandbox.itunes.apple.com/verifyReceipt"
guard let validationUrl = URL(string: validationString) else { return }
let session = URLSession(configuration: .default)
var request = URLRequest(url: validationUrl, cachePolicy: .reloadIgnoringLocalCacheData)
request.httpMethod = "POST"
let task = session.uploadTask(with:request, from: data) { (data, response, error) in
guard let data = data, error == nil else { return }
do {
let purchaseReceiptJSON = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
print("Success retrieved json:\(purchaseReceiptJSON)")
} catch let error {
print(error)
}
}
task.resume()
} catch let error {
print(error)
}
}
This is my server code
const express = require('express');
const requirePromise = require('request-promise');
const app = express();
let verificationURL = 'https://sandbox.itunes.apple.com/verifyReceipt';
let secretKey = 'myAppstoreConnectSecretKey';
let receiptData = 'MIIntgYJKoZIhvcNAQcCoIInpzCCJ6MCAQExCzAJBgUrDgMCGgUAMIIXVwYJKoZIhvcNAQcBoIIXSASCFetc'
const options = {
url: verificationURL,
method: 'POST',
headers: {
'User-Agent': 'Request-Promise',
'Content-Type': 'application/x-www-form-urlencoded',
},
json: true
};
options.form = JSON.stringify({
'receipt-data': receiptData,
'password': secretKey
});
requirePromise(options).then((resData) => {
console.log(resData);
return resData;
}).catch(function (error) {
console.log(error);
});
If you're going to be using your server to validate receipts (which you should) then the validatePurchaseReceipt method should be calling your server, not the /verifyReceipt endpoint. The receipt data is passed to your server exactly like you do with requestReceiptDict.
Also, the secretKey should be hardcoded on your server - not anywhere on the client.
Here's a similar question: https://stackoverflow.com/a/54261816/3166209

How to retrieve multiple issues on github graphql api (using javascript)?

The goal I want to achieve is to read and later write issues and labels within a github repository using javascript.
So far I have been able to get authenticated and retrieve some data on the repository, but I do not find the way to retrieve data neither on one single, nor on a set of issues.
This is the code I am using.
var request = require("request");
var url = 'https://api.github.com/graphql';
var headers = {
Authorization:'token XXXXXXXXXXXXXXXXXXXXXXXXXXX',
Accept: 'application/json',
'User-Agent': 'request',
'Content-Type': 'application/json'
};
var options = {
method: 'post',
body: undefined,
json: true,
url: url,
headers: headers
};
function makeRequest(options){
request(options, function (error, response, body) {
if (error) {
console.error('error posting json: ', error);
throw error;
}
var responseHeaders = response.headers;
var statusCode = response.statusCode;
console.log('Status code: ', statusCode);
console.log('Body: ', body);
});
};
options.body = {
query: '{repository(owner:"TonyEdelweiss", name:"hello-world") {createdAt name projectsUrl}}'
};
makeRequest(options);
options.body = {
query: '{repository(owner:"TonyEdelweiss", name:"hello-world"){issues(first: 2){edges{cursor node{id}}}}}'
};
makeRequest(options);
On the first makeRequest() I get the following, which is okay:
Status code: 200 Body: { data: { repository:
{ createdAt: '2017-09-29T17:01:25Z',
name: 'hello-world',
projectsUrl: 'https://github.com/TonyEdelweiss/hello-world/projects' } } }
On te second one I only get an '[Object]' )-:
Status code: 200 Body: { data: { repository: { issues: [Object] } }
}
Can anybody give a hint?
Also I have found this in github API v4 documentation: "All GraphQL operations must specify their selections down to fields which return scalar values to ensure an unambiguously shaped response." This might explain why I am not getting the data, but gives no further guidance.
Your request is actually working fine. But the maximum depth you can view using console.log default to 2. You can use util.inspect to change it, set the depth to null to view the full object :
const util = require('util');
.....
console.log('Body: ', util.inspect(body, {depth: null}));

Node.JS Request Module Callback Not Firing

I'm running this code using the request module for node.js
var hsKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
var hsForm = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
var hsHost = "https://docs.google.com/"
var url = hsHost + "forms/d/" + hsForm + "/formResponse"
var form = {
"entry.129401737": pointsAvg,
"entry.2000749128": hiddenNeurons,
"submit": "Submit",
"formkey": hsKey
};
request.post({
url: url,
form: form
}, function (err, res, body) {
console.log("Sent data");
});
I have tried running the above code just using standard Node.JS libraries, to no avail. The callback function is never fired and the request doesn't go through. I don't know why.
I believe I've found the answer to my own problem. The issue seems to be that I'm not allocating any time in the Node.js event loop to allow the request to be executed.
Have a look at this question:
your code should look something like
var hsKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var hsForm = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var hsHost = "https://docs.google.com/"
var url = hsHost + "forms/d/" + hsForm + "/formResponse"
var form = {
"entry.129401737": pointsAvg,
"entry.2000749128": hiddenNeurons,
"submit": "Submit",
"formkey": hsKey
};
request.post({
url: url,
form: form
}, function (response) {
response.setEncoding('utf8');
response.on('data', function(chunk){
//do something with chunk
});
});
The data event should get fired on receiving a response.
So if you read the docs for the request module at npm
request
.get('http://google.com/img.png')
.on('response', function(response) {
console.log(response.statusCode) // 200
console.log(response.headers['content-type']) // 'image/png'
});
There is a response event that should get fired.
I ran into this as well. I ended up creating a separate js file containing only the request, without the describe and it methods, and running it with 'mocha mynewbarebonesreq.js'. suddenly I could see that there was an exception being thrown and swallowed by mocha (with the standard reporter, spec).
I finally installed and enabled mocha_reporter which shows the exceptions
now it looks like this:
describe('CMSLogin', function () {
it('should log in as user ' + JSON.stringify(USER_PASS), function (done) {
request({
url: "http://cms.lund.multiq.com:3000/api/CMSUsers/login",
method: "POST",
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
json: false,
body: JSON.stringify(USER_PASS)
}, (err, res, body) => {
var parsedBody = JSON.parse(body);
this.token = parsedBody.id;
console.log(this.token)
assert.equal(USER_PASS.userId, parsedBody.userId);
assert.doesNotThrow(() => Date.parse(parsedBody.created));
if (err) { done.fail(err); }
done();
});
});
}

Categories

Resources