Я пытаюсь получить ответ от сервера websocket (реализованного с помощью websockets
и asyncio
) из метода Django REST API. Что-то вроде следующей структуры:
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()
Очевидно, это заставляет метод Django GET возвращать <class 'coroutine'>
AssertionError: Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` to be returned from the view, but received a `<class 'coroutine'>`
Любые указатели будут очень благодарны!
РЕДАКТИРОВАТЬ: Спасибо всем, кто ответил! Я искал легкое решение, поскольку это, вероятно, единственное место, где приложению Django необходимо взаимодействовать с сервером WS. В конце концов я принял решение @Joran, но упаковал все во вспомогательную функцию, примерно так:
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 ...