Python Django Channels provides error on startup on colleagues computer but not on my computer what is going wrong?
I have encountered the following error.
The weird thing about this error is that it does not occur on my windows 11 computer, but it only occurs on the windows 11 computer of a colleague and on a remote debian linux server which I have setup specifically to test whether an error like this would also occur on Linux.
All computers have the same code (git synced), same libraries (pip freeze and venv), same python version (except the linux server)
I cannot figure out the origin and I cannot find any information about a similar error on StackOverflow or any other site. The weird thing is that it does work on my own computer!
Traceback (most recent call last):
File "/usr/lib/python3.11/threading.py", line 1038, in _bootstrap_inner
self.run()
File "/usr/lib/python3.11/threading.py", line 975, in run
self._target(*self._args, **self._kwargs)
File "/srv/<redacted>/venv/lib/python3.11/site-packages/django/utils/autoreload.py", line 64, in wrapper
fn(*args, **kwargs)
File "/srv/<redacted>/venv/lib/python3.11/site-packages/daphne/management/commands/runserver.py", line 128, in inner_run
application=self.get_application(options),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/<redacted>/venv/lib/python3.11/site-packages/daphne/management/commands/runserver.py", line 153, in get_application
return ASGIStaticFilesHandler(get_default_application())
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/<redacted>/venv/lib/python3.11/site-packages/daphne/management/commands/runserver.py", line 31, in get_default_application
raise ImproperlyConfigured("Cannot import ASGI_APPLICATION module %r" % path)
django.core.exceptions.ImproperlyConfigured: Cannot import ASGI_APPLICATION module 'config.asgi'
This error is very unhelpful, so after some more debugging we figured out that the origin of the crash comes from:
ImportError: cannot import name 'DEFAULT_CHANNEL_LAYER' from 'channels'
My computer: Windows 11 - Python 3.12.1 (Works here)
My colleague: Windows 11 - Python 3.12.1 (Does not work here)
Linux server (current traceback): Debian - Python 3.11.2 (Does not work here either)
It is not likely because of a python version mismatch, because my colleague also has this issue and does run the same version as me.
I would like to add that the django channels used is a relatively clean install. Therefore I believe the issue to be a problem with the setup. We are also using Django Rest Framework, Django Tenants & Django Tenant User, as major libraries.
It only gives the error when using the daphne ASGI server instead of default WSGI and it only crashes when the consumer is imported, otherwise it does not crash.
Relavant code:
asgi.py
import os
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from django.core.asgi import get_asgi_application
from django.urls import path
from config.middleware import TokenAuthMiddleware
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.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 apps.chats.consumers import MyWebSocketConsumer
application = ProtocolTypeRouter({
"http": django_asgi_app,
"websocket": TokenAuthMiddleware(
URLRouter(
[
path("ws/test/", MyWebSocketConsumer.as_asgi()),
]
)
),
})
config/middleware.py
from django.contrib.auth.models import AnonymousUser
from rest_framework.authtoken.models import Token
from channels.db import database_sync_to_async
from channels.middleware import BaseMiddleware
@database_sync_to_async
def get_user(token_key):
try:
token = Token.objects.get(key=token_key)
return token.user
except Token.DoesNotExist:
return AnonymousUser()
class TokenAuthMiddleware(BaseMiddleware):
def __init__(self, inner):
super().__init__(inner)
async def __call__(self, scope, receive, send):
try:
token_key = dict(scope['headers']).get(b'authorization').decode('ascii').split(" ")[1]
except ValueError:
token_key = None
print("test3")
print(token_key)
scope['user'] = AnonymousUser() if token_key is None else await get_user(token_key)
return await super().__call__(scope, receive, send)
apps/chats/consumers.py
import json
from channels.generic.websocket import JsonWebsocketConsumer
from django_tenants.utils import get_tenant_model
from apps.public.models import Domain
from django_tenants.utils import tenant_context
Tenant = get_tenant_model()
class MyWebSocketConsumer(JsonWebsocketConsumer):
def connect(self):
user = self.scope['user']
tenant_domain = dict(self.scope['headers']).get(b'host').decode('ascii').split(":")[0]
tenant_domain_obj = Domain.objects.get(domain=tenant_domain)
tenant = Tenant.objects.filter(domains=tenant_domain_obj).first()
with tenant_context(tenant):
if user.is_authenticated:
user_chats = user.chats_followed.all()
self.groups = [f"chat_{chat.id}" for chat in user_chats]
# Subscribe the WebSocket connection to all the user's chat groups
for group_name in self.groups:
self.channel_layer.group_add(group_name, self.channel_name)
# Accept the WebSocket connection
self.accept()
def disconnect(self, close_code):
# Remove the WebSocket connection from the group
for group_name in self.groups:
self.channel_layer.group_discard(group_name, self.channel_name)
def receive_json(self, content):
# This is called when a message is received from the client
message = content.get("message", "")
chat_id = content.get("chat_id")
print(message)
# Broadcast the message to the specific chat group
if chat_id:
group_name = f"chat_{chat_id}"
self.channel_layer.group_send(
group_name,
{
"type": "chat_message",
"chat_id": chat_id,
"message": message,
}
)
def chat_message(self, event):
message = event['message']
# Send the message to the WebSocket
self.send(text_data=json.dumps({"message": message}))
I myself am totally baffeled by why it works on my computer and not on somebody else's computer.
- I have checked the environment variables (they are okay)
- I have checked python version
- I have checked installed packages
- I have checked OS versions
it is all the same, what is going wrong.