Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use shared queues with python flask Restful web services

Tags:

python

rest

flask

i'm new to python flask REST web services. I'm trying to develop a rest web service which will have a shared queue, multiple threads will constantly write to that queue on the server side and finally when a user calls a GET methods, the service should return first item in the shared queue.

I was trying getting start to develop this by first implementing a shared variable, following is the code I used,

from flask import Flask
app = Flask(__name__)

count= 0 #Shared Variable

@app.route("/")
def counter():
    count = count+1
    return {'count':count}

if __name__ == "__main__":

    app.run() 

But even above code is not working. Then I though of using cache for the shared variable, but it will not the correct way to implement a shared queue (my ultimate goal). Please give me your advises

like image 780
Proceso Avatar asked Nov 24 '13 05:11

Proceso


People also ask

Can we implement RESTful web services using Flask?

"Flask allows Python developers to create lightweight RESTful APIs."

Is FastAPI better than Flask?

FastAPI surpasses Flask in terms of performance, and it is one of the fastest Python web frameworks. Only Starlette and Uvicorn are faster. Because of ASGI, FastAPI supports concurrency and asynchronous code by declaring the endpoints. For concurrent programming, Python 3.4 introduced Async I/O.

How do you handle multiple requests in Flask?

As of Flask 1.0, flask server is multi-threaded by default. Each new request is handled in a new thread. This is a simple Flask application using default settings.


2 Answers

The thing you want to do is a little bit more complex than that, I'm afraid.

Flask (and other WSGI python systems) don't work in a single thread - they will normally need to spawn multiple threads and instances to cope with requests coming in without blocking, or without multiple requests accessing the same 'first task' at the same time. Thus global variables don't work as they might in other simple single-threaded python scripts.

You need some way for the different processes to all access the same single queue of data.

Usually, this means outsourcing the data queue to an external database. One popular option is Redis. There's a good intro to flask and redis for exactly this:

http://flask.pocoo.org/snippets/73/

I hope this helps you in the right direction!

like image 153
Daniel Fairhead Avatar answered Oct 16 '22 10:10

Daniel Fairhead


You have a couple of bugs in your example. Here is a version that works:

from flask import Flask, jsonify
app = Flask(__name__)

count= 0 #Shared Variable

@app.route("/")
def counter():
    global count
    count = count+1
    return jsonify({'count':count})

if __name__ == "__main__":
    app.run()

The two problems you have in your version are:

  • You missed to declare count as global in your view function. Without the global declaration the view function creates a local variable of the same name.
  • The response returned by the view function cannot be a dictionary, it needs to be a string or a Response object. I corrected this using jsonify() to convert the dict to a JSON string.

But note that this way of creating a shared value is not robust. In particular note that if you run this application under a web server that creates multiple processes then each process will have its own copy of the count value.

If you need to do this on a production server my recommendation is that you use a database to store your shared value(s).

like image 24
Miguel Avatar answered Oct 16 '22 10:10

Miguel