Run python scripts from website - python

I just needed a bit of guidance for what I should read more on for the following problem:
I have a few python scripts in a folder on my network drive that I run daily and I want to create a website where I display those scripts in form of a list and when I click on them I want them to be running.
Is there a way to solve this problem with AngularJs ?
Thanks for the help

Okay, So I have a small node server I which I changed a bit for your purpose, I know this isn't an ideal server, but this should do the job. The response on the post request should depend on weather you just want to fire the python script or you want its output too.
From frontend, send a post request with data containing the path to the python script or something else, and change the post case yourself.
Use an angular loop to read through the list, which can be a json served from the static folder in your directory.
This server is not secure by any means and probably can be cracked into in a short while, but for a local scenario it serves the purpose.
Also, if you don't wanna use this, then remember that you can server up the list from an endpoint to the page and populate the HTML using ng-repeat and then send post requests with either the script relative path or the script name and handle paths at the backend, this will be the takeaway. Sorry couldn't post anything for frontend.
var http = require('http');
var fs = require('fs');
var url = require('url');
var colors = require('colors');
var exec = require('child_process').exec;
var staticReg = /^\/static\/\w+\.\w+$/;;
var server = http.createServer(function(request, response){
var url_parts = url.parse(request.url)
if (request.method=="GET"){
process.stdout.write("GET :: ".green + url_parts.path.yellow)
if(staticReg.test(url_parts.path)){
if (fs.existsSync("."+url_parts.path)){
response.writeHead(200)
response.write(fs.readFileSync("."+url_parts.path))
response.end()
process.stdout.write(" :: 200\n".green)
}
else{
response.writeHead(404)
response.end()
process.stdout.write(" :: 404\n".red)
}
return
}
switch (url_parts.path){
case "/":
process.stdout.write(" :: 200\n".green)
var home = fs.readFileSync("./index.html")
response.writeHead(200);
response.write(home);
response.end();
break;
default :
process.stdout.write(" :: 404\n".red)
response.writeHead(404);
response.write("404 not found")
response.end();
break;
}
}
if (request.method=="POST"){
process.stdout.write("POST :: ".green + url_parts.path.yellow)
var body = '';
request.on('data',function(data){
body+=data;
});
request.on('end', function(){
switch(url_parts.path){
case "/fire/":
body=JSON.parse(body)
process.stdout.write(" :: 200\n".green)
command='python '+body["script_path"]
exec(command,function callback(error, stdout, stderr){
// Do error checking here and send response.
})
// Or send response here.
response.writeHead(200);
response.write("Command fired.")
response.end();
break;
}
})
}
})
server.listen(8002);
console.log("Listening to "+"localhost".blue+" on port "+ "8002".green);
server.on('error',function(err){
console.log('Error happened: '+err.toString());
})

Related

how to retrieve Python array in javascript (Flask to React communication)

I dumped Python array to a response with json.dumps and now I'm trying to retrieve the data as Javascript list.
#app.route('/get_scales')
#cross_origin()
def get_scales():
classes = inspect.getmembers(sys.modules['mingus.core.scales'], inspect.isclass)
scales = [class_[0] for class_ in classes if ('Error' not in class_[0] and class_[0] != '_Scale')]
return json.dumps(scales)
getScales() {
// create a new XMLHttpRequest
var xhr = new XMLHttpRequest();
// get a callback when the server responds
xhr.addEventListener("load", () => {
// update the state of the component with the result here
console.log(xhr.responseText);
});
// open the request with the verb and the url
xhr.open("GET", "http://127.0.0.1:5000/get_scales");
// send the request
xhr.send();
var formatted_response = JSON.stringify(xhr.responseText);
console.log(JSON.parse(xhr.responseText));
return xhr.responseText;
}
When I made the function in getScales log to console type of xhr.responseText it shows String, but then when trying to parse it with JSON.parse it throws an error. Trying to stringify it first, like above doesn't help either.
I don't know what error it gave, but I think it was actually because xhr.response, wasn't there yet when you tried to use it. This is because XMLrequests function asynchronously, meaning that while the XMLrequest is still waiting for a response, the rest of your code continues executing. Try this instead:
xhr.open('GET', url, false);
the "false" parameter basically says you want your XMLrequest to function synchronously. So the rest of your code will wait for it to finish.
Do keep in mind that your performance may suffer because of this in a lot of situations.
So if you have multiple XMLrequests at a time or Sequentially, you could consider using HTML5 Workers for this.
Or If you don't want your requests to function synchronously (if you can avoid having your XMLrequest function synchronously, you definitely should) you could also try something like this (something like this is defentintely the best option for performance, so if you can use it):
getScales() {
// create a new XMLHttpRequest
var xhr = new XMLHttpRequest();
// get a callback when the server responds
xhr.addEventListener("load", () => {
// update the state of the component with the result here
console.log(xhr.responseText);
var formatted_response = JSON.stringify(xhr.responseText);
console.log(JSON.parse(xhr.responseText));
return xhr.responseText;
});
// open the request with the verb and the url
xhr.open("GET", "http://127.0.0.1:5000/get_scales");
// send the request
xhr.send();
}

Extract file from POST request nodejs

I am trying nodejs for the first time. I am using it with python shell. I am trying to transfer a file from one PC to another using Post request
app.js (Server PC)
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.post('/mytestapp', function(req, res) {
console.log(req)
var command = req.body.command;
var parameter = req.body.parameter;
console.log(command + "|" + parameter)
pyshell.send(command + "|" + parameter);
res.send("POST Handler for /create")
});
python file send file from (Client PC)
f = open(filePath, 'rb')
try:
response = requests.post(serverURL, data={'command':'savefile'}, files={os.path.basename(filePath): f})
I use fiddler and the request seems to contain the file on Client PC, but I can't seem to get the file on Server PC. How can I extract and save the file? Is it because I am missing headers? what should I use? thanks
I'm going to guess and say you're using Express based on the syntax in your question. Express doesn't ship with out of the box support for file uploading.
You can use the multer or busboy middleware packages to add multipart upload support.
Its actually pretty easy to do this, here is a sample with multer
const express = require('express')
const bodyParser = require('body-parser')
const multer = require('multer')
const server = express()
const port = process.env.PORT || 1337
// Create a multer upload directory called 'tmp' within your __dirname
const upload = multer({dest: 'tmp'})
server.use(bodyParser.json())
server.use(bodyParser.urlencoded({extended: true}))
// For this route, use the upload.array() middleware function to
// parse the multipart upload and add the files to a req.files array
server.port('/mytestapp', upload.array('files') (req, res) => {
// req.files will now contain an array of files uploaded
console.log(req.files)
})
server.listen(port, () => {
console.log(`Listening on ${port}`)
})

Raspberry Pi - Node.js run Python script to continuously sample ADC

I am trying to host a local server (using Node.js) on a Raspberry Pi. The Pi has an ADC (MCP3008) connected to it, and I have a Python script that continuously samples the ADC and prints the current value. I want to have the Node server run the Python script, and whenever it sees a print statement, to just do a console.log(current value) for the time being. I am new to Node and web development in general, so it may be something simple that I'm missing so that Node will continuously receive data from the Python script. I'm trying to use Socket.io at the moment, as that seems to make sense as the method for Node to see changes from the Python script, but maybe this isn't the best way to do it. The basic webpage is from a tutorial I found (http://www.jaredwolff.com/blog/raspberry-pi-getting-interactive-with-your-server-using-websockets/). The code I am currently using is here:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, url= require('url')
, fs = require('fs')
, gpio = require('onoff').Gpio
, PythonShell = require('python-shell');
app.listen(5000);
function handler (req, res) {
var path = url.parse(req.url).pathname;
if (path == '/') {
index = fs.readFile(__dirname+'/public/index.html',
function(error,data) {
if (error) {
res.writeHead(500);
return res.end("Error: unable to load index.html");
}
res.writeHead(200,{'Content-Type': 'text/html'});
res.end(data);
});
} else if( /\.(js)$/.test(path) ) {
index = fs.readFile(__dirname+'/public'+path,
function(error,data) {
if (error) {
res.writeHead(500);
return res.end("Error: unable to load " + path);
}
res.writeHead(200,{'Content-Type': 'text/plain'});
res.end(data);
});
} else {
res.writeHead(404);
res.end("Error: 404 - File not found.");
}
}
// Python
var pyshell = new PythonShell('mcp3008.py');
pyshell.run('mcp3008.py', function (err, results) {
if (err) throw err;
console.log('Results: %j', results);
});
io.sockets.on('connection', function (socket) {
pyshell.on('message', function (message) {
console.log(message);
});
});
Thank you for any hints or help that you can provide!
As jfriend00 recommended, I looked into node.js solutions. I had previously tried this, using several mcp3008 packages available on npm, but none of them successfully installed on my Raspberry Pi (model B). However, I ended up rewriting the one located here (https://github.com/fiskeben/mcp3008.js) as a separate .js file, included it with my code (along with some work from the npm spi library), and put it into a loop to read the ADC pin. That's working for now, and should be good enough for my current needs, but it still seems like a more processor-intensive solution than it should be. Thanks for your feedback!

Calling a python function using dojo/request

Firstly, I'm very new to the world of web development, so sorry if this question is overly simple. I'm trying to use python to handle AJAX requests. From reading the documentation it seems as though Dojo/request should be able to do this form me, however I've not found any examples to help get this working.
Assuming I've got a Python file (myFuncs.py) with some functions that return JSON data that I want to get from the server. For this call I'm interested in a particular function inside this file:
def sayhello():
return simplejson.dumps({'message':'Hello from python world'})
What is not clear to me is how to call this function using Dojo/request. The documentation suggests something like this:
require(["dojo/dom", "dojo/request", "dojo/json", "dojo/domReady!"],
function(dom, request, JSON){
// Results will be displayed in resultDiv
var resultDiv = dom.byId("resultDiv");
// Request the JSON data from the server
request.get("../myFuncs.py", {
// Parse data from JSON to a JavaScript object
handleAs: "json"
}).then(function(data){
// Display the data sent from the server
resultDiv.innerHTML = data.message
},
function(error){
// Display the error returned
resultDiv.innerHTML = error;
});
}
);
Is this even close to what I'm trying to achieve? I don't understand how to specify which function to call inside myFuncs.py?
What you could also do is to create a small jsonrpc server and use dojo to do a ajax call to that server and get the json data....
for python side you can follow this
jsonrpclib
for dojo you could try something like this..
<script>
require(['dojox/rpc/Service','dojox/rpc/JsonRPC'],
function(Service,JsonRpc)
{
function refreshContent(){
var methodParams = {
envelope: "JSON-RPC-2.0",
transport: "POST",
target: "/jsonrpc",
contentType: "application/json-rpc",
services:{}
};
methodParams.services['myfunction'] = { parameters: [] };
service = new Service(methodParams);
function getjson(){
dojo.xhrGet({
url: "/jsonrpc",
load : function(){
var data_list = [];
service.myfunction().then(
function(data){
dojo.forEach(data, function(dat){
data_list.push(dat);
});
console.log(data_list)
},
function(error) {
console.log(error);
}
);
}
});
}
getjson();
}
refreshContent();
});
});
</script>
I've used this approach with django where i am not creating a different server for the rpc calls but using django's url link to forward the call to my function.. But you can always create a small rpc server to do the same..

How to make asynchronous HTTP POST requests

I have this program which runs in a loop with pythoncom.PumpMessages().
While this program runs, it takes input and stores it iternally.
When the input reaches a certain lenght, I'd like to send a HTTP POST request asynchronously to a database I have in the cloud so the program doesn't stop taking input while the request is sent. I do not need the request from the server, although it would be nice.
Is this possible? I'm having a hard time figuring this out. Right now it does it synchronously.
Thanks!
This can be done if you use python requests library to send post requests.
It has been answered here.
Asynchronous Requests with Python requests
The example is for "GET" request but you can easily do post request as well.
JavaScript works on any browser without added libraries.
This is great for loading parts of a page without stalling the UI, but use another method (e.g. server or NodeJS) if sending many requests (e.g. >100).
<p id="demo">Customer info will be listed here...</p>
<script>
function showCustomer(str) {
var xmlhttp;
if (str == "") {
document.getElementById("demo").innerHTML = "";
return;
}
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML = this.responseText;
}
};
xmlhttp.open("GET", "yourFile.php?queryVariable="+str, true);
xmlhttp.send();
}
</script>
Source: http://www.w3schools.com/xml/tryit.asp?filename=try_dom_xmlhttprequest_database
GET: http://www.w3schools.com/xml/tryit.asp?filename=try_dom_xmlhttprequest_first
More here: http://www.w3schools.com/xml/dom_http.asp

Categories