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.
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).
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With