Reputation: 2710
Hi I am using following class based view to define a endpoint to return large Django Queryset as either Json or CSV using Streaming Response
class DataView(viewsets.ReadOnlyModelViewSet):
permission_classes = [IsAuthenticated, StrictDjangoModelPermissions]
authentication_classes = [JWTAuthentication]
queryset = Data.objects.all()
serializer_class = DataSerializer
pagination_class = LimitOffsetPagination
filter_backends = (DjangoFilterBackend,SearchFilter)
filterset_class = DataFilter
search_fields = ['^ts']
def generate_data(self, start, end, needCSV, points):
cols = ['ts', 'topic_id', 'value_string']
if len(points) > 0:
data = Data.objects.filter(ts__range=(start, end), topic_id__in=points)
else:
data = Data.objects.filter(ts__range=(start, end))
dis_dict = {point.id: point.navPoint for point in Points.objects.filter(id__in=points)}
if needCSV:
yield ','.join(cols + ['dis']) + '\n'
for row in data:
dis_value = dis_dict.get(row.topic_id, '')
yield ','.join(map(str, [getattr(row, col) for col in cols] + [dis_value])) + '\n'
else:
yield '['
for i, row in enumerate(data):
if i > 0:
yield ','
dis_value = dis_dict.get(row.topic_id, '')
row_dict = {col: str(getattr(row, col)) for col in cols}
row_dict['dis'] = dis_value
yield json.dumps(row_dict)
yield ']'
def list(self, request, *args, **kwargs):
try:
csv = request.GET.get('csv', False)
csv = csv and csv.lower() == 'true'
points = request.GET.getlist('point', [])
start = request.GET['start']
end = request.GET['end']
contentType = 'text/csv' if csv else 'application/json'
fileName = 'data.csv' if csv else 'data.json'
response = StreamingHttpResponse(self.generate_data(start, end, csv, points), content_type=contentType)
response['Content-Disposition'] = f'attachment; filename="{fileName}"'
return response
except Exception as e:
return Response({ "status": False, "message": str(e) })
The code works perfectly when I test this using command py manage.py runserver
But when I run this in production using uvicorn project.asgi:application --port 8000
It shows the following warning
C:\Users\Zain ul abdin\AppData\Local\Programs\Python\Python310\lib\site-packages\django\http\response.py:517: Warning: StreamingHttpResponse must consume synchronous iterators in order to serve them asynchronously. Use an asynchronous iterator instead.
warnings.warn(
The point to note is using runserver, the response is actually streaming, line by line, but using uvicorn it suddenly returns entire response, e.g. yield not working properly.
I am using Django 5, and my question is simple how can I get rid of the warning?
Steps I already took to solve the warning but failed
Upvotes: 0
Views: 83