Klaymen
Klaymen

Reputation: 75

WSGI + jQuery example

I'm quite new in WSGI and jQuery, therefore, I'm looking for a simple example where the combination of these two devices are used. I've already spent several hours to find something in this topic, without any serious success: This question is a good starting point: How to implement a minimal server for AJAX in Python?, however, at this moment I have no idea how to modify it in order to use jQuery in it.

I would really appreciate, if you would be able to give me some hints. Thank you in advance!

Upvotes: 0

Views: 2781

Answers (2)

Klaymen
Klaymen

Reputation: 75

After an extended research I have arrived to the following example. The WSGI file:

import threading
import webbrowser
from wsgiref.simple_server import make_server
from cgi import parse_qs

FILE = 'frontend.html'
PORT = 8080

def test_app(environ, start_response):

    path = environ.get('PATH_INFO', '').lstrip('/')      #get path

    if ("static" in path):                               #handle query for
        status = '200 OK'                                #files in /static
        headers = [('Content-type', 'text/javascript')]
        start_response(status, headers)
        f2serv=file(path,'r')                            #read file 
    return environ['wsgi.file_wrapper'](f2serv)          #return file

    if environ['REQUEST_METHOD'] == 'POST':              #If POST...
        try:
            request_body_size = int(environ['CONTENT_LENGTH'])
            request_body = environ['wsgi.input'].read(request_body_size)
        except (TypeError, ValueError):
            request_body = "0"

        parsed_body = parse_qs(request_body)    
        value = parsed_body.get('test_text', [''])[0] #Returns the first value

        try:
            response_body = str(int(value) ** 2)
        except:
            response_body = 'error'

        status = '200 OK'
        headers = [('Content-type', 'text/plain')]
        start_response(status, headers)
        return [response_body]

    else:                                             #If not POST, just pass
        response_body = open(FILE).read()             #the html file itself
        status = '200 OK'
        headers = [('Content-type', 'text/html'),
                   ('Content-Length', str(len(response_body)))]
        start_response(status, headers)
        return [response_body]

def open_browser():
    # Start a browser after waiting for half a second
    def _open_browser():
        webbrowser.open('http://localhost:%s/%s' % (PORT, FILE))
    thread = threading.Timer(0.5, _open_browser)
    thread.start()

def start_server():   
    httpd = make_server("", PORT, test_app)
    httpd.serve_forever()

if __name__ == "__main__":
    open_browser()
    start_server()

The html file (named "frontend.html"):

<html>
    <head>
        <title>AJAX test</title>
    </head>
    <body>
        <script src="static/jquery-1.8.1.js"
            type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            function submit(){
            $.post( "?", { test_text : $("#test_text").val() },
                function( data ) {
                $('#test_result').html(data);});
            };
        </script>
        square(
        <input type="text" name="test_text" id="test_text" value="0" size="4">
        ) =
        <span id="test_result">0</span>
        <input type="button" value="compute"
            title="compute" onclick="submit();"/>
    </body>
</html>

Important: in order to make the example above work, the actual version of jquery.js must be copied under /static (in this case static/jquery-1.8.1.js).

Upvotes: 0

Paul Collingwood
Paul Collingwood

Reputation: 9116

jQuery runs in the clients browser, so you don't necessarily have to modify the code you linked to. But I'd suggest using this instead of rolling your own python server:

http://flask.pocoo.org/

Much easier to work with then a minimal version with somebody else's code. Plus is directly supports AJAX type commands and is documented:

http://flask.pocoo.org/docs/patterns/jquery/

So, in short, you'd end up with two handlers (URLS that can be accessed)

Mainhandler Ajaxhandler

The "front end" would be served by going to Mainhandler. But when the user clicks on a button, say, the jQuery creates a call to "Ajaxhandler", get's some new data and updates the webpage directly with that new data. And that handler knows to return, say, small amounts of data that can be used to update the page, not replace it.

And that's it.

So you'd have some javascript (jQuery) then that actually did the ajaxy bit.

 /* Send the data using post and put the results in a div */
    $.post( url, { s: term },
            function( data ) {
                var content = $( data );
                $("#result").empty().append( content );
                $("#result").fadeIn();
                $("#s").attr('value', ''); /* reset search text box */

So here when the user clicks a button a post request is made to the server, the results are retrieved and a div is emptied then updated with the new value and it's updated without the webpage changing globally. Ajax!

Upvotes: 1

Related Questions