Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft: Add warning async is not supported #1911

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions debug_toolbar/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
from debug_toolbar.toolbar import DebugToolbar
from debug_toolbar.utils import clear_stack_trace_caches

try:
from django.core.handlers.asgi import ASGIRequest
except ImportError:
ASGIRequest = None

_HTML_TYPES = ("text/html", "application/xhtml+xml")


Expand Down Expand Up @@ -73,6 +78,10 @@ def __call__(self, request):
if not show_toolbar(request) or DebugToolbar.is_toolbar_request(request):
return self.get_response(request)

if self._check_async_request(request):
self._show_async_request_is_not_supported()
return self.get_response(request)

toolbar = DebugToolbar(request, self.get_response)

# Activate instrumentation ie. monkey-patch.
Expand Down Expand Up @@ -133,3 +142,12 @@ def get_headers(request, panels):
else:
headers[header] = value
return headers

def _check_async_request(self, request) -> bool:
return type(request) == ASGIRequest

@staticmethod
def _show_async_request_is_not_supported():
print("-" * 10)
print("Be caution, django-debug-toolbar does not support async requests!")
print("-" * 10)
1 change: 1 addition & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Pending

* Changed ordering (and grammatical number) of panels and their titles in
documentation to match actual panel ordering and titles.
* Added warning "async is not supported"

4.4.5 (2024-07-05)
------------------
Expand Down
51 changes: 51 additions & 0 deletions tests/test_integration.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import io
import os
import re
import sys
import time
import unittest
from unittest.mock import patch
Expand Down Expand Up @@ -33,6 +35,12 @@
webdriver = None


try:
from django.test import AsyncRequestFactory
except ImportError:
AsyncRequestFactory = None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AsyncRequestFactory is defined in Django >= v3.1 so the ImportError should not happen on all supported versions of Django.

Just modify line 16 to read from django.test import AsyncRequestFactory, RequestFactory



rf = RequestFactory()


Expand Down Expand Up @@ -843,3 +851,46 @@ def test_theme_toggle(self):
self.get("/regular/basic/")
toolbar = self.selenium.find_element(By.ID, "djDebug")
self.assertEqual(toolbar.get_attribute("data-theme"), "light")


Copy link
Contributor

@cclauss cclauss Jul 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
from django.test import AsyncRequestFactory

https://docs.djangoproject.com/en/stable/topics/testing/advanced/#asyncrequestfactory

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the tip

Copy link
Contributor

@cclauss cclauss Jul 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You must move that line up near the top of the file with the other imports.

Modify line 16 to read from django.test import AsyncRequestFactory, RequestFactory

@unittest.skipUnless(
AsyncRequestFactory is not None, "Test valid only for django with async requests"
)
@override_settings(DEBUG=True)
class DebugToolbarAsyncTestCase(BaseTestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.async_rf = AsyncRequestFactory()
cls.simple_get_response = lambda *args, **kwargs: HttpResponse(
"<html><body></body></html>"
)
cls._default_stdout = sys.stdout

def setUp(self):
super().setUp()
self.captured_output = io.StringIO()
sys.stdout = self.captured_output

@classmethod
def tearDownClass(cls):
super().tearDownClass()
sys.stdout = cls._default_stdout

def test_do_not_render_toolbar_if_it_was_async_request(self):
captured_output = io.StringIO()
sys.stdout = captured_output

request = self.async_rf.get("/")
response = DebugToolbarMiddleware(self.simple_get_response)(request)

self.assertEqual(response.content, b"<html><body></body></html>")

def test_prints_warning_async_is_not_supported(self):
request = self.async_rf.get("/")
DebugToolbarMiddleware(self.simple_get_response)(request)

assert (
self.captured_output.getvalue()
== "----------\nBe caution, django-debug-toolbar does not support async requests!\n----------\n"
)