#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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/050.ac7ce1ee30a515be9135892200fa7b11%40djangoproject.com.