Calling Python method in Tornado server from Javascript

1,251 views
Skip to first unread message

Gee

unread,
Sep 4, 2014, 8:52:43 PM9/4/14
to python-...@googlegroups.com
Hello,
I am using Tornado server, and trying to execute/call a python function (defined in ui_methods.py) from the javascript (front.html). The code (have not included the server code) below is a simplified version for ease of understanding.
Now I have two issues:
1.  It seems like the drawPie is called as soon as I open the web browser. It displays "'fracs:', ['10', '20', '30', '40']) File saved" even before the Vote button is pressed. However, I would like to call the drawPie method once the Vote button is pressed.
2. In front.html, if I define the variable data and then use in drawPie(data) as shown below, I get error "NameError: global name 'data' is not defined". How can I define the "data" variable and assign values in javascript before passing it to drawPie()?

I will appreciate any help/suggestion.

var data = ["10", "20", "30", "40"];
{{ drawPie(data) }};

ui_methods.py

from pylab import *
print "Within ui_methods"
def drawPie(self, fracs):
    figure(3, figsize=(4,4))
    axes([0.1, 0.1, 0.8, 0.8])
    mycolors=['red', 'blue', 'green', 'brown']
    mylabels=['Red', 'Blue', 'Green', 'Brown']
    #fracs=[40, 30, 20, 10]
    print ("fracs:", fracs)
    pie(fracs,labels=mylabels,colors=mycolors)
    savefig('pie')
    print ("File saved")
    return



front.html
<!DOCTYPE html>
<html>
    <head>
        <title>Pie Chart</title>
        <script
        src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
        </script>
        <script type="text/javascript">
            var ws = new WebSocket("ws://10.151.170.5:8888/websocket");
            ws.onmessage = function(evt){
                x = document.createElement("p");
                document.getElementById("button").appendChild(x);
            }
            function DispatchText(){
                if (document.getElementById("day1").checked) {
                    var data = ["10", "20", "30", "40"];
                    {{ drawPie(["10", "20", "30", "40"]) }};
                }
            }
        </script>
    </head>
    <body>
    <form>
    <input type="radio" id="day1" name="day" value="Monday">Monday<br>
    <input type="radio" id="day2" name="day" value="Tuesday">Tuesday<br>
    </form>
    <button onclick= "DispatchText()" action="javascript:void(0);">Vote</button>
    </body>
</html>




Gee

unread,
Sep 5, 2014, 12:25:07 AM9/5/14
to python-...@googlegroups.com
Well, the answer to question 2 is found from the internet as below (in case someone needs it). I am yet to find an answer for question 1.
{% set data=  ["10", "20", "30", "40"] %};
{{ drawPie(data)}};

Mike Nolet

unread,
Sep 5, 2014, 4:44:32 AM9/5/14
to python-...@googlegroups.com
Hi Gee,

Your {{ drawPie(data) }}: call will indeed immediately call the function as it's rendering front.html.

If you want to call the python function *later* then you will have to do so using javascript, you won't be able to do that using the tempting syntax.  "{{}}" is used to render the HTML to be sent to the browser and the connection to Tornado will be long closed before the browser starts processing the HTML/Javascript.  If you're using jQuery, (highly recommended) you could do something like this in your HTML (untested and written quickly with $.ajax to give you an idea):

function DispatchText(){
   
if (document.getElementById("day1").checked) {
     
var data = ["10", "20", "30", "40"];

      $
.ajax({
         url
: "http://your.web.domain.com/callDrawPie",
         data
: JSON.stringify(data),
         dataType
: 'json',
         success
: function() {
            console
.log("Server handled request successfully.");
           
// do whatever client side work you need to do here.
         
}
     
});        
   
{{ drawPie(["10", "20", "30", "40"]) }};
   
}
}


And then on the server side you just need a new handler for /callDrawPie that reads in the request body, decodes the JSON and calls your drawPie function accordingly.

Hope that's helpful,

-Mike

Gee

unread,
Sep 8, 2014, 12:52:36 AM9/8/14
to python-...@googlegroups.com
Thank you so much Mike for your help. I have been able to implement your suggestions, and it now works beautifully with ajax/JSON. 
Reply all
Reply to author
Forward
0 new messages