We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Django 3.1 async views do not work
When using sentry versions greater than 0.16.3, (tested on 0.18.0), Django 3.1 aysnc views do not work.

```
log.py                     224 ERROR    Internal Server Error: /async_ok
Traceback (most recent call last):
  File "/Users/williamchu/dev/sentry-python/.tox/py3.8-django-3.1/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/Users/williamchu/dev/sentry-python/.tox/py3.8-django-3.1/lib/python3.8/site-packages/django/core/handlers/base.py", line 186, in _get_response
    self.check_response(response, callback)
  File "/Users/williamchu/dev/sentry-python/.tox/py3.8-django-3.1/lib/python3.8/site-packages/django/core/handlers/base.py", line 312, in check_response
    raise ValueError(
ValueError: The view tests.integrations.django.myapp.views.async_ok didn't return an HttpResponse object. It returned an unawaited coroutine instead. You may need to add an 'await' into your view.
```

I have made a branch with a test case to demonstrate this: https://github.com/uptickmetachu/sentry-python/tree/django3.1-test-async-view



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `sentry_sdk/integrations/django/views.py`
Content:
```
1 from sentry_sdk.hub import Hub
2 from sentry_sdk._types import MYPY
3 from sentry_sdk import _functools
4 
5 if MYPY:
6     from typing import Any
7 
8 
9 def patch_views():
10     # type: () -> None
11 
12     from django.core.handlers.base import BaseHandler
13     from sentry_sdk.integrations.django import DjangoIntegration
14 
15     old_make_view_atomic = BaseHandler.make_view_atomic
16 
17     @_functools.wraps(old_make_view_atomic)
18     def sentry_patched_make_view_atomic(self, *args, **kwargs):
19         # type: (Any, *Any, **Any) -> Any
20         callback = old_make_view_atomic(self, *args, **kwargs)
21 
22         # XXX: The wrapper function is created for every request. Find more
23         # efficient way to wrap views (or build a cache?)
24 
25         hub = Hub.current
26         integration = hub.get_integration(DjangoIntegration)
27 
28         if integration is not None and integration.middleware_spans:
29 
30             @_functools.wraps(callback)
31             def sentry_wrapped_callback(request, *args, **kwargs):
32                 # type: (Any, *Any, **Any) -> Any
33                 with hub.start_span(
34                     op="django.view", description=request.resolver_match.view_name
35                 ):
36                     return callback(request, *args, **kwargs)
37 
38         else:
39             sentry_wrapped_callback = callback
40 
41         return sentry_wrapped_callback
42 
43     BaseHandler.make_view_atomic = sentry_patched_make_view_atomic
44
```

Path: `sentry_sdk/integrations/django/asgi.py`
Content:
```
1 """
2 Instrumentation for Django 3.0
3 
4 Since this file contains `async def` it is conditionally imported in
5 `sentry_sdk.integrations.django` (depending on the existence of
6 `django.core.handlers.asgi`.
7 """
8 
9 from sentry_sdk import Hub
10 from sentry_sdk._types import MYPY
11 
12 from sentry_sdk.integrations.django import DjangoIntegration
13 from sentry_sdk.integrations.asgi import SentryAsgiMiddleware
14 
15 if MYPY:
16     from typing import Any
17     from typing import Union
18 
19     from django.http.response import HttpResponse
20 
21 
22 def patch_django_asgi_handler_impl(cls):
23     # type: (Any) -> None
24     old_app = cls.__call__
25 
26     async def sentry_patched_asgi_handler(self, scope, receive, send):
27         # type: (Any, Any, Any, Any) -> Any
28         if Hub.current.get_integration(DjangoIntegration) is None:
29             return await old_app(self, scope, receive, send)
30 
31         middleware = SentryAsgiMiddleware(
32             old_app.__get__(self, cls), unsafe_context_data=True
33         )._run_asgi3
34         return await middleware(scope, receive, send)
35 
36     cls.__call__ = sentry_patched_asgi_handler
37 
38 
39 def patch_get_response_async(cls, _before_get_response):
40     # type: (Any, Any) -> None
41     old_get_response_async = cls.get_response_async
42 
43     async def sentry_patched_get_response_async(self, request):
44         # type: (Any, Any) -> Union[HttpResponse, BaseException]
45         _before_get_response(request)
46         return await old_get_response_async(self, request)
47 
48     cls.get_response_async = sentry_patched_get_response_async
49 
50 
51 def patch_channels_asgi_handler_impl(cls):
52     # type: (Any) -> None
53     old_app = cls.__call__
54 
55     async def sentry_patched_asgi_handler(self, receive, send):
56         # type: (Any, Any, Any) -> Any
57         if Hub.current.get_integration(DjangoIntegration) is None:
58             return await old_app(self, receive, send)
59 
60         middleware = SentryAsgiMiddleware(
61             lambda _scope: old_app.__get__(self, cls), unsafe_context_data=True
62         )
63 
64         return await middleware(self.scope)(receive, send)
65 
66     cls.__call__ = sentry_patched_asgi_handler
67
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/sentry_sdk/integrations/django/asgi.py b/sentry_sdk/integrations/django/asgi.py
--- a/sentry_sdk/integrations/django/asgi.py
+++ b/sentry_sdk/integrations/django/asgi.py
@@ -6,10 +6,9 @@
 `django.core.handlers.asgi`.
 """
 
-from sentry_sdk import Hub
+from sentry_sdk import Hub, _functools
 from sentry_sdk._types import MYPY
 
-from sentry_sdk.integrations.django import DjangoIntegration
 from sentry_sdk.integrations.asgi import SentryAsgiMiddleware
 
 if MYPY:
@@ -21,6 +20,9 @@
 
 def patch_django_asgi_handler_impl(cls):
     # type: (Any) -> None
+
+    from sentry_sdk.integrations.django import DjangoIntegration
+
     old_app = cls.__call__
 
     async def sentry_patched_asgi_handler(self, scope, receive, send):
@@ -50,6 +52,9 @@
 
 def patch_channels_asgi_handler_impl(cls):
     # type: (Any) -> None
+
+    from sentry_sdk.integrations.django import DjangoIntegration
+
     old_app = cls.__call__
 
     async def sentry_patched_asgi_handler(self, receive, send):
@@ -64,3 +69,17 @@
         return await middleware(self.scope)(receive, send)
 
     cls.__call__ = sentry_patched_asgi_handler
+
+
+def wrap_async_view(hub, callback):
+    # type: (Hub, Any) -> Any
+    @_functools.wraps(callback)
+    async def sentry_wrapped_callback(request, *args, **kwargs):
+        # type: (Any, *Any, **Any) -> Any
+
+        with hub.start_span(
+            op="django.view", description=request.resolver_match.view_name
+        ):
+            return await callback(request, *args, **kwargs)
+
+    return sentry_wrapped_callback
diff --git a/sentry_sdk/integrations/django/views.py b/sentry_sdk/integrations/django/views.py
--- a/sentry_sdk/integrations/django/views.py
+++ b/sentry_sdk/integrations/django/views.py
@@ -6,6 +6,18 @@
     from typing import Any
 
 
+try:
+    from asyncio import iscoroutinefunction
+except ImportError:
+    iscoroutinefunction = None  # type: ignore
+
+
+try:
+    from sentry_sdk.integrations.django.asgi import wrap_async_view
+except (ImportError, SyntaxError):
+    wrap_async_view = None  # type: ignore
+
+
 def patch_views():
     # type: () -> None
 
@@ -27,13 +39,14 @@
 
         if integration is not None and integration.middleware_spans:
 
-            @_functools.wraps(callback)
-            def sentry_wrapped_callback(request, *args, **kwargs):
-                # type: (Any, *Any, **Any) -> Any
-                with hub.start_span(
-                    op="django.view", description=request.resolver_match.view_name
-                ):
-                    return callback(request, *args, **kwargs)
+            if (
+                iscoroutinefunction is not None
+                and wrap_async_view is not None
+                and iscoroutinefunction(callback)
+            ):
+                sentry_wrapped_callback = wrap_async_view(hub, callback)
+            else:
+                sentry_wrapped_callback = _wrap_sync_view(hub, callback)
 
         else:
             sentry_wrapped_callback = callback
@@ -41,3 +54,16 @@
         return sentry_wrapped_callback
 
     BaseHandler.make_view_atomic = sentry_patched_make_view_atomic
+
+
+def _wrap_sync_view(hub, callback):
+    # type: (Hub, Any) -> Any
+    @_functools.wraps(callback)
+    def sentry_wrapped_callback(request, *args, **kwargs):
+        # type: (Any, *Any, **Any) -> Any
+        with hub.start_span(
+            op="django.view", description=request.resolver_match.view_name
+        ):
+            return callback(request, *args, **kwargs)
+
+    return sentry_wrapped_callback

{"golden_diff": "diff --git a/sentry_sdk/integrations/django/asgi.py b/sentry_sdk/integrations/django/asgi.py\n--- a/sentry_sdk/integrations/django/asgi.py\n+++ b/sentry_sdk/integrations/django/asgi.py\n@@ -6,10 +6,9 @@\n `django.core.handlers.asgi`.\n \"\"\"\n \n-from sentry_sdk import Hub\n+from sentry_sdk import Hub, _functools\n from sentry_sdk._types import MYPY\n \n-from sentry_sdk.integrations.django import DjangoIntegration\n from sentry_sdk.integrations.asgi import SentryAsgiMiddleware\n \n if MYPY:\n@@ -21,6 +20,9 @@\n \n def patch_django_asgi_handler_impl(cls):\n     # type: (Any) -> None\n+\n+    from sentry_sdk.integrations.django import DjangoIntegration\n+\n     old_app = cls.__call__\n \n     async def sentry_patched_asgi_handler(self, scope, receive, send):\n@@ -50,6 +52,9 @@\n \n def patch_channels_asgi_handler_impl(cls):\n     # type: (Any) -> None\n+\n+    from sentry_sdk.integrations.django import DjangoIntegration\n+\n     old_app = cls.__call__\n \n     async def sentry_patched_asgi_handler(self, receive, send):\n@@ -64,3 +69,17 @@\n         return await middleware(self.scope)(receive, send)\n \n     cls.__call__ = sentry_patched_asgi_handler\n+\n+\n+def wrap_async_view(hub, callback):\n+    # type: (Hub, Any) -> Any\n+    @_functools.wraps(callback)\n+    async def sentry_wrapped_callback(request, *args, **kwargs):\n+        # type: (Any, *Any, **Any) -> Any\n+\n+        with hub.start_span(\n+            op=\"django.view\", description=request.resolver_match.view_name\n+        ):\n+            return await callback(request, *args, **kwargs)\n+\n+    return sentry_wrapped_callback\ndiff --git a/sentry_sdk/integrations/django/views.py b/sentry_sdk/integrations/django/views.py\n--- a/sentry_sdk/integrations/django/views.py\n+++ b/sentry_sdk/integrations/django/views.py\n@@ -6,6 +6,18 @@\n     from typing import Any\n \n \n+try:\n+    from asyncio import iscoroutinefunction\n+except ImportError:\n+    iscoroutinefunction = None  # type: ignore\n+\n+\n+try:\n+    from sentry_sdk.integrations.django.asgi import wrap_async_view\n+except (ImportError, SyntaxError):\n+    wrap_async_view = None  # type: ignore\n+\n+\n def patch_views():\n     # type: () -> None\n \n@@ -27,13 +39,14 @@\n \n         if integration is not None and integration.middleware_spans:\n \n-            @_functools.wraps(callback)\n-            def sentry_wrapped_callback(request, *args, **kwargs):\n-                # type: (Any, *Any, **Any) -> Any\n-                with hub.start_span(\n-                    op=\"django.view\", description=request.resolver_match.view_name\n-                ):\n-                    return callback(request, *args, **kwargs)\n+            if (\n+                iscoroutinefunction is not None\n+                and wrap_async_view is not None\n+                and iscoroutinefunction(callback)\n+            ):\n+                sentry_wrapped_callback = wrap_async_view(hub, callback)\n+            else:\n+                sentry_wrapped_callback = _wrap_sync_view(hub, callback)\n \n         else:\n             sentry_wrapped_callback = callback\n@@ -41,3 +54,16 @@\n         return sentry_wrapped_callback\n \n     BaseHandler.make_view_atomic = sentry_patched_make_view_atomic\n+\n+\n+def _wrap_sync_view(hub, callback):\n+    # type: (Hub, Any) -> Any\n+    @_functools.wraps(callback)\n+    def sentry_wrapped_callback(request, *args, **kwargs):\n+        # type: (Any, *Any, **Any) -> Any\n+        with hub.start_span(\n+            op=\"django.view\", description=request.resolver_match.view_name\n+        ):\n+            return callback(request, *args, **kwargs)\n+\n+    return sentry_wrapped_callback\n", "issue": "Django 3.1 async views do not work\nWhen using sentry versions greater than 0.16.3, (tested on 0.18.0), Django 3.1 aysnc views do not work.\r\n\r\n```\r\nlog.py                     224 ERROR    Internal Server Error: /async_ok\r\nTraceback (most recent call last):\r\n  File \"/Users/williamchu/dev/sentry-python/.tox/py3.8-django-3.1/lib/python3.8/site-packages/django/core/handlers/exception.py\", line 47, in inner\r\n    response = get_response(request)\r\n  File \"/Users/williamchu/dev/sentry-python/.tox/py3.8-django-3.1/lib/python3.8/site-packages/django/core/handlers/base.py\", line 186, in _get_response\r\n    self.check_response(response, callback)\r\n  File \"/Users/williamchu/dev/sentry-python/.tox/py3.8-django-3.1/lib/python3.8/site-packages/django/core/handlers/base.py\", line 312, in check_response\r\n    raise ValueError(\r\nValueError: The view tests.integrations.django.myapp.views.async_ok didn't return an HttpResponse object. It returned an unawaited coroutine instead. You may need to add an 'await' into your view.\r\n```\r\n\r\nI have made a branch with a test case to demonstrate this: https://github.com/uptickmetachu/sentry-python/tree/django3.1-test-async-view\r\n\r\n\n", "before_files": [{"content": "from sentry_sdk.hub import Hub\nfrom sentry_sdk._types import MYPY\nfrom sentry_sdk import _functools\n\nif MYPY:\n    from typing import Any\n\n\ndef patch_views():\n    # type: () -> None\n\n    from django.core.handlers.base import BaseHandler\n    from sentry_sdk.integrations.django import DjangoIntegration\n\n    old_make_view_atomic = BaseHandler.make_view_atomic\n\n    @_functools.wraps(old_make_view_atomic)\n    def sentry_patched_make_view_atomic(self, *args, **kwargs):\n        # type: (Any, *Any, **Any) -> Any\n        callback = old_make_view_atomic(self, *args, **kwargs)\n\n        # XXX: The wrapper function is created for every request. Find more\n        # efficient way to wrap views (or build a cache?)\n\n        hub = Hub.current\n        integration = hub.get_integration(DjangoIntegration)\n\n        if integration is not None and integration.middleware_spans:\n\n            @_functools.wraps(callback)\n            def sentry_wrapped_callback(request, *args, **kwargs):\n                # type: (Any, *Any, **Any) -> Any\n                with hub.start_span(\n                    op=\"django.view\", description=request.resolver_match.view_name\n                ):\n                    return callback(request, *args, **kwargs)\n\n        else:\n            sentry_wrapped_callback = callback\n\n        return sentry_wrapped_callback\n\n    BaseHandler.make_view_atomic = sentry_patched_make_view_atomic\n", "path": "sentry_sdk/integrations/django/views.py"}, {"content": "\"\"\"\nInstrumentation for Django 3.0\n\nSince this file contains `async def` it is conditionally imported in\n`sentry_sdk.integrations.django` (depending on the existence of\n`django.core.handlers.asgi`.\n\"\"\"\n\nfrom sentry_sdk import Hub\nfrom sentry_sdk._types import MYPY\n\nfrom sentry_sdk.integrations.django import DjangoIntegration\nfrom sentry_sdk.integrations.asgi import SentryAsgiMiddleware\n\nif MYPY:\n    from typing import Any\n    from typing import Union\n\n    from django.http.response import HttpResponse\n\n\ndef patch_django_asgi_handler_impl(cls):\n    # type: (Any) -> None\n    old_app = cls.__call__\n\n    async def sentry_patched_asgi_handler(self, scope, receive, send):\n        # type: (Any, Any, Any, Any) -> Any\n        if Hub.current.get_integration(DjangoIntegration) is None:\n            return await old_app(self, scope, receive, send)\n\n        middleware = SentryAsgiMiddleware(\n            old_app.__get__(self, cls), unsafe_context_data=True\n        )._run_asgi3\n        return await middleware(scope, receive, send)\n\n    cls.__call__ = sentry_patched_asgi_handler\n\n\ndef patch_get_response_async(cls, _before_get_response):\n    # type: (Any, Any) -> None\n    old_get_response_async = cls.get_response_async\n\n    async def sentry_patched_get_response_async(self, request):\n        # type: (Any, Any) -> Union[HttpResponse, BaseException]\n        _before_get_response(request)\n        return await old_get_response_async(self, request)\n\n    cls.get_response_async = sentry_patched_get_response_async\n\n\ndef patch_channels_asgi_handler_impl(cls):\n    # type: (Any) -> None\n    old_app = cls.__call__\n\n    async def sentry_patched_asgi_handler(self, receive, send):\n        # type: (Any, Any, Any) -> Any\n        if Hub.current.get_integration(DjangoIntegration) is None:\n            return await old_app(self, receive, send)\n\n        middleware = SentryAsgiMiddleware(\n            lambda _scope: old_app.__get__(self, cls), unsafe_context_data=True\n        )\n\n        return await middleware(self.scope)(receive, send)\n\n    cls.__call__ = sentry_patched_asgi_handler\n", "path": "sentry_sdk/integrations/django/asgi.py"}], "after_files": [{"content": "from sentry_sdk.hub import Hub\nfrom sentry_sdk._types import MYPY\nfrom sentry_sdk import _functools\n\nif MYPY:\n    from typing import Any\n\n\ntry:\n    from asyncio import iscoroutinefunction\nexcept ImportError:\n    iscoroutinefunction = None  # type: ignore\n\n\ntry:\n    from sentry_sdk.integrations.django.asgi import wrap_async_view\nexcept (ImportError, SyntaxError):\n    wrap_async_view = None  # type: ignore\n\n\ndef patch_views():\n    # type: () -> None\n\n    from django.core.handlers.base import BaseHandler\n    from sentry_sdk.integrations.django import DjangoIntegration\n\n    old_make_view_atomic = BaseHandler.make_view_atomic\n\n    @_functools.wraps(old_make_view_atomic)\n    def sentry_patched_make_view_atomic(self, *args, **kwargs):\n        # type: (Any, *Any, **Any) -> Any\n        callback = old_make_view_atomic(self, *args, **kwargs)\n\n        # XXX: The wrapper function is created for every request. Find more\n        # efficient way to wrap views (or build a cache?)\n\n        hub = Hub.current\n        integration = hub.get_integration(DjangoIntegration)\n\n        if integration is not None and integration.middleware_spans:\n\n            if (\n                iscoroutinefunction is not None\n                and wrap_async_view is not None\n                and iscoroutinefunction(callback)\n            ):\n                sentry_wrapped_callback = wrap_async_view(hub, callback)\n            else:\n                sentry_wrapped_callback = _wrap_sync_view(hub, callback)\n\n        else:\n            sentry_wrapped_callback = callback\n\n        return sentry_wrapped_callback\n\n    BaseHandler.make_view_atomic = sentry_patched_make_view_atomic\n\n\ndef _wrap_sync_view(hub, callback):\n    # type: (Hub, Any) -> Any\n    @_functools.wraps(callback)\n    def sentry_wrapped_callback(request, *args, **kwargs):\n        # type: (Any, *Any, **Any) -> Any\n        with hub.start_span(\n            op=\"django.view\", description=request.resolver_match.view_name\n        ):\n            return callback(request, *args, **kwargs)\n\n    return sentry_wrapped_callback\n", "path": "sentry_sdk/integrations/django/views.py"}, {"content": "\"\"\"\nInstrumentation for Django 3.0\n\nSince this file contains `async def` it is conditionally imported in\n`sentry_sdk.integrations.django` (depending on the existence of\n`django.core.handlers.asgi`.\n\"\"\"\n\nfrom sentry_sdk import Hub, _functools\nfrom sentry_sdk._types import MYPY\n\nfrom sentry_sdk.integrations.asgi import SentryAsgiMiddleware\n\nif MYPY:\n    from typing import Any\n    from typing import Union\n\n    from django.http.response import HttpResponse\n\n\ndef patch_django_asgi_handler_impl(cls):\n    # type: (Any) -> None\n\n    from sentry_sdk.integrations.django import DjangoIntegration\n\n    old_app = cls.__call__\n\n    async def sentry_patched_asgi_handler(self, scope, receive, send):\n        # type: (Any, Any, Any, Any) -> Any\n        if Hub.current.get_integration(DjangoIntegration) is None:\n            return await old_app(self, scope, receive, send)\n\n        middleware = SentryAsgiMiddleware(\n            old_app.__get__(self, cls), unsafe_context_data=True\n        )._run_asgi3\n        return await middleware(scope, receive, send)\n\n    cls.__call__ = sentry_patched_asgi_handler\n\n\ndef patch_get_response_async(cls, _before_get_response):\n    # type: (Any, Any) -> None\n    old_get_response_async = cls.get_response_async\n\n    async def sentry_patched_get_response_async(self, request):\n        # type: (Any, Any) -> Union[HttpResponse, BaseException]\n        _before_get_response(request)\n        return await old_get_response_async(self, request)\n\n    cls.get_response_async = sentry_patched_get_response_async\n\n\ndef patch_channels_asgi_handler_impl(cls):\n    # type: (Any) -> None\n\n    from sentry_sdk.integrations.django import DjangoIntegration\n\n    old_app = cls.__call__\n\n    async def sentry_patched_asgi_handler(self, receive, send):\n        # type: (Any, Any, Any) -> Any\n        if Hub.current.get_integration(DjangoIntegration) is None:\n            return await old_app(self, receive, send)\n\n        middleware = SentryAsgiMiddleware(\n            lambda _scope: old_app.__get__(self, cls), unsafe_context_data=True\n        )\n\n        return await middleware(self.scope)(receive, send)\n\n    cls.__call__ = sentry_patched_asgi_handler\n\n\ndef wrap_async_view(hub, callback):\n    # type: (Hub, Any) -> Any\n    @_functools.wraps(callback)\n    async def sentry_wrapped_callback(request, *args, **kwargs):\n        # type: (Any, *Any, **Any) -> Any\n\n        with hub.start_span(\n            op=\"django.view\", description=request.resolver_match.view_name\n        ):\n            return await callback(request, *args, **kwargs)\n\n    return sentry_wrapped_callback\n", "path": "sentry_sdk/integrations/django/asgi.py"}]}