jbflow
jbflow

Reputation: 642

How to do a get request inside a Django Channels consumer connect method?

I'm trying to do a get request for a seperate django CRUD API app inside a Django Channels app connect method

So inside the consumers.py I'm doing this


class AssistantConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.commands = requests.get('http://localhost:8000/api/commands')
        print(self.commands)

Doing this results in the websocket getting stuck on

WebSocket HANDSHAKING /ws/assistant/user/ [127.0.0.1:64374]

Can anyone tell me why?

The API is working on it's own, I'm posting to it from React, which also connects to the websocket. All that is working - I just need to fetch some data from the database in the consumer.

Couldn't find anything anywhere about this situation.

Upvotes: 0

Views: 2094

Answers (2)

jbflow
jbflow

Reputation: 642

OK I found a solution - don't know if it's the right one or how stable it is but this package on PyPi does the trick.

https://pypi.org/project/requests-async/

Thanks to Timothee for pointing out that I needed to be doing it async.

This now works.

import requests_async as requests
async def connect(self):
    self.commands = await requests.get('http://localhost:8000/api/commands/')
    print(self.commands)
    await self.accept()

Maybe this will help someone else and if anyone knows of a reason I shouldn't be doing this I'd be interested to know.

Upvotes: 1

Timaayy
Timaayy

Reputation: 856

async def connect is only called when a client attempts a connection and your routing file sends the incoming connection to your AssistantConsumer. In your case, you are getting stuck on this initial 'handshake'. This means that you are receiving the request to connect from the client but you are not accepting that connection and therefore the WebSocket connection is never opened.

Adding await self.accept() should accept the incoming connection and therefore open the WebSocket.

This is what it would look like:

class AssistantConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.commands = requests.get('http://localhost:8000/api/commands')
        print(self.commands)
        await self.accept()

Upvotes: 0

Related Questions