"Cannot import ASGI_APPLICATION module %r" % path channels problem - django

I got this error: ImproperlyConfigured("Cannot import ASGI_APPLICATION module %r" % path)
Here is my routing.py:
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator
from channels.auth import AuthMiddlewareStack
from django.urls import path
from messanger.contacts.consumers import ChatConsumer
application = ProtocolTypeRouter({
# Empty for now (http->django views is added by default)
'websocket': AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter(
[
path('user-notification', ChatConsumer)
]
)
)
)
})
When i remove this line of code, runserver work: from messanger.contacts.consumers import ChatConsumer
But i don't understand what's wrong with my consumers file in contacts app:
from channels.consumer import AsyncConsumer
class ChatConsumer(AsyncConsumer):
async def websocket_connect(self, event):
await self.send({
"type": "websocket.accept",
})
async def websocket_receive(self, event):
await self.send({
"type": "websocket.send",
"text": event["text"],
})

In your settings.py file add:
ASGI_APPLICATION = 'yourappname.asgi.application'

I was able to solve this issue by going in the asgi.py file and import get_asgi_application() which act as tradition http request fallback Like so in asgi.py :
mport os
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator
from django.core.asgi import get_asgi_application
from django.urls import path
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
# Initialize Django ASGI application early to ensure the AppRegistry
# is populated before importing code that may import ORM models.
django_asgi_app = get_asgi_application()
from chat.consumers import AdminChatConsumer, PublicChatConsumer
application = ProtocolTypeRouter({
# Django's ASGI application to handle traditional HTTP requests
"http": django_asgi_app,
# WebSocket chat handler
"websocket": AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter([
path("chat/admin/", AdminChatConsumer.as_asgi()),
path("chat/", PublicChatConsumer.as_asgi()),
])
)
),
})

You need to add in your settings.py file :
ASGI_APPLICATION = 'yourappname.routing.application'
and that is because ASGI_APPLICATION is looking for application = ... in your files. And also there could be a potentional problem with your not adding ChatConsumer.as_asgi() in your path which will instantiate a new consumer instance for each connection.

Related

django.core.exceptions.ImproperlyConfigured: Cannot import ASGI_APPLICATION module 'snp.routing'

ASGI_APPLICATION = 'snp.routing.application'
routing.py:
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import chat.routing
application = ProtocolTypeRouter ({
'websocket': AuthMiddlewareStack(
URLRouter (
chat.routing.websocket_urlpatterns
)
)
})
i'm having this error while imporing ASGI_APPLICATION, how can i fix it
raise ImproperlyConfigured("Cannot import ASGI_APPLICATION module %r" % path)
django.core.exceptions.ImproperlyConfigured: Cannot import ASGI_APPLICATION module 'snp.routing'
from django.core.asgi import get_asgi_application
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator
import appname.routing
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'projectname.settings')
application = ProtocolTypeRouter({
'http': get_asgi_application(),
'websocket': AllowedHostsOriginValidator(
AuthMiddlewareStack((
URLRouter(
appname.routing.webscoket_urlpatterns
)
))
)
})
TRY THIS:)
In my case I just didn't install the channel library.
pip install channels
just try this

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

TypeError: AuthMiddlewareStack() missing 1 required positional argument: 'inner'

Hi I am trying to build ASGI APPLICATION but
I get this error
File "/home/marwan/Desktop/Gowd/gowd_project/config/routing.py", line 8, in <module>
AuthMiddlewareStack(
TypeError: AuthMiddlewareStack() missing 1 required positional argument: 'inner'
and this is my routing.py file
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator
from django.urls import path
application = ProtocolTypeRouter({
'websocket': AllowedHostsOriginValidator(
AuthMiddlewareStack(
# URLRouter([...]) # Empty for now because we don't have a consumer yet.
)
)
})
try below code
application = ProtocolTypeRouter({
'websocket': AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter([])
)
),
})

How to only allow logged in users connect to websocket in Django Channels?

I have a chat app and I want only users that are logged in to be able to connect to the websocket.
How can you achieve that?
Is there something like the #login_required decorator for Django channels?
I know from the documentation that that's how you can access the user:
class ChatConsumer(WebsocketConsumer):
def connect(self, event):
self.user = self.scope["user"]
But how do you deny the connection if the user isn't logged in?
I figured out the answer to my question:
# mysite/routing.py
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import chat.routing
application = ProtocolTypeRouter({
# (http->django views is added by default)
'websocket': AuthMiddlewareStack(
URLRouter(
chat.routing.websocket_urlpatterns
)
),
})
class ChatConsumer(WebsocketConsumer):
def connect(self):
self.user = self.scope['user']
if self.user.is_authenticated:
# accept connection if user is logged in
self.accept()
else:
# don't accept connection if user is not logged in
self.close()
The AuthMiddlewareStack will populate the connection’s scope with a reference to the currently authenticated user, similar to how Django’s AuthenticationMiddleware populates the request object of a view function with the currently authenticated user.
Example to add AuthMiddlewareStack as below:
# mysite/routing.py
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import chat.routing
application = ProtocolTypeRouter({
# (http->django views is added by default)
'websocket': AuthMiddlewareStack(
URLRouter(
chat.routing.websocket_urlpatterns
)
),
})
Reference:
https://channels.readthedocs.io/en/latest/tutorial/part_2.html#write-your-first-consumer

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".