I'm making a dashboard in python, using flask.
It needs to run three tasks: flask, datastream_handler()
, and dashboard_handler()
. One of these tasks, datastream_handler()
, is required to be an async function.
I've used threading to allow the tasks to run at the same time, (flask and dashboard_handler()
are threads, datastream_handler()
is run from the main thread).
dashboard_handler()
and datastream_handler()
start up and run perfectly, and flask appears to start but when I visit the webpage it gives me an error in terminal:
RuntimeError: You cannot use AsyncToSync in the same thread as an async event loop - just await the async function directly.
I'm confused, because I have awaited the async function (datastream_handler) directly?
I've tried switching it around so that flask is the main thread, and datastream_handler()
is started as a threading.Thread (using asyncio.run to start the async function from a non-async function). However, this just gave the same error.
I looked up this error and a couple of people had the same error with Django and requests-html, but their findings were specific to their respective framework and couldn't be applied to flask.
Here is my code:
datastream_handler
and dashboard_handler
are in different files;
dashboard_handler
is just a normal synchronous function with a while loop and datastream_handler
is an async function which currently only contains a while loop with print and asyncio.sleep, for testing purposes.
I don't think the contents of these functions are causing the errors, but correct me if I am wrong
app = Flask(__name__)
socket = SocketIO(app)
@app.route("/")
async def index():
return render_template("index.html")
def start_flask():
socket.run(app, host="0.0.0.0", port=5000)
async def main():
q = Queue() #queue for data transfer
threading.Thread(target=dashboard_handler, args=(q,), daemon=True).start()
threading.Thread(target=start_flask, daemon=True).start()
await datastream_handler(q)
if __name__ == "__main__":
asyncio.run(main())
If anyone can help I would be very grateful
Thanks
What is the reason putting Flask
in thread? Flask
app should be initiated in the main thread.
About this error,
RuntimeError: You cannot use AsyncToSync in the same thread as an async event loop - just await the async function directly.
I think this come from 2 reasons:
async def index()
which flask will turn it into threaded async using asgiref
's module AsyncToSync
and at it can't be done in thread.If you want to run 3 of those concurrently using thread and one of it is asynchronous
maybe you can use python-worker
link
datastream_handler
and dashboard_handler
as a workerfrom worker import worker, async_worker
@async_worker
async def datastream_handler(q):
...
@worker
def dashboard_handler(q):
...
if __name__ == "__main__":
q = Queue()
asyncio.run(datastream_handler(q))
dashboard_handler(q)
socket.run(app, host="0.0.0.0", port=5000)
datastream_handler
and dashboard_handler
will automatically run as a thread.