I am using FastAPI to create a websocket endpoint, but I have lots of synchronous application code that I would like to use without creating async wrappers. But since all websocket methods seem to be async, I am trying to wrap them in a sync utility function.
@app.websocket("/listen")
def listen_endpoint(websocket: WebSocket):
run_sync(websocket.accept())
run_sync(websocket.receive_json())
run_sync(websocket.send_text('ACK'))
run_sync(websocket.close())
The problem is with the implementation of run_sync
. I tried the following as suggested here: https://websockets.readthedocs.io/en/stable/faq.html
Can I use websockets synchronously, without async / await? You can convert every asynchronous call to a synchronous call by wrapping it in asyncio.get_event_loop().run_until_complete(...).
def run_sync(aw: Awaitable):
return asyncio.get_event_loop().run_until_complete(aw)
But:
File "app/main.py", line 56, in listen_endpoint
run_sync(websocket.accept())
File "app/lib/util.py", line 77, in run_sync
return asyncio.get_event_loop().run_until_complete(aw)
File "/home/mangesh/ws/python-versions/3.9.0/lib/python3.9/asyncio/base_events.py", line 618, in run_until_complete
self._check_running()
File "/home/mangesh/ws/python-versions/3.9.0/lib/python3.9/asyncio/base_events.py", line 578, in _check_running
raise RuntimeError('This event loop is already running')
RuntimeError: This event loop is already running
Also tried this:
def run_sync(aw: Awaitable):
return asyncio.run(aw)
But:
File "app/main.py", line 56, in listen_endpoint
run_sync(websocket.accept())
File "app/lib/util.py", line 77, in run_sync
return asyncio.run(aw)
File "/home/mangesh/ws/python-versions/3.9.0/lib/python3.9/asyncio/runners.py", line 33, in run
raise RuntimeError(
RuntimeError: asyncio.run() cannot be called from a running event loop
Found another suggestion at https://www.aeracode.org/2018/02/19/python-async-simplified/, but I don't think that will work in FastAPI.
Is it possible to do what I'm trying to do? Thanks in advance.