I'm trying to get a response from a websocket server (implemented with websockets
and asyncio
) from within a Django REST API method. Something of the following structure:
Django App
(This does not work, but illustrates the idea)
class AnAPI(views.APIView):
async def get(self, request):
try:
timeout = 5
try:
ws_conn = await asyncio.wait_for(websockets.connect(WS_STRING), timeout)
except ConnectionTimeoutError as e:
<.....>
await ws_conn.send(...)
response = await ws_conn.recv()
ws_conn.close()
return Response(...)
except Exception as e:
print(e)
return Response(...)
WS Server
ws_server = websockets.serve(...)
asyncio.get_event_loop().run_until_complete(ws_server)
asyncio.get_event_loop().run_forever()
Apparently, this makes the Django GET method return a <class 'coroutine'>
AssertionError: Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` to be returned from the view, but received a `<class 'coroutine'>`
Any pointers would be much appreciated!
EDIT: Thanks to all of those who have answered. I was looking for a light weight solution as this is probably the only place where the Django app needed to interact with the WS server, I ended up adopting @Joran's solution, but packed everything into a helper function: something like this:
class AnAPI(views.APIView):
def get(self, request):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
result = loop.run_until_complete(my_async_helper_function())
return Response(...)
async def my_async_helper_function():
try:
timeout = 5
try:
ws_conn = await asyncio.wait_for(websockets.connect(WS_STRING), timeout)
except ConnectionTimeoutError as e:
<.....>
await ws_conn.send(...)
response = await ws_conn.recv()
await ws_conn.close()
return ...
except Exception as e:
print(e)
await ws_conn.close()
return ...
you cannot use async with django responses (I think...)
instead you could try
import asyncio
class AnAPI(views.APIView):
def get(self, request):
try:
timeout = 5
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
ws_conn = loop.run_until_complete(websockets.connect(WS_STRING), timeout)
except ConnectionTimeoutError as e:
<.....>
loop.run_until_complete(ws_conn.send(...))
response = loop.run_until_complete(ws_conn.recv())
ws_conn.close()
return Response(...)
alternatively I believe https://pypi.org/project/websocket_client/ offers a non async interface which is very easy to use
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.