Writing my first Lambda funcation to put item with Python
The problem im having - not getting the input from the registration form ( front end hosted on S3 bucket with static webhost enabled ) to the DynamoDB table
the Data will be sent with this funcation to the API hosted on AWS
const BASE_URL = `API-URL`;
function handleForm() {
const name = document.querySelector('#name').value;
const email = document.querySelector('#email').value;
const phone = document.querySelector('#phone').value;
const data = {
name,
email,
phone
}
console.log(data);
saveDataToAWS(data);
}
async function saveDataToAWS(data) {
const result = await axios.post(BASE_URL, data);
return result.data;
}
Im not sure im using AXIOS the right way but lets continue
The Lambda funcation im using now is pretty much this :
import json
import boto3
dynamodb=boto3.resource('dynamodb')
table=dynamodb.Table('register')
def lambda_handler(event, context):
table.put_item(
Item={
'name'=event['name'],
'email'=event['email'],
'phone'=event['phone']
}
)
respone={
'mes':'Good input !'
}
return {
'statusCode': 200,
'body': respone
}
Im pretty much 99% new to writting code in AWS so im sure im doing most of it wrong
Really looking for you help !
The 'event' attribute has a 'body' parameter that will contain the data in your example:
data = json.loads(event["body"])
table.put_item(
Item={
'name':data['name'],
'email':data['email'],
'phone':data['phone']
}
)
Remember to check CloudWatch Logs as well, as it will tell you whether the Lambda was invoked in the first place, and if it failed.
More information on the structure of the event-attribute can be found here:
https://aws-lambda-for-python-developers.readthedocs.io/en/latest/02_event_and_context/
Related
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'
For context, I have an enterprise level subscription to an API provider which includes real-time financial data via a WebSocket protocol. However, the documentation only gives guidance on how to use the WebSocket with Python and NodeJS. I want to establish a connection to the WebSocket via R so I can stream real-time financial data, specifically using the 'websocket' library. Here is the code the API documentation provides for python users.
import websocket
import simplejson as json
import time
import ssl
ws = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE})
ws.connect("wss://websockets.financialmodelingprep.com")
login = {
'event':'login',
'data': {
'apiKey': "<key>",
}
}
subscribe = {
'event':'subscribe',
'data': {
'ticker': "aapl",
}
}
unsubscribe = {
'event':'unsubscribe',
'data': {
'ticker': "aapl",
}
}
ws.send(json.dumps(login))
time.sleep(1)
ws.send(json.dumps(subscribe))
time.sleep(1)
ws.send(json.dumps(unsubscribe))
while True:
print(ws.recv())
I tried to use the WebSocket$new() function in R but I keep getting errors, and I'm assuming this is because I'm not adding my credentials properly. Here is the code I'm trying to use:
WebSocket$new(
url = 'wss://crypto.financialmodelingprep.com/',
headers = list(
login = "{
'event' = 'login',
'data' = {'apiKey' : <key>}
}"
)
)
And here is the error I am getting:
<WebSocket>
Public:
clearAccessLogChannels: function (channels = c("all"))
clearErrorLogChannels: function (channels = c("all"))
clone: function (deep = FALSE)
close: function (code = 1000L, reason = "")
connect: function ()
initialize: function (url, protocols = character(0), headers = NULL, autoConnect = TRUE,
onClose: function (callback)
onError: function (callback)
onMessage: function (callback)
onOpen: function (callback)
protocol: function ()
readyState: function ()
send: function (msg)
setAccessLogChannels: function (channels = c("all"))
setErrorLogChannels: function (channels = c("all"))
Private:
accessLogChannels: function (channels, stompValue)
accessLogChannelValues: none connect disconnect control frame_header frame_paylo ...
callbacks: environment
errorLogChannels: function (channels, stompValue)
errorLogChannelValues: none devel library info warn rerror fatal all
getInvoker: function (eventName)
pendingConnect: FALSE
wsObj: externalptr
I've also tried following this tutorial but again, it doesn't help me figure out my problem.
Would anyone know how I can successfully establish this connection in R? Thanks in advance.
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.
I am trying to wrap my head around AWS-CDK to deploy Lambda functions to aws through it. I already have a pre-existing Api gateway, that I have manually deployed through the console and would like to know if there is any means to connect it as a trigger to new lambda functions deployed using the CDK? I have read through the example code:
apigw.LambdaRestApi(
self, 'Endpoint',
handler=my_lambda,
)
This creates a new gateway in aws, which is not the functionality that I am looking for.
Any help would be much appreciated!
import * as cdk from '#aws-cdk/core';
import * as lambda from '#aws-cdk/aws-lambda';
import * as apigateway from '#aws-cdk/aws-apigateway';
class BindApiFunctionStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const restapi = apigateway.RestApi.fromRestApiAttributes(this, "myapi", {
restApiId : "<yourrestapiid>",
rootResourceId : "<yourrootresourceid>"
});
const helloWorld = new lambda.Function(this, "hello", {
runtime: lambda.Runtime.NODEJS_10_X,
handler: 'index.handler',
code: lambda.Code.fromInline('exports.handler = function(event, ctx, cb) { return cb(null, "hi"); }')
})
restapi.root.addResource("test").addMethod("GET", new apigateway.LambdaIntegration(helloWorld))
}
}
const app = new cdk.App();
new BindApiFunctionStack(app, 'MyStack');
app.synth();
I have a Node.js application which is currently a web-based API. For one of my API functions, I make a call to a short Python script that I've written to achieve some extra functionality.
After reading up on communicating between Node and Python using the child_process module, I gave it a try and achieved my desired results. I call my Node function that takes in an email address, sends it to Python through std.in, my Python script performs the necessary external API call using the provided e-mail, and writes the output of the external API call to std.out and sends it back to my Node function.
Everything works properly until I fire off several requests consecutively. Despite Python correctly logging the changed e-mail address and also making the request to the external API with the updated e-mail address, after the first request I make to my API (returning the correct data), I keep receiving the same old data again and again.
My initial guess was that Python's input stream wasn't being flushed, but after testing the Python script I saw that I was correctly updating the e-mail address being received from Node and receiving the proper query results.
I think there's some underlying workings of the child_process module that I may not be understanding... since I'm fairly certain that the corresponding data is being correctly passed back and forth.
Below is the Node function:
exports.callPythonScript = (email)=>
{
let getPythonData = new Promise(function(success,fail){
const spawn = require('child_process').spawn;
const pythonProcess = spawn('python',['./util/emailage_query.py']);
pythonProcess.stdout.on('data', (data) =>{
let dataString = singleToDoubleQuote(data.toString());
let emailageResponse = JSON.parse(dataString);
success(emailageResponse);
})
pythonProcess.stdout.on('end', function(){
console.log("python script done");
})
pythonProcess.stderr.on('data', (data) => {
fail(data);
})
pythonProcess.stdin.write(email);
pythonProcess.stdin.end();
})
return getPythonData;
}
And here is the Python script:
import sys
from emailage.client import EmailageClient
def read_in():
lines = sys.stdin.readlines()
return lines[0]
def main():
client = EmailageClient('key','auth')
email = read_in()
json_response = client.query(email,user_email='authemail#mail.com')
print(json_response)
sys.stdout.flush()
if __name__ == '__main__':
main()
Again, upon making a single call to callPythonScript everything is returned perfectly. It is only upon making multiple calls that I'm stuck returning the same output over and over.
I'm hitting a wall here and any and all help would be appreciated. Thanks all!
I've used a Mutex lock for this kind of example. I can't seem to find the question the code comes from though, as I found it on SO when I had the same kind of issue:
class Lock {
constructor() {
this._locked = false;
this._waiting = [];
}
lock() {
const unlock = () => {
let nextResolve;
if (this._waiting.length > 0) {
nextResolve = this._waiting.pop(0);
nextResolve(unlock);
} else {
this._locked = false;
}
};
if (this._locked) {
return new Promise((resolve) => {
this._waiting.push(resolve);
});
} else {
this._locked = true;
return new Promise((resolve) => {
resolve(unlock);
});
}
}
}
module.exports = Lock;
Where I then call would implement it like this, with your code:
class Email {
constructor(Lock) {
this._lock = new Lock();
}
async callPythonScript(email) {
const unlock = await this._lock.lock();
let getPythonData = new Promise(function(success,fail){
const spawn = require('child_process').spawn;
const pythonProcess = spawn('python',['./util/emailage_query.py']);
pythonProcess.stdout.on('data', (data) =>{
let dataString = singleToDoubleQuote(data.toString());
let emailageResponse = JSON.parse(dataString);
success(emailageResponse);
})
pythonProcess.stdout.on('end', function(){
console.log("python script done");
})
pythonProcess.stderr.on('data', (data) => {
fail(data);
})
pythonProcess.stdin.write(email);
pythonProcess.stdin.end();
})
await unlock();
return getPythonData;
}
}
I haven't tested this code, and i've implemented where i'm dealing with arrays and each array value calling python... but this should at least give you a good start.