channels: Django 3 + channels - runserver does not work with autoreload

I am trying to set up an example repo for Django 3 + ariadne + channels.

I have added channels and ariadne to the top of INSTALLED_APPS

ASGI_APPLICATION = "server.routing.application"
INSTALLED_APPS = [
    "channels",
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "ariadne.contrib.django",
]

And set up routing.py:

from typing import Callable
from ariadne.asgi import GraphQL
from channels.routing import URLRouter, ProtocolTypeRouter
from django.core.handlers.asgi import ASGIHandler
from django.urls import path, re_path

from gql.schema import schema


# This is an ASGI2 compatibility class so that we can use ariadne
# subscriptions with channels.
# Once channels supports ASGI3 this class can go away:
# https://github.com/mirumee/ariadne/issues/210
class DjangoChannelsGraphQL(GraphQL):
    def __call__(self, scope) -> Callable:
        async def handle(receive, send):
            await super(DjangoChannelsGraphQL, self).__call__(scope, receive, send)

        return handle


application = ProtocolTypeRouter(
    {
        "websocket": URLRouter(
            [path("graphql/", DjangoChannelsGraphQL(schema, debug=True))]
        ),
        "http": URLRouter(
            [
                path("graphql/", DjangoChannelsGraphQL(schema, debug=True)),
                re_path(r"", ASGIHandler),
            ]
        ),
    }
)

When I run python manage.py runserver

I get hit with django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.

I don’t quite understand channels’ runserver config, but I’ll include trace for a good measuer:

November 02, 2019 - 16:48:08
Django version 3.0b1, using settings 'server.settings'
Starting ASGI/Channels version 2.3.1 development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
/Users/swistak/messenger/.venv/lib/python3.7/site-packages/channels/management/commands/runserver.py changed, reloading.
Traceback (most recent call last):
  File "/Users/swistak/messenger/.venv/lib/python3.7/site-packages/django/core/management/base.py", line 328, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/swistak/messenger/.venv/lib/python3.7/site-packages/django/core/management/commands/runserver.py", line 60, in execute
    super().execute(*args, **options)
  File "/Users/swistak/messenger/.venv/lib/python3.7/site-packages/django/core/management/base.py", line 369, in execute
    output = self.handle(*args, **options)
  File "/Users/swistak/messenger/.venv/lib/python3.7/site-packages/channels/management/commands/runserver.py", line 59, in handle
    super().handle(*args, **options)
  File "/Users/swistak/messenger/.venv/lib/python3.7/site-packages/django/core/management/commands/runserver.py", line 95, in handle
    self.run(**options)
  File "/Users/swistak/messenger/.venv/lib/python3.7/site-packages/django/core/management/commands/runserver.py", line 102, in run
    autoreload.run_with_reloader(self.inner_run, **options)
  File "/Users/swistak/messenger/.venv/lib/python3.7/site-packages/django/utils/autoreload.py", line 599, in run_with_reloader
    start_django(reloader, main_func, *args, **kwargs)
  File "/Users/swistak/messenger/.venv/lib/python3.7/site-packages/django/utils/autoreload.py", line 584, in start_django
    reloader.run(django_main_thread)
  File "/Users/swistak/messenger/.venv/lib/python3.7/site-packages/django/utils/autoreload.py", line 299, in run
    self.run_loop()
  File "/Users/swistak/messenger/.venv/lib/python3.7/site-packages/django/utils/autoreload.py", line 305, in run_loop
    next(ticker)
  File "/Users/swistak/messenger/.venv/lib/python3.7/site-packages/django/utils/autoreload.py", line 353, in tick
    self.notify_file_changed(filepath)
  File "/Users/swistak/messenger/.venv/lib/python3.7/site-packages/django/utils/autoreload.py", line 328, in notify_file_changed
    trigger_reload(path)
  File "/Users/swistak/messenger/.venv/lib/python3.7/site-packages/django/utils/autoreload.py", line 223, in trigger_reload
    sys.exit(3)
SystemExit: 3

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "manage.py", line 21, in <module>
    main()
  File "manage.py", line 17, in main
    execute_from_command_line(sys.argv)
  File "/Users/swistak/messenger/.venv/lib/python3.7/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
    utility.execute()
  File "/Users/swistak/messenger/.venv/lib/python3.7/site-packages/django/core/management/__init__.py", line 395, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/swistak/messenger/.venv/lib/python3.7/site-packages/django/core/management/base.py", line 341, in run_from_argv
    connections.close_all()
  File "/Users/swistak/messenger/.venv/lib/python3.7/site-packages/django/db/utils.py", line 230, in close_all
    connection.close()
  File "/Users/swistak/messenger/.venv/lib/python3.7/site-packages/django/utils/asyncio.py", line 22, in inner
    raise SynchronousOnlyOperation(message)
django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.```

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 15 (13 by maintainers)

Commits related to this issue

Most upvoted comments

Updating Daphne to 2.4.1 should see you good to go.

Thanks all.

Same for me. Autoreload triggers the following exception:

/Users/mmalysh/Development/my-website/myproject/apps/landing/views.py changed, reloading.
Traceback (most recent call last):
  File "/Users/mmalysh/Development/my-website/venv/lib/python3.6/site-packages/django/core/management/base.py", line 328, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/mmalysh/Development/my-website/venv/lib/python3.6/site-packages/django/core/management/commands/runserver.py", line 60, in execute
    super().execute(*args, **options)
  File "/Users/mmalysh/Development/my-website/venv/lib/python3.6/site-packages/django/core/management/base.py", line 369, in execute
    output = self.handle(*args, **options)
  File "/Users/mmalysh/Development/my-website/venv/lib/python3.6/site-packages/channels/management/commands/runserver.py", line 59, in handle
    super().handle(*args, **options)
  File "/Users/mmalysh/Development/my-website/venv/lib/python3.6/site-packages/django/core/management/commands/runserver.py", line 95, in handle
    self.run(**options)
  File "/Users/mmalysh/Development/my-website/venv/lib/python3.6/site-packages/django/core/management/commands/runserver.py", line 102, in run
    autoreload.run_with_reloader(self.inner_run, **options)
  File "/Users/mmalysh/Development/my-website/venv/lib/python3.6/site-packages/django/utils/autoreload.py", line 599, in run_with_reloader
    start_django(reloader, main_func, *args, **kwargs)
  File "/Users/mmalysh/Development/my-website/venv/lib/python3.6/site-packages/django/utils/autoreload.py", line 584, in start_django
    reloader.run(django_main_thread)
  File "/Users/mmalysh/Development/my-website/venv/lib/python3.6/site-packages/django/utils/autoreload.py", line 299, in run
    self.run_loop()
  File "/Users/mmalysh/Development/my-website/venv/lib/python3.6/site-packages/django/utils/autoreload.py", line 305, in run_loop
    next(ticker)
  File "/Users/mmalysh/Development/my-website/venv/lib/python3.6/site-packages/django/utils/autoreload.py", line 353, in tick
    self.notify_file_changed(filepath)
  File "/Users/mmalysh/Development/my-website/venv/lib/python3.6/site-packages/django/utils/autoreload.py", line 328, in notify_file_changed
    trigger_reload(path)
  File "/Users/mmalysh/Development/my-website/venv/lib/python3.6/site-packages/django/utils/autoreload.py", line 223, in trigger_reload
    sys.exit(3)
SystemExit: 3

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/mmalysh/Development/my-website/myproject/manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "/Users/mmalysh/Development/my-website/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
    utility.execute()
  File "/Users/mmalysh/Development/my-website/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 395, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/mmalysh/Development/my-website/venv/lib/python3.6/site-packages/django/core/management/base.py", line 341, in run_from_argv
    connections.close_all()
  File "/Users/mmalysh/Development/my-website/venv/lib/python3.6/site-packages/django/db/utils.py", line 230, in close_all
    connection.close()
  File "/Users/mmalysh/Development/my-website/venv/lib/python3.6/site-packages/django/utils/asyncio.py", line 22, in inner
    raise SynchronousOnlyOperation(message)
django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.

My asgi.py:

import os
from django.core.asgi import get_asgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
application = get_asgi_application()

Dependencies:

Django==3.0.0
channels==2.3.1