How update data in JavaScript when flask send a josinify response - javascript

I am making a project with raspberry Pi, is a control and monitoring data through internet.
Finally I can make the communication with flask-html-JavaScript
In summary I want to update my chart js graph when the flask function response with jsonify data
I am using Ajax method with getjson but I am executing with setinterval and I don’t want to use setinterval, I want that the getjson function execute when flask function response with jsonify data
Exist any method that can make it?
this is my code in flask:
#app.route('/start', methods=['GET', 'POST'])
def start():
n = request.form['number']
print(int(n))
for i in range(int(n)):
GPIO.output(19, GPIO.LOW)
while gt.read_sensor() == 0:
pass
now0 = datetime.now()
for j in range(1):
value = adc.read( channel = 0 )
volt = (value/1023)*3.3
presure = ((volt/3.3)-0.1)*3/2
p1.append(presure)
global pon
pon = presure
time.sleep(0.25)
pon = -100
Here I capture the value sensor and I call update with global variable the function presson:
#app.route('/pon')
def presson():
return jsonify(result = presson)
and this is my javascript code:
var pon = 0;
var test = 0;
function sendData() {
$.ajax({
type: "POST",
url: "{{ url_for('start') }}",
data: { number : $('#number').val() }
});
setInterval(update_values,100);
}
function update_values() {
$.getJSON('/pon',
function(data) {
$('#result').text(data.result);
pon = data.result;
console.log(data)
});
currently that work good, but sometimes the value is not update, then I want that the function getJSON() run only when recieve a correct value (without setInterval method), what recommend me?

Related

flask upload python-base64 image

I'm trying to upload a base64 image (encoded in Python) to my webapp using Flask.
I get the encoded image but get an error when modifying the src of the image element.
Ajax:
$.ajax({
dataType: "json",
type: 'POST',
url: getWebAppBackendUrl("return_cam"),
data: {
image_bytes: img_b64
},
success: function (filter_bytes) {
let data = filter_bytes.heatmap
document.getElementById("cam").src = "data:image/png;base64," + data;
}
});
server side:
#app.route('/return_cam', methods=['GET', 'POST'])
def return_cam():
img_b64 = request.form.get("image_bytes") #get POST data
api_result = client.run_function("returnCAM", image=img_b64)
response = api_result.get("response")
result_dict = json.loads(response)
return json.dumps(result_dict)
The 'data' variable looks like this when printed in the console:
b'ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj/ADj...'
and I get ERR_INVALID_URL.
I guess there is some processing to do on this data variable...
Thanks for the help!
Looks like you need to decode that value. Something like:
img_b64 = request.form.get("image_bytes")
img_b64 = img_b64.decode('utf-8')
#...
Not sure if client.run_function will appreciate this, as it's not clear from your question what that method does. Perhaps you could put the above mod within that function if you wrote it yourself, so that the correctly decoded value ends up within response as expected.

ODOO: How to call python function from javascript [duplicate]

I'd like to call a Python function from JavaScript code, because there isn't an alternative in JavaScript for doing what I want. Is this possible? Could you adjust the below snippet to work?
JavaScript code:
var tag = document.getElementsByTagName("p")[0];
text = tag.innerHTML;
// Here I would like to call the Python interpreter with Python function
arrOfStrings = openSomehowPythonInterpreter("~/pythoncode.py", "processParagraph(text)");
~/pythoncode.py contains functions using advanced libraries that don't have an easy to write equivalent in JavaScript:
import nltk # is not in JavaScript
def processParagraph(text):
...
nltk calls
...
return lst # returns a list of strings (will be converted to JavaScript array)
All you need is to make an ajax request to your pythoncode.
You can do this with jquery http://api.jquery.com/jQuery.ajax/, or use just javascript
$.ajax({
type: "POST",
url: "~/pythoncode.py",
data: { param: text}
}).done(function( o ) {
// do something
});
From the document.getElementsByTagName I guess you are running the javascript in a browser.
The traditional way to expose functionality to javascript running in the browser is calling a remote URL using AJAX. The X in AJAX is for XML, but nowadays everybody uses JSON instead of XML.
For example, using jQuery you can do something like:
$.getJSON('http://example.com/your/webservice?param1=x&param2=y',
function(data, textStatus, jqXHR) {
alert(data);
}
)
You will need to implement a python webservice on the server side. For simple webservices I like to use Flask.
A typical implementation looks like:
#app.route("/your/webservice")
def my_webservice():
return jsonify(result=some_function(**request.args))
You can run IronPython (kind of Python.Net) in the browser with silverlight, but I don't know if NLTK is available for IronPython.
Communicating through processes
Example:
Python: This python code block should return random temperatures.
# sensor.py
import random, time
while True:
time.sleep(random.random() * 5) # wait 0 to 5 seconds
temperature = (random.random() * 20) - 5 # -5 to 15
print(temperature, flush=True, end='')
Javascript (Nodejs): Here we will need to spawn a new child process to run our python code and then get the printed output.
// temperature-listener.js
const { spawn } = require('child_process');
const temperatures = []; // Store readings
const sensor = spawn('python', ['sensor.py']);
sensor.stdout.on('data', function(data) {
// convert Buffer object to Float
temperatures.push(parseFloat(data));
console.log(temperatures);
});
Typically you would accomplish this using an ajax request that looks like
var xhr = new XMLHttpRequest();
xhr.open("GET", "pythoncode.py?text=" + text, true);
xhr.responseType = "JSON";
xhr.onload = function(e) {
var arrOfStrings = JSON.parse(xhr.response);
}
xhr.send();
You cannot run .py files from JavaScript without the Python program like you cannot open .txt files without a text editor. But the whole thing becomes a breath with a help of a Web API Server (IIS in the example below).
Install python and create a sample file test.py
import sys
# print sys.argv[0] prints test.py
# print sys.argv[1] prints your_var_1
def hello():
print "Hi" + " " + sys.argv[1]
if __name__ == "__main__":
hello()
Create a method in your Web API Server
[HttpGet]
public string SayHi(string id)
{
string fileName = HostingEnvironment.MapPath("~/Pyphon") + "\\" + "test.py";
Process p = new Process();
p.StartInfo = new ProcessStartInfo(#"C:\Python27\python.exe", fileName + " " + id)
{
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
};
p.Start();
return p.StandardOutput.ReadToEnd();
}
And now for your JavaScript:
function processSayingHi() {
var your_param = 'abc';
$.ajax({
url: '/api/your_controller_name/SayHi/' + your_param,
type: 'GET',
success: function (response) {
console.log(response);
},
error: function (error) {
console.log(error);
}
});
}
Remember that your .py file won't run on your user's computer, but instead on the server.
Despite what some replies and comments suggest, there are a number of ways for using Python on the front-end. For your question in particular, see this reply.

How do I send data from JS to Python with Flask?

I'm making a website with Flask and I'd like to be able to execute python code using data from the page. I know that I can simply use forms but it's a single page that is continually updated as it receives user input and it'd be a massive pain in the ass to have it reload the page every time something happens. I know I can do {{ function() }} inside the javascript but how do I do {{ function(args) }} inside the javascript using js variables? So far the only thing I can think of is to update an external database like MongoDB with the js then use Python to read from that, but this process will slow down the website quite a lot.
The jQuery needs to get a list of dictionary objects from the Python function which can then be used in the html. So I need to be able to do something like:
JS:
var dictlist = { getDictList(args) };
dictlist.each(function() {
$("<.Class>").text($(this)['Value']).appendTo("#element");
});
Python:
def getDictList(args):
return dictlistMadeFromArgs
To get data from Javascript to Python with Flask, you either make an AJAX POST request or AJAX GET request with your data.
Flask has six HTTP methods available, of which we only need the GET and POST. Both will take jsdata as a parameter, but get it in different ways. That's how two completely different languages in two different environments like Python and Javascript exchange data.
First, instantiate a GET route in Flask:
#app.route('/getmethod/<jsdata>')
def get_javascript_data(jsdata):
return jsdata
or a POST one:
#app.route('/postmethod', methods = ['POST'])
def get_post_javascript_data():
jsdata = request.form['javascript_data']
return jsdata
The first one is accessed by /getmethod/<javascript_data> with an AJAX GET as follows:
$.get( "/getmethod/<javascript_data>" );
The second one by using an AJAX POST request:
$.post( "/postmethod", {
javascript_data: data
});
Where javascript_data is either a JSON dict or a simple value.
In case you choose JSON, make sure you convert it to a dict in Python:
json.loads(jsdata)[0]
Eg.
GET:
#app.route('/getmethod/<jsdata>')
def get_javascript_data(jsdata):
return json.loads(jsdata)[0]
POST:
#app.route('/postmethod', methods = ['POST'])
def get_post_javascript_data():
jsdata = request.form['javascript_data']
return json.loads(jsdata)[0]
If you need to do it the other way around, pushing Python data down to Javascript, create a simple GET route without parameters that returns a JSON encoded dict:
#app.route('/getpythondata')
def get_python_data():
return json.dumps(pythondata)
Retrieve it from JQuery and decode it:
$.get("/getpythondata", function(data) {
console.log($.parseJSON(data))
})
The [0] in json.loads(jsdata)[0] is there because when you decode a JSON encoded dict in Python, you get a list with the single dict inside, stored at index 0, so your JSON decoded data looks like this:
[{'foo':'bar','baz':'jazz'}] #[0: {'foo':'bar','baz':'jazz'}]
Since what we need is the just the dict inside and not the list, we get the item stored at index 0 which is the dict.
Also, import json.
.html
... id="clickMe" onclick="doFunction();">
.js
function doFunction()
{
const name = document.getElementById("name_").innerHTML
$.ajax({
url: '{{ url_for('view.path') }}',
type: 'POST',
data: {
name: name
},
success: function (response) {
},
error: function (response) {
}
});
};
.py
#app.route("path", methods=['GET', 'POST'])
def view():
name = request.form.get('name')
...
im new in coding, but you can try this:
index.html
<script>
var w = window.innerWidth;
var h = window.innerHeight;
document.getElementById("width").value = w;
document.getElementById("height").value = h;
</script>
<html>
<head>
<!---Your Head--->
</head>
<body>
<form method = "POST" action = "/data">
<input type = "text" id = "InputType" name = "Text">
<input type = "hidden" id = "width" name = "Width">
<input type = "hidden" id = "height" name = "Height">
<input type = "button" onclick = "myFunction()">
</form>
</body>
</html>
.py
from flask import Flask, request
app = Flask(__name__)
html = open("index.html").read()
#app.route("/")
def hello():
return html
#app.route("/data", methods=["POST", "GET"])
def data():
if request.method == "GET":
return "The URL /data is accessed directly. Try going to '/form' to submit form"
if request.method == "POST":
text = request.form["Text"]
w = request.form["Width"]
h = request.form["Height"]
//process your code
return //value of your code

Undefined result from Deferred AJAX request to Flask

I'm new to Flask and AJAX and my current challenge is that when I make an AJAX request to the server my result is undefined. I am using deferred objects to keep track of several asynchronous requests, and all are working except for the AJAX function shown below. The other two are non-AJAX. Likely problem areas in the code below are marked with >>>>
For context, I am writing the backend to a one-page animation in the browser. The template remains the same regardless of any requests (clicks) from the viewer or any data requests the animation makes on its own programmatically (periodic adding and subtracting of visual material).
Flask/Python:
from flask import Response, json, render_template
from app import app
from motifs import get_motif_list
# >>>> can/should I use two functions aimed at the same route? Not sure how to both render the template and pass data
#app.route('/')
def index():
motifs = get_motif_list(10)
return Response(json.dumps(motifs), mimetype='application/json')
#app.route("/")
def index():
return render_template("index.html")
JavaScript:
function getData() {
var deferredData = new jQuery.Deferred();
$.ajax({
type: "GET",
url: "/",
dataType: "json", // >>>> when I comment this out I get an error, when I leave it in I get a parsererror
success: deferredData.resolve(),
complete: function(xhr, textStatus) {
console.log("AJAX REquest complete -> ", xhr, " -> ", textStatus);
}
});
return deferredData; // contains the passed data >>>> currently undefined!!!
};
// DEFERRED OBJECTS
// used to perform a callback after multiple asynchronous functions
var deferredData = getData();
var deferredWindow = windowLoaded();
var deferredImages = loadImages();
// SINGLE CALLBACK AFTER MULTIPLE ASYNCHRONOUS FUNCTIONS
$.when( deferredWindow, deferredData, deferredImages ).done( function( window, data, images ) {
console.log("The window has loaded - " + window); // successful!
console.log("The data are: " + data); // >>>> undefined!
console.log("The images are: " + images); // successful!
});
UPDATE:
Thanks to #Jason P the success function in the getData AJAX call is now success: function(data) { deferredData.resolve(data); } and the result is no longer undefined! Alas, it's not my data, either. I think I may have a bug (or a conceptual misunderstanding) in my Flask code because the request returns the complete text of my html template instead of my JSON data. Thoughts?
UPDATE 2
Also #Jason P's suggestion I changed the route url in Flask and the AJAX request to an alternate route: /ajax to avoid a potential(?!) clash with the template rendering. However, the request still returns the full text of my html template. Perhaps I also need to differentiate the python/flask function names? ...will try that next. Updated code below.
Python/Flask:
#app.route('/ajax')
def index():
motifs = get_motif_list(10)
return Response(json.dumps(motifs), mimetype='application/json')
#app.route("/")
def index():
return render_template("index.html")
JavaScript AJAX url property changed to:
url: '/ajax'
UPDATE 3
I differentiated the python/flask function names so that the /ajax route function is now called ajax(), and the root route '/' function is still called index(). The JSON object now renders to the screen (instead of being passed in as a variable) and nothing from the javascript renders (presumably now missing the template rendering?)
RESOLVED
Following on comments by #Jason P the call is finally resolved and functioning. Wheew! Here is the final code:
Flask/Python
from flask import Response, json, render_template
from app import app
from motifs import get_motif_list
#app.route('/ajax')
def ajax():
motifs = get_motif_list(10)
return Response(json.dumps(motifs), mimetype='application/json')
#app.route("/")
def index():
return render_template("index.html")
JavaScript:
function getData() {
var deferredData = new jQuery.Deferred();
$.ajax({
type: "GET",
url: "/ajax",
// dataType: "json",
success: function(data) {
deferredData.resolve(data);
},
error: function (data) {
debugger;
alert("Error");
},
complete: function(xhr, textStatus) {
console.log("AJAX Request complete -> ", xhr, " -> ", textStatus);
}
});
return deferredData; // contains the passed data
};
// all else in the script remains the same as above...
Thanks!
This line:
success: deferredData.resolve()
Immediately executes resolve().
Try this instead:
success: function(data) { deferredData.resolve(data); }

Create dynamic list of dates in jQuery

In javascript I need a plain list of dates like (for a jquery datepicker):
["16-5-2013", "24-5-2013", "25-5-2013", "26-5-2013"]
Because this list is dynamic I want to use this ajax call:
var disabledDays = $.ajax({
type: 'GET',
url: "/disabled-days",
});
In Django I wrote this test view which returns the data in json:
def disabled_days(request, soort):
from django.http import HttpResponse
import json
soort = ["16-5-2013", "24-5-2013", "25-5-2013", "26-5-2013", "27-5-2013"]
return HttpResponse(json.dumps(soort), mimetype="application/json")
Is json here the way to pass the data? I find the date list in the responsText, but I am unable to access this data.
For example I tried to iter over the items like:
for (i = 0; i < disabledDays1.length; i++) {
item = results[i];
disabledDays.push(item);
}
This results in an empty list.
The responsetext is (encoding is json):
["16-5-2013", "24-5-2013", "25-5-2013", "26-5-2013"]
When I do a console.log() I see this info:
GET http://localhost:8080/disabled-days
200 OK
39ms
jquery-1.9.1.js (regel 8526)
Object { readyState=1, getResponseHeader=function(), getAllResponseHeaders=function(), meer...}
Below is the solution Anh Tú gave (not working yet):
var disabledDays1 = $.ajax({
type: 'GET',
url: "/disabled-days",
});
var disabledDays = []
for (i = 0; i < disabledDays1.length; i++) {
item = results[i];
if(typeof(responsetext)==string){responsetext= JSON.parse(responsetext);} $.each(responsetext,function(i,item){disabledDays.push(item);});
}
console.log(disabledDays);
I think you're handling the ajax request wrong. Normally you declare a callback function when the request success that and process the data received like this:
var disabledDays = []
$.ajax({
type: 'GET',
url: "/disabled-days",
success: function(data){
// data is the response json
disabledDays = data
// do whatever it needs to be done with disabledDays,
// it should be the array of dates.
// the process should be inside this method because of asynchronous
// javascript method execution
}
});
Hope it helps!

Categories

Resources