Django StreamingHttpResponse передает потоки локально, но не в производстве

Я размещаю этот вопрос после долгих исследований, но не получил ни одного решения, которое бы мне помогло. Я не знаю, что я делаю неправильно, так как я новичок в Django

Ниже приведена моя кодовая база для stream.py

import json
from django.http import StreamingHttpResponse
from decimal import Decimal

class DecimalEncoder(json.JSONEncoder):
   
    def default(self, obj):        
        if isinstance(obj, Decimal):
            return str(obj)  # or float(obj)
        return super(DecimalEncoder, self).default(obj)

class StreamResponseMixin:   
    def stream_response(self, queryset, serializer_class, gen_message_func=None):
        
        def generate_stream():
            for item in queryset:
                serializer = serializer_class(item)
                yield self.gen_message(serializer.data, gen_message_func)

        response = StreamingHttpResponse(generate_stream(), content_type='text/event-stream')
        response['X-Accel-Buffering'] = 'no'  # Disable buffering in nginx
        response['Cache-Control'] = 'no-cache'  # Ensure clients don't cache the data
        response['Transfer-Encoding'] = 'chunked'
        return response

    def gen_message(self, data, gen_message_func=None):
       
        if gen_message_func:
            return gen_message_func(data)
        return '{}\n'.format(json.dumps(data, cls=DecimalEncoder)) # Default behavior if no custom message generator is provided

Views.py

class PackageViewSet(viewsets.ModelViewSet, StreamResponseMixin):
   
    queryset = Package.objects.all().order_by('-created_at')

    def get_serializer_class(self):
        if self.action in ['list', 'modified']:
            return PackageListSerializer
        return PackageDetailSerializer

    def get_queryset(self):
        user = self.request.user
        package_queryset = Package.objects.all().order_by('-created_at')

        package_queryset = package_queryset.select_related('customer', 'creator').prefetch_related(
            Prefetch('products', queryset=Product.objects.all()),
        )

        try:
            customer = Customer.objects.get(user=user)
            package_queryset = package_queryset.filter(customer=customer)
        except ObjectDoesNotExist:
            pass

        return package_queryset

    @action(detail=False, methods=['GET'], url_path='stream-packages')
    def get_stream(self, *args, **kwargs):
        packages = self.get_queryset().iterator(chunk_size=50)
        return self.stream_response(queryset=packages, serializer_class=PackageListSerializer)

nginx.conf

server {
        listen 443 ssl;
        server_name abc.api.ai;

        ssl_certificate /etc/letsencrypt/live/abc.api.ai/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/abc.api.ai/privkey.pem;

        location / {
            if ($internal_ips = 0) {
                return 403;
            }
            proxy_pass http://abc-backend-staging:8000;
            include proxy.conf;
        }
        location /api/packages/stream-packages/ {
            proxy_pass http://abc-backend-staging:8000;
            include proxy.conf;
            proxy_http_version 1.1;
            proxy_set_header Connection "";
            chunked_transfer_encoding on;
            proxy_buffering off;
            proxy_request_buffering off;
        }
    }

proxy.conf, который включен в nginx.conf

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto "https";

entrypoint.sh, поскольку мое приложение развертывается через контейнер docker

exec poetry run uvicorn myapplication.asgi:application --host 0.0.0.0 --port 8000

Я не знаю, чего мне не хватает, хотя на localhost он работает, но не в production.

Я пробовал различные решения по настройке Nginx, размещенные на Github, StackOverflow и официальном форуме Django, но ни одно из них не сработало в моем случае. Однако в большинстве случаев решением была установка "proxy_buffering off", но и она не сработала в моем случае.

Я столкнулся с той же проблемой, что и здесь, но предоставленное решение не работает в моем случае

Дополнительно для некоторых конечных точек API он отображает данные после получения всех за один раз, а для некоторых даже не отправляет их, поскольку конечные точки содержат больше данных по сравнению с другими.

Сейчас я чувствую себя подавленным после того, как потратил несколько дней на решение этой проблемы. Любая помощь будет очень признательна.

Спасибо!

Вернуться на верх