i'm facing a problem with Asyncio, web sockets and sync calls.
We have an application which uses websockets and Flask.
Websockets are managed with asyncio, we receive messages on
async def on_message(message):
** some logic
await doStuff(message)
The problem is that our workflow is that we have an endpoint with Flask that needs to perform some action that needs to send a request to the websocket server, wait for the ws response and send the sync response to the controller.
Something like that
@app.route("/request", methods=["POST"])
def manageRequest():
data = request.get_json()
## send data to ws
ws.send(data)
## we need the response on the on_message method
response = {} ##ws response
makeSomething(response)
return newResponse
is there a way to wait for the async response in the method, just like a Completable in Java?
No, there is no simple way to do that, in terms of a simple keyword, outside of the event loop. All coroutines must run inside an event loop, and only coroutines can call the
awaitkeyword.asyncio.runwill run the passed in coroutine on the event loop and then return its result when finished, but it is mainly intended to be the entry point for the entire program or an entire thread. It will block the thread it is called on until the coroutine(s) is(are) completely finished, and it has some setup and cleanup it does for the event loop, so it is heavy handed.The primary method to interact with an event loop is to use
asyncio.run_coroutine_threadsafe. Note that this requires you to have a reference to theasyncioevent loop itself. I am not familiar with Flask, and so it sounds like you have a thread running with the WebSocket server event loop. You'll need the reference to that loop.Another method, which may be desired if your coroutines and WebSocket server are setup in such a way where it isn't desired for the coroutine to return the response value directly, you could use a standard
queue.Queueto get data back out of the event loop.