Skip to content

Commit fe7f007

Browse files
authored
Merge pull request #53 from dabapps/async
Add support for async views
2 parents d87bfce + 6e17bfb commit fe7f007

File tree

5 files changed

+65
-36
lines changed

5 files changed

+65
-36
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ jobs:
99

1010
strategy:
1111
matrix:
12-
python: [3.6, 3.7, 3.8]
13-
django: [1.8, 1.11, 2.2, 3.1]
12+
python: [3.6, 3.7, 3.8, 3.9]
13+
django: [2.2, 3.0, 3.1, 3.2]
1414

1515
steps:
1616
- uses: actions/checkout@v2

log_request_id/__init__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@
33
__version__ = "1.6.0"
44

55

6-
local = threading.local()
6+
try:
7+
from asgiref.local import Local
8+
except ImportError:
9+
from threading import local as Local
10+
11+
12+
local = Local()
713

814

915
REQUEST_ID_HEADER_SETTING = 'LOG_REQUEST_ID_HEADER'

log_request_id/tests.py

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
import logging
22

3+
try:
4+
from asgiref.sync import async_to_sync
5+
except ImportError:
6+
async_to_sync = None
7+
38
from django.core.exceptions import ImproperlyConfigured
49
from django.test import RequestFactory, TestCase, override_settings
510
from requests import Request
611

712
from log_request_id import DEFAULT_NO_REQUEST_ID, local
813
from log_request_id.session import Session
914
from log_request_id.middleware import RequestIDMiddleware
10-
from testproject.views import test_view
15+
from testproject.views import test_view, test_async_view
1116

1217

1318
class RequestIDLoggingTestCase(TestCase):
19+
url = "/"
20+
21+
def call_view(self, request):
22+
return test_view(request)
1423

1524
def setUp(self):
1625
self.factory = RequestFactory()
@@ -24,41 +33,41 @@ def setUp(self):
2433
pass
2534

2635
def test_id_generation(self):
27-
request = self.factory.get('/')
36+
request = self.factory.get(self.url)
2837
middleware = RequestIDMiddleware()
2938
middleware.process_request(request)
3039
self.assertTrue(hasattr(request, 'id'))
31-
test_view(request)
40+
self.call_view(request)
3241
self.assertTrue(request.id in self.handler.messages[0])
3342

3443
def test_external_id_in_http_header(self):
3544
with self.settings(LOG_REQUEST_ID_HEADER='REQUEST_ID_HEADER'):
36-
request = self.factory.get('/')
45+
request = self.factory.get(self.url)
3746
request.META['REQUEST_ID_HEADER'] = 'some_request_id'
3847
middleware = RequestIDMiddleware()
3948
middleware.process_request(request)
4049
self.assertEqual(request.id, 'some_request_id')
41-
test_view(request)
50+
self.call_view(request)
4251
self.assertTrue('some_request_id' in self.handler.messages[0])
4352

4453
def test_default_no_request_id_is_used(self):
45-
request = self.factory.get('/')
46-
test_view(request)
54+
request = self.factory.get(self.url)
55+
self.call_view(request)
4756
self.assertTrue(DEFAULT_NO_REQUEST_ID in self.handler.messages[0])
4857

4958
@override_settings(NO_REQUEST_ID='-')
5059
def test_custom_request_id_is_used(self):
51-
request = self.factory.get('/')
52-
test_view(request)
60+
request = self.factory.get(self.url)
61+
self.call_view(request)
5362
self.assertTrue('[-]' in self.handler.messages[0])
5463

5564
def test_external_id_missing_in_http_header_should_fallback_to_generated_id(self):
5665
with self.settings(LOG_REQUEST_ID_HEADER='REQUEST_ID_HEADER', GENERATE_REQUEST_ID_IF_NOT_IN_HEADER=True):
57-
request = self.factory.get('/')
66+
request = self.factory.get(self.url)
5867
middleware = RequestIDMiddleware()
5968
middleware.process_request(request)
6069
self.assertTrue(hasattr(request, 'id'))
61-
test_view(request)
70+
self.call_view(request)
6271
self.assertTrue(request.id in self.handler.messages[0])
6372

6473
def test_log_requests(self):
@@ -67,11 +76,11 @@ class DummyUser(object):
6776
pk = 'fake_pk'
6877

6978
with self.settings(LOG_REQUESTS=True):
70-
request = self.factory.get('/')
79+
request = self.factory.get(self.url)
7180
request.user = DummyUser()
7281
middleware = RequestIDMiddleware()
7382
middleware.process_request(request)
74-
response = test_view(request)
83+
response = self.call_view(request)
7584
middleware.process_response(request, response)
7685
self.assertEqual(len(self.handler.messages), 2)
7786
self.assertTrue('fake_pk' in self.handler.messages[1])
@@ -83,42 +92,44 @@ class DummyUser(object):
8392
username = 'fake_username'
8493

8594
with self.settings(LOG_REQUESTS=True, LOG_USER_ATTRIBUTE='username'):
86-
request = self.factory.get('/')
95+
request = self.factory.get(self.url)
8796
request.user = DummyUser()
8897
middleware = RequestIDMiddleware()
8998
middleware.process_request(request)
90-
response = test_view(request)
99+
response = self.call_view(request)
91100
middleware.process_response(request, response)
92101
self.assertEqual(len(self.handler.messages), 2)
93102
self.assertTrue('fake_username' in self.handler.messages[1])
94103

95104
def test_response_header_unset(self):
96105
with self.settings(LOG_REQUEST_ID_HEADER='REQUEST_ID_HEADER'):
97-
request = self.factory.get('/')
106+
request = self.factory.get(self.url)
98107
request.META['REQUEST_ID_HEADER'] = 'some_request_id'
99108
middleware = RequestIDMiddleware()
100109
middleware.process_request(request)
101-
response = test_view(request)
110+
response = self.call_view(request)
102111
self.assertFalse(response.has_header('REQUEST_ID'))
103112

104113
def test_response_header_set(self):
105114
with self.settings(LOG_REQUEST_ID_HEADER='REQUEST_ID_HEADER', REQUEST_ID_RESPONSE_HEADER='REQUEST_ID'):
106-
request = self.factory.get('/')
115+
request = self.factory.get(self.url)
107116
request.META['REQUEST_ID_HEADER'] = 'some_request_id'
108117
middleware = RequestIDMiddleware()
109118
middleware.process_request(request)
110-
response = test_view(request)
119+
response = self.call_view(request)
111120
middleware.process_response(request, response)
112121
self.assertTrue(response.has_header('REQUEST_ID'))
113122

114123

115124
class RequestIDPassthroughTestCase(TestCase):
125+
url = "/"
126+
116127
def setUp(self):
117128
self.factory = RequestFactory()
118129

119130
def test_request_id_passthrough_with_custom_header(self):
120131
with self.settings(LOG_REQUEST_ID_HEADER='REQUEST_ID_HEADER', OUTGOING_REQUEST_ID_HEADER='OUTGOING_REQUEST_ID_HEADER'):
121-
request = self.factory.get('/')
132+
request = self.factory.get(self.url)
122133
request.META['REQUEST_ID_HEADER'] = 'some_request_id'
123134
middleware = RequestIDMiddleware()
124135
middleware.process_request(request)
@@ -133,7 +144,7 @@ def test_request_id_passthrough_with_custom_header(self):
133144

134145
def test_request_id_passthrough(self):
135146
with self.settings(LOG_REQUEST_ID_HEADER='REQUEST_ID_HEADER'):
136-
request = self.factory.get('/')
147+
request = self.factory.get(self.url)
137148
request.META['REQUEST_ID_HEADER'] = 'some_request_id'
138149
middleware = RequestIDMiddleware()
139150
middleware.process_request(request)
@@ -150,3 +161,17 @@ def test_misconfigured_for_sessions(self):
150161
def inner():
151162
Session()
152163
self.assertRaises(ImproperlyConfigured, inner)
164+
165+
166+
# asgiref is required from Django 3.0
167+
if async_to_sync:
168+
169+
class AsyncRequestIDLoggingTestCase(RequestIDLoggingTestCase):
170+
url = "/async/"
171+
172+
def call_view(self, request):
173+
return async_to_sync(test_async_view)(request)
174+
175+
176+
class AsyncRequestIDPassthroughTestCase(RequestIDPassthroughTestCase):
177+
url = "/async/"

testproject/urls.py

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
1-
import django
1+
from django.urls import path
22
from testproject import views
33

4-
if django.VERSION < (1, 9):
5-
from django.conf.urls import patterns, url
6-
urlpatterns = patterns(
7-
'',
8-
url(r'^$', views.test_view),
9-
)
104

11-
else:
12-
from django.conf.urls import url
13-
urlpatterns = [
14-
url(r'^$', views.test_view),
15-
]
5+
urlpatterns = [
6+
path("", views.test_view),
7+
path("async/", views.test_async_view),
8+
]

testproject/views.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,8 @@
88
def test_view(request):
99
logger.debug("A wild log message appears!")
1010
return HttpResponse('ok')
11+
12+
13+
async def test_async_view(request):
14+
logger.debug("An async log message appears")
15+
return HttpResponse('ok')

0 commit comments

Comments
 (0)