Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make Flask/ keep Ajax HTTP connection alive?

I have a jQuery Ajax call, like so:

    $("#tags").keyup(function(event) {
      $.ajax({url: "/terms",
        type: "POST",
        contentType: "application/json",
        data: JSON.stringify({"prefix": $("#tags").val() }),
        dataType: "json",
        success: function(response) { display_terms(response.terms); },
      });

I have a Flask method like so:

@app.route("/terms", methods=["POST"])
def terms_by_prefix():
    req = flask.request.json
    tlist = terms.find_by_prefix(req["prefix"])
    return flask.jsonify({'terms': tlist})

tcpdump shows the HTTP dialog:

POST /terms HTTP/1.1
Host: 127.0.0.1:5000
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:12.0) Gecko/20100101 Firefox/12.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: application/json; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://127.0.0.1:5000/
Content-Length: 27
Pragma: no-cache
Cache-Control: no-cache

{"prefix":"foo"}

However, Flask replies without keep-alive.

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 445
Server: Werkzeug/0.8.3 Python/2.7.2+
Date: Wed, 09 May 2012 17:55:04 GMT

{"terms": [...]}

Is it really the case that keep-alive is not implemented?

like image 991
Bittrance Avatar asked May 09 '12 20:05

Bittrance


2 Answers

The default request_handler is WSGIRequestHandler.

Before app.run(), Add one line, WSGIRequestHandler.protocol_version = "HTTP/1.1"

Don't forget from werkzeug.serving import WSGIRequestHandler.

like image 90
faicker Avatar answered Oct 20 '22 00:10

faicker


Werkzeug's integrated web server builds on BaseHTTPServer from Python's standard library. BaseHTTPServer seems to support Keep-Alives if you set its HTTP protocol version to 1.1.

Werkzeug doesn't do it but if you're ready to hack into the machinery that Flask uses to instantiate Werkzeug's BaseWSGIServer, you can do it yourself. See Flask.run() which calls werkzeug.serving.run_simple(). What you have to do boils down to BaseWSGIServer.protocol_version = "HTTP/1.1".

I haven't tested the solution. I suppose you do know that Flask's web server ought to be used for development only.

like image 45
jd. Avatar answered Oct 20 '22 01:10

jd.