#32798: StreamingHttpResponse raises SynchronousOnlyOperation in ASGI server ------------------------------------------+------------------------ Reporter: Ralph Broenink | Owner: nobody Type: Bug | Status: new Component: HTTP handling | Version: 3.2 Severity: Normal | Keywords: Triage Stage: Unreviewed | Has patch: 0 Needs documentation: 0 | Needs tests: 0 Patch needs improvement: 0 | Easy pickings: 0 UI/UX: 0 | ------------------------------------------+------------------------ When using a ASGI-compliant server, such as Daphne, StreamingHttpResponse's iterator will be executed in an asynchronous context, preventing database queries from being performed (raising SynchronousOnlyOperation). This is not expected behaviour, and appears not to be documented.
*Steps to reproduce* 1. Create a simple project and app. Set-up for use with Channels. We are not going to use this component and the bug does seem to originate from Django itself, but Channels ensures that runserver is ASGI-compliant. 2. Create the following view: {{{ from django.contrib.contenttypes.models import ContentType from django.http import StreamingHttpResponse def test_view(request): def generate(): yield "hello\n" list(ContentType.objects.all()) yield "bye\n" return StreamingHttpResponse(generate(), content_type="text/plain") }}} 3. Open the page served by test_view 4. Observe the following trace: {{{ Exception inside application: You cannot call this from an async context - use a thread or sync_to_async. Traceback (most recent call last): File "venv/lib/python3.8/site-packages/channels/staticfiles.py", line 44, in __call__ return await self.application(scope, receive, send) File "venv/lib/python3.8/site-packages/channels/routing.py", line 71, in __call__ return await application(scope, receive, send) File "venv/lib/python3.8/site-packages/django/core/handlers/asgi.py", line 168, in __call__ await self.send_response(response, send) File "venv/lib/python3.8/site-packages/django/core/handlers/asgi.py", line 242, in send_response for part in response: File "channelstest/testapp/views.py", line 9, in generate list(ContentType.objects.all()) File "venv/lib/python3.8/site-packages/django/db/models/query.py", line 287, in __iter__ self._fetch_all() File "venv/lib/python3.8/site-packages/django/db/models/query.py", line 1303, in _fetch_all self._result_cache = list(self._iterable_class(self)) File "venv/lib/python3.8/site-packages/django/db/models/query.py", line 53, in __iter__ results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size) File "venv/lib/python3.8/site- packages/django/db/models/sql/compiler.py", line 1152, in execute_sql cursor = self.connection.cursor() File "venv/lib/python3.8/site-packages/django/utils/asyncio.py", line 24, in inner raise SynchronousOnlyOperation(message) django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async. }}} This error is probably caused by the fact that Django 3 now actively prevents this kind of error (it would have gone undetected in Django 2) and the fact that the iterator is called in an asynchronous context in handlers/asgi.py. As mentioned above, this issue should at the very least be documented in the documentation, but preferably should be resolved altogether. -- Ticket URL: <https://code.djangoproject.com/ticket/32798> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/050.ac7ce1ee30a515be9135892200fa7b11%40djangoproject.com.