Skip to content

Commit 42af77a

Browse files
authored
FIX - renderer in some cases - _request not needed (#163)
1 parent 8a721ae commit 42af77a

File tree

2 files changed

+51
-36
lines changed

2 files changed

+51
-36
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ urlpatterns = [
191191
]
192192
```
193193

194-
Next, use `DEFAULT_RENDERER_CLASSES` in `settings.py` to manage the renderers you want to use. The `django_eventstream.renderers.SSEEventRenderer` is required to enable SSE functionality. If you also want the Browsable API view, add `django_eventstream.renderers.BrowsableAPIEventStreamRenderer`.
194+
Next, use `DEFAULT_RENDERER_CLASSES` in `settings.py` to manage the renderers you want to use. The `django_eventstream.renderers.SSEEventRenderer` is required to enable SSE functionality. If you also want the Browsable API view, add `django_eventstream.renderers.BrowsableAPIEventStreamRenderer`. By default they are define in the EventsViewSet class.
195195

196196
Example:
197197

django_eventstream/viewsets.py

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import logging
12
from django.conf import settings
23
from rest_framework.viewsets import ViewSet
34
from rest_framework.response import Response
@@ -10,6 +11,7 @@
1011
BrowsableAPIEventStreamRenderer,
1112
)
1213

14+
logger = logging.getLogger(__name__)
1315

1416
class EventsViewSet(ViewSet):
1517
"""
@@ -22,50 +24,64 @@ class EventsViewSet(ViewSet):
2224
- By setting the channel in the URL.
2325
Those three ways are mutually exclusive, so you can only use one of them.
2426
25-
If you want to see a specific type of messages and not the default "message" type, you can set the messages_types attribute in the class definition.
26-
That's the only way provided to set the messages types.
27+
If you want to see a specific type of messages and not the default "message" type, you can set the messages_types attribute in the class definition or by using the configure_events_view_set method.
28+
That's the only ways provided to set the messages types.
2729
"""
2830

2931
http_method_names = ["get"]
3032
renderer_classes = (BrowsableAPIEventStreamRenderer, SSEEventRenderer)
3133

32-
no_api_sse_renderer = False
34+
api_sse_renderer_available = True
3335

34-
def __init__(
35-
self, channels: list = None, messages_types: list = None, *args, **kwargs
36-
):
36+
def __init__(self, channels: list = None, messages_types: list = None, *args, **kwargs):
3737
super().__init__()
3838
self.channels = channels if channels is not None else []
3939
self.messages_types = messages_types if messages_types is not None else []
40-
self._api_sse = False
40+
self._api_sse = True
4141

4242
def get_renderers(self):
43-
if hasattr(settings, "REST_FRAMEWORK"):
44-
api_settings = APISettings(
45-
user_settings=settings.REST_FRAMEWORK,
46-
defaults=None,
47-
import_strings=None,
48-
)
49-
default_renderers = list(api_settings.DEFAULT_RENDERER_CLASSES)
50-
51-
sse_renderers = []
52-
api_sse_renderers = []
53-
54-
for renderer_class in default_renderers:
55-
renderer_instance = renderer_class()
56-
if renderer_instance.format == "api_sse":
57-
api_sse_renderers.append(renderer_class)
58-
self._api_sse = True
59-
if renderer_instance.format == "text/event-stream":
60-
sse_renderers.append(renderer_class)
61-
62-
if len(api_sse_renderers) == 0:
63-
self.no_api_sse_renderer = True
43+
try:
44+
if hasattr(settings, "REST_FRAMEWORK") and "DEFAULT_RENDERER_CLASSES" in settings.REST_FRAMEWORK:
45+
api_settings = APISettings(
46+
user_settings=settings.REST_FRAMEWORK,
47+
defaults=None,
48+
import_strings=None,
49+
)
50+
default_renderers = list(api_settings.DEFAULT_RENDERER_CLASSES)
6451
else:
65-
self.no_api_sse_renderer = False
66-
67-
self.renderer_classes = api_sse_renderers + sse_renderers
68-
52+
default_renderers = []
53+
54+
if default_renderers:
55+
56+
sse_renderers = []
57+
api_sse_renderers = []
58+
self._api_sse = False
59+
60+
for renderer_class in default_renderers:
61+
try:
62+
renderer_instance = renderer_class()
63+
if renderer_instance.format == "api_sse":
64+
api_sse_renderers.append(renderer_class)
65+
self._api_sse = True
66+
if renderer_instance.format == "text/event-stream":
67+
sse_renderers.append(renderer_class)
68+
except Exception as e:
69+
logger.error(f"Failed to initialize renderer {renderer_class}: {e}")
70+
71+
if not api_sse_renderers:
72+
self.api_sse_renderer_available = False
73+
else:
74+
self.api_sse_renderer_available = True
75+
76+
self.renderer_classes = api_sse_renderers + sse_renderers
77+
except Exception as e:
78+
logger.error(f"Error in get_renderers: {e}")
79+
self.renderer_classes = []
80+
logger.info(f"renderer_classes: {self.renderer_classes}")
81+
82+
if not self.renderer_classes:
83+
logger.warning(f"No renderers are available for the viewset named {self.__class__.__name__} ")
84+
6985
return super().get_renderers()
7086

7187
def list(self, request):
@@ -107,15 +123,14 @@ def channel(self, request, channel=None):
107123
},
108124
status=status.HTTP_400_BAD_REQUEST,
109125
)
110-
return self._stream_or_respond([channel], request._request)
126+
return self._stream_or_respond([channel], request)
111127

112128
def _accepted_format(self, request, format_list):
113129
accept_header = request.META.get("HTTP_ACCEPT", "")
114130
query_format = request.GET.get("format", "")
115131
return any(fmt in accept_header or fmt in query_format for fmt in format_list)
116132

117-
def _stream_or_respond(self, channels, django_request):
118-
request = django_request._request
133+
def _stream_or_respond(self, channels, request):
119134
messages_types = self.messages_types if self.messages_types else ["message"]
120135
data = {
121136
"channels": ", ".join(channels),

0 commit comments

Comments
 (0)