How to connect node.js app with python script? - javascript

I've node app in Meteor.js and short python script using Pafy.
import pafy
url = "https://www.youtube.com/watch?v=AVQpGI6Tq0o"
video = pafy.new(url)
allstreams = video.allstreams
for s in allstreams:
print(s.mediatype, s.extension, s.quality, s.get_filesize(), s.url)
What's the most effective way of connecting them so python script get url from node.js app and return back output to node.js? Would it be better to code it all in Python instead of Meteor.js?

Well, there are plenty of ways to do this, it depends on your requirements.
Some options could be:
Just use stdin/stdout and a child process. In this case, you just need to get your Python script to read the URL from stdin, and output the result to stdout, then execute the script from Node, maybe using child_process.spawn. This is I think the simplest way.
Run the Python part as a server, let's say HTTP, though it could be anything as long as you can send a request and get a response. When you need the data from Node, you just send an HTTP request to your Python server which will return you the data you need in the response.
In both cases, you should return the data in a format that can be parsed easily, otherwise you are going to have to write extra (and useless) logic just to get the data back. Using JSON for such things is quite common and very easy.
For example, to have your program reading stdin and writing JSON to stdout, you could change your script in the following way (input() is for Python 3, use raw_input() if you are using Python 2)
import pafy
import json
url = input()
video = pafy.new(url)
data = []
allstreams = video.allstreams
for s in allstreams:
data.append({
'mediatype': s.mediatype,
'extension': s.extension,
'quality': s.quality,
'filesize': s.get_filesize(),
'url': s.url
})
result = json.dumps(data)
print(result)
Here is a very short example in NodeJS using the Python script
var spawn = require('child_process').spawn;
var child = spawn('python', ['my_script.py']);
child.stdout.on('data', function (data) {
var parsedData = JSON.parse(data.toString());
console.log(parsedData);
});
child.on('close', function (code) {
if (code !== 0) {
console.log('an error has occurred');
}
});
child.stdin.write('https://www.youtube.com/watch?v=AVQpGI6Tq0o');
child.stdin.end();

Related

Running JavaScript with a web request?

BACK STORY :
Let me come from my problem, I need to update firebase database with Arduino so I used firebase-Arduino library but for some reason it will not compile Node MCU so my next way is a bit complicated that is I created a java script to update the firebase I just need to add 1 to the database so I don't need to update sensor value or anything so if I load the webpage it will update the value ,I thought it will be triggered with http request from Arduino but I was wrong it does not work like that.
QUESTION : How to run the JavaScript in a webpage with a web request from Arduino?
Assuming you have node.js installed you can have something like this (source):
const https = require('https');
https.get('your_url_here', (resp) => {
let data = '';
// A chunk of data has been recieved.
resp.on('data', (chunk) => {
data += chunk;
});
// The whole response has been received. Print out the result.
resp.on('end', () => {
console.log(JSON.parse(data).explanation);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
But if you don't have installed node.js you might create the http request from bash commands like curl. This can be useful since you can make it run as daemon (run on th background every X minutes).
Let me know if you managed, something good luck.

How to get a return variable from a Python Script through JQuery?

Currently I am trying to call a simple python script to test if I can receive output into my javascript function. However, when I do this ajax request
function testPhy()
{
$.ajax({
url: "./Phython/test.py",
data: {param: text},
success: function(dataR){
console.log("LK: " + dataR)
},
error: function(request, status, error) {
console.log("Error: " + error)
}
});
}
testPhy();
I get the content's of the script and not the return variable
print("script running")
text = "Why hi there"
return text
Is there a way I can grab the contents of text from the python file using this Ajax query?
You need to create Server Node.js for example, i suggest you to read this tutorial
1- you create a basic server with a basic client web
2- use "child_process" package which comes packaged with node.
const spawnpy = require("child_process").spawn;
const pythonProcess = spawnpy('python',["path/script.py", arg1, arg2, .and so on]);
3- To send data to node just do that in the python script:
print(dataToSendToNode)
sys.stdout.flush()
4- node server can listen for data using:
pythonProcess.stdout.on('data', (data) => {
// Do something with the data returned from python script
});
5- you answer to the ajax request (send data to your client browser)
You have lot of solutions to execute a python script with node.js, you could use python-shell, so when your server will be activa, search on google python node.js ...

Sending data from JavaScript to Python function locally with AJAX

I am trying to build a website where a user can enter text, which will be picked up via javascript, and sent to a python function where it will be posted to twitter. For the time being, the python function is being stored locally, along with the rest of the site. However, my AJAX isn't too great and I'm having a few issues.
I have written AJAX code which sends a POST request to the python function with the tweet, and the response is the entire python script. No connection is made to the socket my script is listening to. Below is the AJAX function and the python script. Any ideas what's going on?
Thanks in advance for any help!
$(function(){
$('#PostTweet').on('click', function(e) {
var tweet = document.getElementById("theTweet").value;
var len = tweet.length;
if(len > 140){
window.alert("Tweet too long. Please remove some characters");
}else{
callPython(tweet);
}
});
});
function callPython(tweet){
window.alert("sending");
$.ajax({
type: "POST",
url: "tweet.py",
data: tweet,
success: function(response){
window.alert(response);
}
})
}
And the Python Script:
from OAuthSettings import settings
import twitter
from socket import *
consumer_key = settings['consumer_key']
consumer_secret = settings['consumer_secret']
access_token_key = settings['access_token_key']
access_token_secret = settings['access_token_secret']
s = socket()
s.bind(('', 9999))
s.listen(4)
(ns, na) = s.accept()
def PostToTwits(data):
try:
api = twitter.Api(
consumer_key = consumer_key,
consumer_secret = consumer_secret,
access_token_key = access_token_key,
access_token_secret = access_token_secret)
api.PostUpdate(data)
makeConnection(s)
except twitter.TwitterError:
print 'Post Unsuccessful. Error Occurred'
def makeConnection(s):
while True:
print "connected with: " + str(na)
try:
data = ns.recv(4096)
print data
PostToTwits(data)
except:
ns.close()
s.close()
break
makeConnection(s)
Your problem is that you are working with pure sockets which know nothing about HTTP protocol. Take a look at Flask or Bottle web micro frameworks to see how to turn python script or function into web endpoint.
you need a webserver so that your can make request via web browser.
you can web framework like flask or django or you can use webpy.
A simple example using webpy from their website
import web
urls = (
'/(.*)', 'hello'
)
app = web.application(urls, globals())
class hello:
def GET(self, name):
if not name:
name = 'World'
return 'Hello, ' + name + '!'
if __name__ == "__main__":
app.run()
then you call url(your python function) from javascript.
You can totally write a simple web server using sockets, and indeed you've done so. But this approach will quickly get tedious for anything beyond a simple exercise.
For example, your code is restricted to handling a single request handler, which goes to the heart of your problem.
The url on the post request is wrong. In your setup there is no notion of a url "tweet.py". That url would actually work if you were also serving the web page where the jquery lives from the same server (but you can't be).
You have to post to "http://localhost:9999" and you can have any path you want after:"http://localhost:9999/foo", "http://localhost:9999/boo". Just make sure you run the python script from the command line first, so the server is listening.
Also the difference between a get and a post request is part of the HTTP protocol which your simple server doesn't know anything about. This mainly means that it doesn't matter what verb you use on the ajax request. Your server listens for all HTTP verb types.
Lastly, I'm not seeing any data being returned to the client. You need to do something like ns.sendall("Some response"). Tutorials for building a simple http server abound and show different ways of sending responses.

any way to send a function with socket.io?

guys.
I want to send a function to browser with socket.io, but failed to do it.
On server side, I response a function with emit, but I get a undefined on browser.
Is there any way to get a function from server with socketio?
there is my code.
// server.js
var static = require('node-static');
var http = require('http');
var file = new(static.Server)();
var app = http.createServer(function(req, res) {
file.serve(req, res);
}).listen(8000);
io = require('socket.io').listen(app);
io.sockets.on('connection', function(socket) {
socket.on('schedule', function() {
console.log('SCHEDULE TASK');
socket.emit('schedule', function() { console.log('hello world'); });
});
});
// client.js
var socket = io.connect('http://localhost:8000');
socket.on('schedule', function(fn) {
fn();
});
socket.emit('schedule');
You cannot send an actual function. You could send a string of Javascript and then you could turn that into a function in the client.
But, I'd suggest you really ought to rethink what you're trying to do here. Generally, the client already has the code it needs (from the script tags that it downloaded) and you send the client data which it then passes to the code it already has or data that it uses to make decisions about which code that it already has to call.
If you show us the real world problem you're trying to solve, we can likely suggest a much better solution than sending a string of Javascript code to the client.
If you really wanted to send a function, you would have to turn it into a string first, send the string, then use the string to turn it back into a function in the client by using a Function object or eval() or creating your own dynamic script tag with inline source.
You can only send strings via socket.io, not functions. That being said, I suggest you to send function names instead.
//server.js
socket.emit('schedule', 'helloworld');
//client.js
function helloworld(){
console.log('hello world');
}
socket.on('schedule',function(name){
window[name](); //hello world
});

Nodejs and callbacks

I am very new to Node.js and how it's callbacks work exactly, I am trying to find some good documentation on it but it's just not clicking for me yet. I'm coming from python so I'll show an example of what I'm use to doing in python, I'm not sure if it's possible in node though
def getRequest(link):
url = urllib.request.urlopen(link).read().decode()
return url
class urlData:
def __init__(self, link):
self.results = getRequest(link)
I'm not sure if node can do this because it's async ways, or is it possible? I'm not sure how to go about this the correct way, how would I replicate this action in node? If not can the this code be toyed with to get similar results, a way to set the variable with the data that is going to come?
The way you might do this in node is the following:
Install Request. https://github.com/mikeal/request
var request = require('request');
Now we have a simple http client.
var data;
request.get({url:url, json:true}, function (e, r, body) {
// this will get called when the response returns. Your app will continue before this is called.
data = body; // i have no idea what you want to do with it
console.log(body); // should be json
})

Categories

Resources