Using Gevent in flask: API is not asynchronous

Viewed 2802

Earlier I was using Waitress. Now I'm using Gevent to run my Flask app that has only one API

from flask import Flask, request, jsonify
import documentUtil
from gevent.pywsgi import WSGIServer

app = Flask(__name__)

@app.route('/post-document-string', methods=['POST']) 
def parse_data():
    req_data = request.get_json(force=True)
    text = req_data['text']
    result = documentUtil.parse(text)
    return jsonify(keywords = result)

if __name__=='__main__':
    http_server = WSGIServer(('127.0.0.1', 8000), app)
    http_server.serve_forever()

This works fine. But the API is not asynchronous. If from front-end, I fire the same API twice at the same time, the second call waits for the first one to give response first.

What is wrong here ? How can I make it asynchronous ?

4 Answers

We use Gunicorn to run Flask in multiple processes. You get more juice out of python that way + auto restarts and stuff. Sample config file:

import multiprocessing

bind = "0.0.0.0:80"
workers = (multiprocessing.cpu_count() * 2) + 1
# ... additional config

Then run with something like

gunicorn --config /path/to/file application.app
"""index.py"""

from flask import Flask
from flask import jsonify

app = Flask(__name__)


@app.route('/')
def index():
    """Main page"""
    doc = {
        'site': 'stackoverflow',
        'page_id': 6347182,
        'title': 'Using Gevent in flask'
    }
    return jsonify(doc)


# To start application
gunicorn -k gevent --bind 0.0.0.0 index:app

k : worker_class
--bind : bind address
# See https://docs.gunicorn.org/en/latest/settings.html

Not sure, however I think adding thread param in server object can solve the problem.

http_server = WSGIServer(('127.0.0.1', 8000), app, numthreads=50)

source: https://f.gallai.re/wsgiserver

I found the Chrome browser was the culprit, after learning based on this answer: https://stackoverflow.com/a/62912019/253127

basically Chrome is trying to cache the result of the first request, and then serve that to the additional tabs.

You might get around this by disabling AJAX caching, assuming you're using jQuery the code is:

$.post(
  {url: '/', cache: false},
  {'text':'my data'}
).then(function(data){
  console.log(`server return data was: ${data}`);
});
Related