Django StreamingHttpResponse with asgi setup warning

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

  1. Converted generate_data function from sync to async (Error)
  2. Converted def list() function to async as well (Error)
  3. Tried to use sync_to_async utility function (Error)
Вернуться на верх