Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run while loop concurrently with Flask server

I'm updating some LEDs using python. I've been doing this like so:

from LEDs import *
myLEDs = LEDs()
done = False
while not done:
  myLEDs.iterate()

I wanted to use Flask to act as a bridge between some nice-looking ReactJS front-end I can run in my browser (to change the current pattern, etc) and the LED-controlling code in Python.

I have Flask working fine, can handle HTTP requests, etc. I'm wondering how I can set myLEDs.iterate() to continuously run (or run on a rapid schedule) concurrently with my flask app, while still being able to communicate with one another, like so:

myLEDs = LEDs()

@app.route('/changePattern',methods=['POST'])
def changePattern():
  n = request.json['num']
  myLEDs.setPattern(n)
  return jsonify(**locals())

if __name__ == '__main__':
  app.debug = True
  myLEDs.setToFrequentlyIterateAndStillTalkToFlask()
  app.run()

I came across celery, which seems like it would do the trick, but also seems like overkill for how simple my problem is.

Is using Flask overkill for simply wanting a UI to manage my python back-end code? Is there a simpler library than Celery to use for running something in the background?

Edit

This is part of a larger project to develop an app with a Node-Webkit front-end attached to a Python backend. I'm open to changing my approach to this app if it doesn't seem feasible.

like image 746
ryantuck Avatar asked Mar 01 '15 23:03

ryantuck


People also ask

Can Flask handle concurrent requests?

The server component that comes with Flask is really only meant for when you are developing your application; even though it can be configured to handle concurrent requests with app. run(threaded=True) (as of Flask 1.0 this is the default).

Can Flask server handle multiple requests?

Flask applications are deployed on a web server, either the built-in server for development and testing or a suitable server (gunicorn, nginx etc.) for production. By default, the server can handle multiple client requests without the programmer having to do anything special in the application.

How does Flask handle multiple concurrent requests?

Flask will process one request per thread at the same time. If you have 2 processes with 4 threads each, that's 8 concurrent requests. Flask doesn't spawn or manage threads or processes.

How do you keep a Flask server running?

To keep running the application (so that you may close your laptop and have some fun, while the application keeps running), we will use the powerful linux command: nohup (no hangup). We can see after the nohup command the 'process id' : 21108 of the running process.


1 Answers

Use multiprocess to run the loop in a different process as the Flask HTTP requests:

import time
from flask import Flask, jsonify
from multiprocessing import Process, Value


app = Flask(__name__)


tasks = [
   {
      'id': 1,
      'title': u'Buy groceries',
      'description': u'Milk, Cheese, Pizza, Fruit, Tylenol', 
      'done': False
   },
   {
      'id': 2,
      'title': u'Learn Python',
      'description': u'Need to find a good Python tutorial on the web', 
      'done': False
   }
]


@app.route('/todo/api/v1.0/tasks', methods=['GET'])
def get_tasks():
   return jsonify({'tasks': tasks})


def record_loop(loop_on):
   while True:
      if loop_on.value == True:
         print("loop running")
      time.sleep(1)


if __name__ == "__main__":
   recording_on = Value('b', True)
   p = Process(target=record_loop, args=(recording_on,))
   p.start()  
   app.run(debug=True, use_reloader=False)
   p.join()

The tasks part is from here, multiprocessing code from me.
Note the "use_reloader=False" part. This is necessary to avoid running the loop twice. For the reason see here

The functionality can be tested by starting up the server with

python <your_name_for_the example>.py

and calling

curl -i http://localhost:5000/todo/api/v1.0/tasks
like image 72
Evelyn Tímea Fledrich Avatar answered Sep 23 '22 08:09

Evelyn Tímea Fledrich