Web Sockets failing connection / Django Channels - django

The problem is, it Used to work.. And then i decided to change my frontend css framework, and then it stopped working. even though the code is the exact same.
my asgi.py file
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
import apps.conversation.routing as conversation_routing
import apps.twikkerprofile.routing as core_routing
import apps.feed.routing as feed_routing
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'twikker.settings')
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": AuthMiddlewareStack(
URLRouter(
conversation_routing.websocket_urlpatterns +
core_routing.websocket_urlpatterns +
feed_routing.websocket_urlpatterns
)
)
})
My routing.py files all follow this pattern:
from django.urls import path
from apps.feed import consumers
websocket_urlpatterns = [
path('ws/tweek/', consumers.TweekConsumer.as_asgi()),
path('ws/like/', consumers.LikeConsumer.as_asgi()),
]
The websockets declaration in the frontend:
const tweekSocket = new WebSocket(
'ws://'
+ window.location.host
+ '/ws/'
+ 'tweek/'
);
const likeSocket = new WebSocket(
'ws://'
+ window.location.host
+ '/ws/'
+ 'like/'
);
And the errors I get in the console:
Edit:
When I start the server, this is what I get
System check identified no issues (0 silenced).
October 24, 2022 - 11:37:50
Django version 4.1.2, using settings 'twikker.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
But I guess it should be Starting ASGI/Channels, doesnt it?

Ok so I followed a youtube tutorial, where I only did "pip install channels", and added "channels" to INSTALLED_APPS in settings.py,
But after reading the channels docs, I saw i should actualy "pip install -U channels["daphne"]" and add "daphne" to INSTALLED_APPS,
then it worked

Related

ModuleNotFoundError: No module named 'channels.http'

I found a couple of similar questions, but nothing really helped. I tried updating asgiref version and also updated channels and django-eventstream. I mainly followed the instruction from the django-eventstream-setup page.
relevant packages from my setup:
Package Version
------------------ ---------
asgiref 3.6.0
channels 4.0.0
Django 4.1.2
django-eventstream 4.5.1
django-grip 3.2.0
django-htmx 1.12.2
gripcontrol 4.1.0
huey 2.4.3
MarkupSafe 2.1.2
requests 2.28.1
Werkzeug 2.2.2
The error I get upon executing python manage.py runserver:
...
File "...\venv\lib\site-packages\django_eventstream\routing.py", line 2, in <module>
from . import consumers
File "...\venv\lib\site-packages\django_eventstream\consumers.py", line 7, in <module>
from channels.http import AsgiRequest
ModuleNotFoundError: No module named 'channels.http'
I created an asgi.py file next to settings.py:
import os
from django.core.asgi import get_asgi_application
from django.urls import path, re_path
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
import django_eventstream
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'channels_test.settings')
application = ProtocolTypeRouter({
'http': URLRouter([
path("events/", AuthMiddlewareStack(URLRouter(django_eventstream.routing.urlpatterns)), { 'channels': ['test'] }),
re_path(r"", get_asgi_application()),
]),
})
In setup.py I updated for using asgi:
WSGI_APPLICATION = "channels_test.wsgi.application"
ASGI_APPLICATION = "channels_test.asgi.application"
This is the folder structure:

Django - How can my asgi websocket path be on my swagger

I am creating an api where two endpoints are using the ws(s) protocol.
As my API is behind Google endpoint, Every endpoint needs to be defined onto an OpenApi2.0 file.
To create this definition I use drf-yasg.
I have a routing. py file like this:
""" systems/routing.py"""
from django.urls import path
from .consumers.list_sessions_consumer import MyFirstConsumer
from .consumers.session_consumer import MySecondConsumer
urlpatterns = [
path(r'v1/ws/yo/<str:uuid>/sessions-sumpup', MyFirstConsumer.as_asgi()),
path(r'v1/ws/yo/<str:uuid>/sessions', MySecondConsumer.as_asgi()),
]
and I register it onto my asgi.py file like this:
# pylint: skip-file
""" main/asgi.py """
import os
import django
from django.core.asgi import get_asgi_application
django_asgi_app = get_asgi_application()
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'main.settings')
django.setup()
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from systems.websockets.routing import urlpatterns as system_websocket_url
application = ProtocolTypeRouter({
"http": django_asgi_app,
"websocket": AuthMiddlewareStack(
URLRouter(
system_websocket_url
)
),
})
Don't mind the import order this is due to this error: Django apps aren't loaded yet when using asgi
So my socket works as expected, now, I want my command line: python3 manage.py generate_swagger swagger.yaml to add these new endpoint to my swagger file.
I tried to directly add my url to the same object then all my other urls like so:
urlpatterns = [
path(r'v1/toto/<str:uuid>', MyView.as_view()),
...,
path(r'v1/ws/yo/<str:uuid>/sessions-sumpup', MyFirstConsumer.as_asgi()),
path(r'v1/ws/yo/<str:uuid>/sessions', MySecondConsumer.as_asgi()),
]
But nothing shows up in my swagger file.
Any ideas ?
Thanks

Django daphne asgi: Django can only handle ASGI/HTTP connections, not websocket

This is really frustrating, I did set everything up according to the documentation, but daphne keeps throwing an error when I try to run it independently, it does work correctly when I use python manage.py run server. this is very frustrating and I can't seem to find similar error anywhere else
2020-01-25 09:57:17,627 INFO Starting server at tcp:port=8000:interface=127.0.0.1
2020-01-25 09:57:17,628 INFO HTTP/2 support not enabled (install the http2 and tls Twisted extras)
2020-01-25 09:57:17,628 INFO Configuring endpoint tcp:port=8000:interface=127.0.0.1
2020-01-25 09:57:17,629 INFO Listening on TCP address 127.0.0.1:8000
127.0.0.1:44516 - - [25/Jan/2020:09:57:27] "WSCONNECTING /ws/score/" - -
2020-01-25 09:57:28,637 ERROR Exception inside application: Django can only handle ASGI/HTTP connections, not websocket.
File "/home/sofdeath/.local/lib/python3.7/site-packages/daphne/cli.py", line 30, in asgi
await self.app(scope, receive, send)
File "/home/sofdeath/.local/lib/python3.7/site-packages/django/core/handlers/asgi.py", line 146, in __call__
% scope['type']
Django can only handle ASGI/HTTP connections, not websocket.
127.0.0.1:44516 - - [25/Jan/2020:09:57:28] "WSDISCONNECT /ws/score/" - -
^C2020-01-25 09:57:39,126 INFO Killed 0 pending application instances
here is my asgi.py
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tabulator.settings')
application = get_asgi_application()
my routing.py:
from django.urls import re_path
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator, OriginValidator
import judge.routing
application = ProtocolTypeRouter({
# (http->django views is added by default)
'websocket': AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter(
judge.routing.websocket_urlpatterns
)
)
),
})
and in my settings.py:
INSTALLED_APPS = [
...
'channels',
]
...
WSGI_APPLICATION = 'tabulator.wsgi.application'
ASGI_APPLICATION = "tabulator.routing.application"
...
CHANNEL_LAYERS = {
"default": {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('127.0.0.1', 6379)],
},
},
}
change your asgi.py to this:
import os
import django
from channels.routing import get_default_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tabulator.settings')
django.setup()
application = get_default_application()
You need to change your asgi.py according to this
# mysite/asgi.py
import os
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
import chat.routing
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": AuthMiddlewareStack(
URLRouter(
chat.routing.websocket_urlpatterns
)
),
})
change your asgi.py as #ahmad says and edit your settings.py to this:
CHANNEL_LAYERS = {
"default": {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [("redis", 6379)],
},
},
}
and be sure that DEBUG = False. That is because you are not running your project on local server it it will throw an error if you use "127.0.0.1" or "localhost".

Deployment of Django Channels App in Google Cloud Platform

I am working on my first django channels app and I want to deploy my django channel app in Google Cloud Platform,its working fine in local server,but when I deployed it on Google Cloud Platform,it gives me errors:
WebSocket connection to 'wss://sockets-263709.appspot.com/ws/chat/user2/' failed: Error during WebSocket handshake: Unexpected response code: 400
I have researched but can't figure out how to setup it,here's my below code:
Entry point:
from Frames.wsgi import application
app = application
wsgi.py:
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Frames.settings')
application = get_wsgi_application()
Asgi.py
import os
import django
from channels.routing import get_default_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Frames.settings')
django.setup()
application = get_default_application()
settings.py:
WSGI_APPLICATION = 'Frames.wsgi.application'
ASGI_APPLICATION = "Frames.routing.application"
CHANNEL_LAYERS={
"default":{
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("sockets-263709.appspot.com", 6379)],
},
},
}
client side:
var wsStart='ws://';
// check if it is secured then assign wss://
if (loc.protocol==='https:'){
wsStart="wss://"
}
var chatSocket = new WebSocket(wsStart +window.location.host +
'/ws/chat/' + roomName + '/');
Requirements.txt
absl-py==0.8.1
aioredis==1.3.1
asgiref==3.2.3
astor==0.8.1
async-timeout==3.0.1
attrs==19.3.0
autobahn==19.11.1
Automat==0.8.0
certifi==2019.11.28
cffi==1.13.2
channels==2.3.1
channels-redis==2.4.1
chardet==3.0.4
constantly==15.1.0
daphne==2.4.0
Django==3.0.1
djangochannelsrestframework==0.0.3
djangorestframework==3.11.0
gast==0.3.2
google-pasta==0.1.8
grpcio==1.25.0
h5py==2.10.0
hiredis==1.0.1
hyperlink==19.0.0
idna==2.8
incremental==17.5.0
Markdown==3.1.1
msgpack==0.6.2
mysqlclient==1.4.6
protobuf==3.11.1
pyasn1==0.4.8
pyasn1-modules==0.2.7
pycparser==2.19
PyHamcrest==1.9.0
PyMySQL==0.9.3
pyOpenSSL==19.1.0
pytz==2019.3
PyYAML==5.2
requests==2.22.0
scipy==1.3.3
service-identity==18.1.0
six==1.13.0
sqlparse==0.3.0
termcolor==1.1.0
tqdm==4.40.2
Twisted==19.10.0
txaio==18.8.1
urllib3==1.25.7
I have a start point from WSGI.py,I have researched and came know about daphne but don't know,can anybody point me how to deploy it properly.The connection is successfully open in locally.
Is the host is correctly mention in config(CHANNEL_LAYERS) in settings.py

Django ASGI New Relic getting a CORS Error Heroku

I am running a Django Application using Django channels and a daphne server (ASGI) instead of the typical gunicorn (WSGI) server. So I had to modify my application to this:
# asgi.py
import os
import django
from channels.routing import get_default_application
from asgiref.wsgi import WsgiToAsgi
from django.core.wsgi import get_wsgi_application
from newrelic import agent
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "server.settings")
django.setup()
application = agent.WSGIApplicationWrapper(get_wsgi_application())
application = WsgiToAsgi(application)
To my surprise this actually works. When I access my django api from a browser or postman it works properly and the data shows up in New Relic. However, I also have a client-side Angular web app which makes REST API calls to the django server and I am getting CORS errors.
Please note that this is not a regular CORS issue as when I remove the new relic wrapper I am able to access my API properly from Angular.
Failed to load https://my-app.herokuapp.com/api/: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin https://frontend.com is therefore not allowed access.
Change your asgi.py file something like this
from django.core.asgi import get_asgi_application
import newrelic.agent #import newrelic agent
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "server.settings")
django_asgi_app = get_asgi_application()
from django.conf import settings
newrelic_config_file = settings.BASE_DIR + "/newrelic.ini" #location of your newrelic.ini file
newrelic.agent.initialize(newrelic_config_file) #initialise agent
application = newrelic.agent.ASGIApplicationWrapper(django_asgi_app)