Convert NodeJS HTTP post script to Python - python

I'm trying to call this Node.JS script (which is a unit test) to Python equivalent. It basically generates an AWS token, and uses that to send a .json file as HTTP post request. How can I re-write it in Python? I already did the token generation part.
Here is the NodeJS script:
describe('Send config file', () => {
let token = '';
before(function beforetest(done) {
this.timeout(10000);
tokengen(cognitoUser, authenticationDetails).then((result) => {
token = result.getAccessToken().getJwtToken();
done();
}, (err) => {
done(err);
});
});
it('should send config json', function test(done) {
this.timeout(10000);
chai.request(app)
.post(`${route}/sendjson`).set('accesstoken', token)
.send(vcamconfig)
.end((err, res) => {
expect(res).to.have.status(200);
expect(res.body).to.be.an('object');
expect(res.body).to.have.property('msg');
expect(res.body.msg).to.equal('Uploaded to S3');
console.log(res.body);
done();
});
});
});
And here is the python script I attempted so far to generate an AWS token. I need to use the token to send a file as a POST request.
from warrant.aws_srp import AWSSRP
import boto3
username = "user3"
password = "user3"
client_id = "myclientID1234567890"
user_pool_id = "us-east-1_sdhjsasls"
region = "us-east-1"
client = boto3.client('cognito-idp', region_name=region)
aws = AWSSRP(username=username, password=password, pool_id=user_pool_id, client_id=client_id, client=client)
tokens = aws.authenticate_user()
print(tokens)

Related

Is there a way to call a Cloud Function through Cloud Task using form-data?

I have a Cloud Function(Python - Flask) that is expecting to receive a form-data with two files, it works well when I request it directly, but using Cloud Task it's not reaching in there. Here is what I get: ImmutableMultiDict([])
ps: Using Python for the Cloud Function and Node.JS for the Cloud Task.
Tried to Google, and searched over here and have no answers, even the docs don't say anything about it. Any tips?
that's the code that I'm using to call Cloud Task:
const auth = new GoogleAuth({})
const client = new CloudTasksClient({ credentials: credentials });
const formData = new FormData();
formData.append('pdf_file', 'x');
const task = {
httpRequest: {
httpMethod: 'POST',
url,
body: formData,
headers: {
"Content-Type": "multipart/form-data"
},
oidcToken: {
serviceAccountEmail: "x#appspot.gserviceaccount.com"
}
}
}
const request = { parent: parent, task: task, auth: auth }
const [ response ] = await client.createTask(request);
console.log(response);
console.log(`created task ${response.name}`);
that's the code for my Cloud Function, that I'm using as a test:
import functions_framework
#functions_framework.http
def main(request):
if request.method != 'POST':
print('ERROR: its not a post request')
return {'error': 'Invalid method'}, 400
print(request.form)
return 'ok'

How to fetch data analyzed in python to node.js and pass it to angular?

I am new to angular and i want to display JSON data from python to angular with the help of node.js and I used child process to connect python and node.js but I dont know how to pass it to angular service
node.js file
const express = require('express')
const { spawn } = require('child_process')
const app = express()
const port = 8000
app.get('/', (req, res) => {
let dataToSend
let largeDataSet = []
// spawn new child process to call the python script
const python = spawn('python', ['test.py'])
// collect data from script
python.stdout.on('data', function (data) {
console.log('Pipe data from python script ...')
//dataToSend = data;
largeDataSet.push(data)
})
// in close event we are sure that stream is from child process is closed
python.on('close', (code) => {
console.log(`child process close all stdio with code ${code}`)
// send data to browser
res.send(largeDataSet.join(''))
})
})
app.listen(port, () => {
console.log(`App listening on port ${port}!`)
})
Technically you just have to send a Http GET request from your service.
I suggest that you should read and follow this offical http client guide to set it up correctly.
Here is a simple service snippet. This should be enough.
#Injectable({
providedIn: 'root',
})
export class MyService {
constructor(private http: HttpClient) {}
getData(): Observable<any> {
const url = '';
return this.http.get(url);
}
}

APNS Notifications: Python HTTP/2 POST request returning 404 ({"reason":"BadPath"})

I am developing a watchOS app and I want to send push notifications to my users. I have enabled "Push Notifications" in signing and capabilities and a file called "app_name WatchKit Extension" was generated containing one entitlement called APS environment whose value is set to "development".
I have also generated a .p8 file in the Apple Developer Website with the authentication key and that also gives me the key id.
I have created a Swift class called App Delegate that conforms to UNUserNotificationCenterDelegate. I have implemented the method applicationDidFinishLaunching from where I call WKExtension.shared().registerForRemoteNotifications(). Then I implemented the didRegisterForRemoteNotifications where I receive the device token and convert it into a string by executing these lines of code:
let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
let token = tokenParts.joined()
Then I send the token to the server. In the server I have a Python script that makes the post request to https://api.sandbox.push.apple.com:443 with the headers and notification payload. However, I always get a 404 error ({"reason":"BadPath"}).
I don't know what I am doing wrong. Am I configuring anything wrong? This is the Python script I am using:
import time
import httpx
import asyncio
import jwt
ALGORITHM = 'ES256'
APNS_AUTH_KEY = "path to .p8 file"
f = open(APNS_AUTH_KEY)
secret = f.read()
apns_token = jwt.encode(
{
'iss': 'cert_id',
'iat': time.time()
},
secret,
algorithm=ALGORITHM,
headers={
'alg':ALGORITHM,
'kid':'key_id'
}
)
dev_server = "https://api.sandbox.push.apple.com:443"
device_token = "9fe2814b6586bbb683b1a3efabdbe1ddd7c6918f51a3b83e90fce038dc058550"
headers = {
'method': 'POST',
'path': '/3/device/{0}'.format(device_token),
'autorization': 'bearer {0}'.format(apns_token),
'apns-push-type': 'myCategory',
'apns-expiration': '0',
'apns-priority': '10',
}
payload = {
"aps" : {
"alert" : {
"title" : "Hello Push",
"message": "This is a notification!"
},
"category": "myCategory"
}
}
async def test():
async with httpx.AsyncClient(http2=True) as client:
client = httpx.AsyncClient(http2=True)
r = await client.post(dev_server, headers=headers, data=payload)
print(r.text)
print(r)
asyncio.run(test())
Is there anything wrong with the way I am setting things up or performing the post request?
Thank you for your help!

Can not get python file output using node.js

I am trying to fetch python output from Node.js script using postman but unable to get the required output. I am explaining my code below.
app.js:
router.post('/usecase-workflow', async (req, res) => {
try{
let responseUsecase = await usecaseWorkflow.fetchUsecaseWorkflow(req);
res.send(responseUsecase);
}catch(error) {
responseObj = {
status: 'error',
msg: 'Error occurred while downloading ubot file',
body: error
}
res.send(responseObj);
}
})
usecaseWorkflow.js:
const mongoose = require('mongoose');
const axios = require('axios');
const request = require('request');
class DefineUseCase {
fetchUsecaseWorkflow = async(req) => {
try{
const response = await axios.post('http://127.0.0.1:5005/usecase-workflow',req);
//console.log(response);
return response;
}catch(error) {
console.log(error);
}
}
}
module.exports = new DefineUseCase();
When I am doing REST API call from postman the above code is executing. I am giving the screen shot of postman below.
Here my need is i will upload one zip file and one node.js REST API will call. Inside the node script I am calling one python file to get the final output. But as per my code its not giving any result. If I am calling the Python file directly from postman Its giving some result. I am also giving python call postman screen shot below.
So here I need to fetch the same above output via node.js REST API.

Aws Websocket {"message":"Missing Authentication Token"}

anyone knows what's wrong with this code.
The address from the api gateway returns {"message": "Missing Authentication Token"}.
All code deploy by serverless framework on AWS.
JS custom.js
var socket;
// Connect to the WebSocket and setup listeners
function setupWebSocket(username, token) {
socket = new ReconnectingWebSocket(" {api endpoint}?token=" + token);
socket.onopen = function(event) {
data = {"action": "getRecentMessages"};
socket.send(JSON.stringify(data));
};
socket.onmessage = function(message) {
var data = JSON.parse(message.data);
data["messages"].forEach(function(message) {
if ($("#message-container").children(0).attr("id") == "empty-message") {
$("#message-container").empty();
}
if (message["username"] === username) {
$("#message-container").append("<div class='message self-message'><b>(You)</b> " + message["content"]);
} else {
$("#message-container").append("<div class='message'><b>(" + message["username"] + ")</b> " + message["content"]);
}
$("#message-container").children().last()[0].scrollIntoView();
});
};
}
// Sends a message to the websocket using the text in the post bar
function postMessage(token){
var content = $("#post-bar").val();
if (content !== "") {
data = {"action": "sendMessage", "token": token, "content": content};
socket.send(JSON.stringify(data));
$("#post-bar").val("");
}
}
handler.py
def _send_to_connection(connection_id, data, event):
gatewayapi = boto3.client("apigatewaymanagementapi",
endpoint_url="https://" + event["requestContext"]["domainName"] +
"/" + event["requestContext"]["stage"])
return gatewayapi.post_to_connection(ConnectionId=connection_id,
Data=json.dumps(data).encode('utf-8'))
Contrary to the message, the issue is not actually a missing authentication token. API Gateway returns the same message when the endpoint you are accessing is not exactly correct; i.e. does not exist, probably due to some typo or slight misconfiguration. I would suggest confirming that your endpoint is valid and re-check that.
The reason you get this message is because if they returned a 404 it meant that you now know that the (invalid) endpoint you called does not exist. But that also means that you could do a brute force process of checking all possible endpoints and any not returning 404 do exist but behind some kind of firewall, authentication system or API Key. By returning 403 for all endpoints, even if they don't exist, AWS are improving their security posture. Its the same reason that on a login form you don't return a message such as "Username does not exist", because otherwise someone could find a way to find valid usernames based on your error message.
Hope that helps

Categories

Resources