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

Reply via email to