0

Running my project with python manage.py runserver boots it up perfectly using the channels asgi development server, however when running the project with Daphne (daphne project.routing:application) I get the error AppRegistryNotReady: Apps aren't loaded yet.

settings.py

INSTALLED_APPS = [
    'channels',
    'whitenoise.runserver_nostatic',
    'django.contrib.staticfiles',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.sites',
    # ...
    # ... installed apps and custom apps
]

WSGI_APPLICATION = 'project.wsgi.application'

ASGI_APPLICATION = 'project.routing.application'

CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [REDIS_URL],
        }
    },
}

routing.py

import os

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter

from django.core.asgi import get_asgi_application
from django.conf.urls import url

from my_app.consumers import MyCustomConsumer

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    'websocket': AuthMiddlewareStack(
        URLRouter([
            url(r'^ws/custom/$', MyCustomConsumer),
        ])
    ),
})

I have tried adding django.setup() as described in other questions, as well as running with uvicorn instead of daphne but still getting the same error. I've also tried pointing to the websocket routing in settings.CHANNEL_LAYERS['ROUTING'] and moving the application initialization out to an asgi.py file but no luck there either. I can't tell what I'm doing differently from the channels documentation, any help appreciated.

rykener
  • 711
  • 1
  • 6
  • 16
  • Does this answer your question? [Django apps aren't loaded yet when using asgi](https://stackoverflow.com/questions/53683806/django-apps-arent-loaded-yet-when-using-asgi) – aaron Nov 07 '21 at 05:18

4 Answers4

10

Fetch Django ASGI application early to ensure AppRegistry is populated before importing consumers and AuthMiddlewareStack that may import ORM models.

import os
from django.conf.urls import url
from django.core.asgi import get_asgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
django_asgi_app = get_asgi_application()

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter

from my_app.consumers import MyConsumer

application = ProtocolTypeRouter({
# Django's ASGI application to handle traditional HTTP requests
"http": django_asgi_app,
# WebSocket chat handler
"websocket": AuthMiddlewareStack(
    URLRouter([
        path('ws/custom/', MyConsumer),
    ])
),

})

Yooy Altroo
  • 111
  • 2
  • After trying this, the following error showed up: ```TypeError asgiref.compatibility in new_application __call__() missing 1 required positional argument: 'send'``` – Jamneck Nov 09 '21 at 15:03
2

asgi.py

import os
import django

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'chat.settings')
django.setup()

from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from chat import routing

application = ProtocolTypeRouter({
    'http': get_asgi_application(),
    "websocket": AuthMiddlewareStack(
        URLRouter(
            routing.websocket_urlpatterns
       )
    )
})
1

Nothing worked for me mentioned above. But i tried with below configuration for working in local machine:

import os
from django.core.asgi import get_asgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings')
django_asgi_app = get_asgi_application()

from channels.routing import ProtocolTypeRouter, URLRouter
from app.tokenAuthMiddleware import TokenAuthMiddleware
from app.routing import channel_routing

application = ProtocolTypeRouter({
    "http": django_asgi_app,
    "websocket": TokenAuthMiddleware(
     URLRouter(channel_routing)
    )
})

And then run the below command:

gunicorn app.asgi:application -k uvicorn.workers.UvicornH11Worker

Using UvicornH11Worker instead of UvicornWorker worked for me.

You can check the below link for its reference: uvicorn running with gunicorn

goutham_mi3
  • 335
  • 1
  • 3
  • 12
0

The problem arose from pointing the daphne server at the application in routing.py, when instead it needs to point at an asgi.py file. However, within settings.py, ASGI_APPLICATION needs to point at the application in the routing.py file.

asgi.py

import os
import django
from channels.routing import get_default_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
django.setup()
application = get_default_application()

settings.py

ASGI_APPLICATION = 'project.routing.application'

routing.py

import os

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.urls import path

from my_app.consumers import MyConsumer


application = ProtocolTypeRouter({
    'websocket': AuthMiddlewareStack(
        URLRouter([
            path('ws/custom/', MyConsumer),
        ])
    ),
})

Then running the daphne server with daphne project.asgi:application

rykener
  • 711
  • 1
  • 6
  • 16