posthoganalytics 6.7.4__py3-none-any.whl → 6.7.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,18 @@
1
1
  from typing import TYPE_CHECKING, cast
2
- from posthoganalytics import contexts, capture_exception
2
+ from posthoganalytics import contexts
3
3
  from posthoganalytics.client import Client
4
4
 
5
+ try:
6
+ from asgiref.sync import iscoroutinefunction
7
+ except ImportError:
8
+ # Fallback for older Django versions
9
+ import asyncio
10
+
11
+ iscoroutinefunction = asyncio.iscoroutinefunction
12
+
5
13
  if TYPE_CHECKING:
6
14
  from django.http import HttpRequest, HttpResponse # noqa: F401
7
- from typing import Callable, Dict, Any, Optional # noqa: F401
15
+ from typing import Callable, Dict, Any, Optional, Union, Awaitable # noqa: F401
8
16
 
9
17
 
10
18
  class PosthogContextMiddleware:
@@ -33,9 +41,24 @@ class PosthogContextMiddleware:
33
41
  frontend. See the documentation for `set_context_session` and `identify_context` for more details.
34
42
  """
35
43
 
44
+ # Django middleware capability flags
45
+ sync_capable = True
46
+ async_capable = True
47
+
36
48
  def __init__(self, get_response):
37
- # type: (Callable[[HttpRequest], HttpResponse]) -> None
38
- self.get_response = get_response
49
+ # type: (Union[Callable[[HttpRequest], HttpResponse], Callable[[HttpRequest], Awaitable[HttpResponse]]]) -> None
50
+ self._is_coroutine = iscoroutinefunction(get_response)
51
+ self._async_get_response = None # type: Optional[Callable[[HttpRequest], Awaitable[HttpResponse]]]
52
+ self._sync_get_response = None # type: Optional[Callable[[HttpRequest], HttpResponse]]
53
+
54
+ if self._is_coroutine:
55
+ self._async_get_response = cast(
56
+ "Callable[[HttpRequest], Awaitable[HttpResponse]]", get_response
57
+ )
58
+ else:
59
+ self._sync_get_response = cast(
60
+ "Callable[[HttpRequest], HttpResponse]", get_response
61
+ )
39
62
 
40
63
  from django.conf import settings
41
64
 
@@ -159,23 +182,39 @@ class PosthogContextMiddleware:
159
182
 
160
183
  def __call__(self, request):
161
184
  # type: (HttpRequest) -> HttpResponse
185
+ # Purely defensive around django's internal sync/async handling - this should be unreachable, but if it's reached, we may
186
+ # as well return something semi-meaningful
187
+ if self._is_coroutine:
188
+ raise RuntimeError(
189
+ "PosthogContextMiddleware received sync call but get_response is async"
190
+ )
191
+
162
192
  if self.request_filter and not self.request_filter(request):
163
- return self.get_response(request)
193
+ assert self._sync_get_response is not None
194
+ return self._sync_get_response(request)
164
195
 
165
196
  with contexts.new_context(self.capture_exceptions, client=self.client):
166
197
  for k, v in self.extract_tags(request).items():
167
198
  contexts.tag(k, v)
168
199
 
169
- return self.get_response(request)
200
+ assert self._sync_get_response is not None
201
+ return self._sync_get_response(request)
170
202
 
171
- def process_exception(self, request, exception):
203
+ async def __acall__(self, request):
204
+ # type: (HttpRequest) -> HttpResponse
172
205
  if self.request_filter and not self.request_filter(request):
173
- return
206
+ if self._async_get_response is not None:
207
+ return await self._async_get_response(request)
208
+ else:
209
+ assert self._sync_get_response is not None
210
+ return self._sync_get_response(request)
174
211
 
175
- if not self.capture_exceptions:
176
- return
212
+ with contexts.new_context(self.capture_exceptions, client=self.client):
213
+ for k, v in self.extract_tags(request).items():
214
+ contexts.tag(k, v)
177
215
 
178
- if self.client:
179
- self.client.capture_exception(exception)
180
- else:
181
- capture_exception(exception)
216
+ if self._async_get_response is not None:
217
+ return await self._async_get_response(request)
218
+ else:
219
+ assert self._sync_get_response is not None
220
+ return self._sync_get_response(request)
@@ -1,4 +1,4 @@
1
- VERSION = "6.7.4"
1
+ VERSION = "6.7.5"
2
2
 
3
3
  if __name__ == "__main__":
4
4
  print(VERSION, end="") # noqa: T201
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: posthoganalytics
3
- Version: 6.7.4
3
+ Version: 6.7.5
4
4
  Summary: Integrate PostHog into any python application.
5
5
  Home-page: https://github.com/posthog/posthog-python
6
6
  Author: Posthog
@@ -11,7 +11,7 @@ posthoganalytics/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  posthoganalytics/request.py,sha256=Bsl2c5WwONKPQzwWMmKPX5VgOlwSiIcSNfhXgoz62Y8,6186
12
12
  posthoganalytics/types.py,sha256=Dl3aFGX9XUR0wMmK12r2s5Hjan9jL4HpQ9GHpVcEq5U,10207
13
13
  posthoganalytics/utils.py,sha256=-0w-OLcCaoldkbBebPzQyBzLJSo9G9yBOg8NDVz7La8,16088
14
- posthoganalytics/version.py,sha256=RJbegcgNmUJvUzvz3PhJ7kXrYNUcMXmEqH9X-ctDffs,87
14
+ posthoganalytics/version.py,sha256=p6CR99e3yuHdETbfkJWyHc3CWzU3vZ-LjbWAbp1Noh0,87
15
15
  posthoganalytics/ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  posthoganalytics/ai/sanitization.py,sha256=owipZ4eJYtd4JTI-CM_klatclXaeaIec3XJBOUfsOnQ,5770
17
17
  posthoganalytics/ai/types.py,sha256=ceubs4K9xf8vQx7wokq1NL9hPtxyS7D7sUOuT7Lx1lM,3237
@@ -32,7 +32,7 @@ posthoganalytics/ai/openai/openai_async.py,sha256=k6bo3LfJ_CAPBZCxAzyM2uLz4BpW2Y
32
32
  posthoganalytics/ai/openai/openai_converter.py,sha256=VBaAGdXPSVNgfvCnSAojslWkTRO2luUxpjafR-WMEbs,20469
33
33
  posthoganalytics/ai/openai/openai_providers.py,sha256=RPVmj2V0_lAdno_ax5Ul2kwhBA9_rRgAdl_sCqrQc6M,4004
34
34
  posthoganalytics/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
- posthoganalytics/integrations/django.py,sha256=KYtBr7CkiZQynRc2TCWWYHe-J3ie8iSUa42WPshYZdc,6795
35
+ posthoganalytics/integrations/django.py,sha256=DJ5qz_vWspJX2MK3rnE3_HCydwa0PSKMK8ItIpRGUYU,8637
36
36
  posthoganalytics/test/__init__.py,sha256=VYgM6xPbJbvS-xhIcDiBRs0MFC9V_jT65uNeerCz_rM,299
37
37
  posthoganalytics/test/test_before_send.py,sha256=A1_UVMewhHAvO39rZDWfS606vG_X-q0KNXvh5DAKiB8,7930
38
38
  posthoganalytics/test/test_client.py,sha256=rb_y0HbaxDbS5P4WrG0ked1ZEYUK0G7ooxljRkmIONI,94495
@@ -47,8 +47,8 @@ posthoganalytics/test/test_request.py,sha256=Zc0VbkjpVmj8mKokQm9rzdgTr0b1U44vvMY
47
47
  posthoganalytics/test/test_size_limited_dict.py,sha256=-5IQjIEr_-Dql24M0HusdR_XroOMrtgiT0v6ZQCRvzo,774
48
48
  posthoganalytics/test/test_types.py,sha256=bRPHdwVpP7hu7emsplU8UVyzSQptv6PaG5lAoOD_BtM,7595
49
49
  posthoganalytics/test/test_utils.py,sha256=sqUTbfweVcxxFRd3WDMFXqPMyU6DvzOBeAOc68Py9aw,9620
50
- posthoganalytics-6.7.4.dist-info/licenses/LICENSE,sha256=wGf9JBotDkSygFj43m49oiKlFnpMnn97keiZKF-40vE,2450
51
- posthoganalytics-6.7.4.dist-info/METADATA,sha256=krO8eciyydNJ2LzkNv59_maYsYxnnT4XpvZ_n6FCi44,6024
52
- posthoganalytics-6.7.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
53
- posthoganalytics-6.7.4.dist-info/top_level.txt,sha256=8QsNIqIkBh1p2TXvKp0Em9ZLZKwe3uIqCETyW4s1GOE,17
54
- posthoganalytics-6.7.4.dist-info/RECORD,,
50
+ posthoganalytics-6.7.5.dist-info/licenses/LICENSE,sha256=wGf9JBotDkSygFj43m49oiKlFnpMnn97keiZKF-40vE,2450
51
+ posthoganalytics-6.7.5.dist-info/METADATA,sha256=peQQZXVtHcDFD1kFIuKu7oes7PvXmtSCpL-sPllc6KY,6024
52
+ posthoganalytics-6.7.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
53
+ posthoganalytics-6.7.5.dist-info/top_level.txt,sha256=8QsNIqIkBh1p2TXvKp0Em9ZLZKwe3uIqCETyW4s1GOE,17
54
+ posthoganalytics-6.7.5.dist-info/RECORD,,