posthoganalytics 6.2.1__py3-none-any.whl → 6.3.0__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.
@@ -33,7 +33,7 @@ from langchain_core.messages import (
33
33
  from langchain_core.outputs import ChatGeneration, LLMResult
34
34
  from pydantic import BaseModel
35
35
 
36
- from posthoganalytics import default_client
36
+ from posthoganalytics import setup
37
37
  from posthoganalytics.ai.utils import get_model_params, with_privacy_mode
38
38
  from posthoganalytics.client import Client
39
39
 
@@ -81,7 +81,7 @@ class CallbackHandler(BaseCallbackHandler):
81
81
  The PostHog LLM observability callback handler for LangChain.
82
82
  """
83
83
 
84
- _client: Client
84
+ _ph_client: Client
85
85
  """PostHog client instance."""
86
86
 
87
87
  _distinct_id: Optional[Union[str, int, UUID]]
@@ -127,10 +127,7 @@ class CallbackHandler(BaseCallbackHandler):
127
127
  privacy_mode: Whether to redact the input and output of the trace.
128
128
  groups: Optional additional PostHog groups to use for the trace.
129
129
  """
130
- posthog_client = client or default_client
131
- if posthog_client is None:
132
- raise ValueError("PostHog client is required")
133
- self._client = posthog_client
130
+ self._ph_client = client or setup()
134
131
  self._distinct_id = distinct_id
135
132
  self._trace_id = trace_id
136
133
  self._properties = properties or {}
@@ -481,7 +478,7 @@ class CallbackHandler(BaseCallbackHandler):
481
478
  event_properties = {
482
479
  "$ai_trace_id": trace_id,
483
480
  "$ai_input_state": with_privacy_mode(
484
- self._client, self._privacy_mode, run.input
481
+ self._ph_client, self._privacy_mode, run.input
485
482
  ),
486
483
  "$ai_latency": run.latency,
487
484
  "$ai_span_name": run.name,
@@ -497,13 +494,13 @@ class CallbackHandler(BaseCallbackHandler):
497
494
  event_properties["$ai_is_error"] = True
498
495
  elif outputs is not None:
499
496
  event_properties["$ai_output_state"] = with_privacy_mode(
500
- self._client, self._privacy_mode, outputs
497
+ self._ph_client, self._privacy_mode, outputs
501
498
  )
502
499
 
503
500
  if self._distinct_id is None:
504
501
  event_properties["$process_person_profile"] = False
505
502
 
506
- self._client.capture(
503
+ self._ph_client.capture(
507
504
  distinct_id=self._distinct_id or run_id,
508
505
  event=event_name,
509
506
  properties=event_properties,
@@ -550,14 +547,16 @@ class CallbackHandler(BaseCallbackHandler):
550
547
  "$ai_provider": run.provider,
551
548
  "$ai_model": run.model,
552
549
  "$ai_model_parameters": run.model_params,
553
- "$ai_input": with_privacy_mode(self._client, self._privacy_mode, run.input),
550
+ "$ai_input": with_privacy_mode(
551
+ self._ph_client, self._privacy_mode, run.input
552
+ ),
554
553
  "$ai_http_status": 200,
555
554
  "$ai_latency": run.latency,
556
555
  "$ai_base_url": run.base_url,
557
556
  }
558
557
  if run.tools:
559
558
  event_properties["$ai_tools"] = with_privacy_mode(
560
- self._client,
559
+ self._ph_client,
561
560
  self._privacy_mode,
562
561
  run.tools,
563
562
  )
@@ -589,7 +588,7 @@ class CallbackHandler(BaseCallbackHandler):
589
588
  _extract_raw_esponse(generation) for generation in generation_result
590
589
  ]
591
590
  event_properties["$ai_output_choices"] = with_privacy_mode(
592
- self._client, self._privacy_mode, completions
591
+ self._ph_client, self._privacy_mode, completions
593
592
  )
594
593
 
595
594
  if self._properties:
@@ -598,7 +597,7 @@ class CallbackHandler(BaseCallbackHandler):
598
597
  if self._distinct_id is None:
599
598
  event_properties["$process_person_profile"] = False
600
599
 
601
- self._client.capture(
600
+ self._ph_client.capture(
602
601
  distinct_id=self._distinct_id or trace_id,
603
602
  event="$ai_generation",
604
603
  properties=event_properties,
posthoganalytics/args.py CHANGED
@@ -5,6 +5,8 @@ from datetime import datetime
5
5
  import numbers
6
6
  from uuid import UUID
7
7
 
8
+ from posthoganalytics.types import SendFeatureFlagsOptions
9
+
8
10
  ID_TYPES = Union[numbers.Number, str, UUID, int]
9
11
 
10
12
 
@@ -22,7 +24,8 @@ class OptionalCaptureArgs(TypedDict):
22
24
  error ID if you capture an exception).
23
25
  groups: Group identifiers to associate with this event (format: {group_type: group_key})
24
26
  send_feature_flags: Whether to include currently active feature flags in the event properties.
25
- Defaults to False
27
+ Can be a boolean (True/False) or a SendFeatureFlagsOptions object for advanced configuration.
28
+ Defaults to False.
26
29
  disable_geoip: Whether to disable GeoIP lookup for this event. Defaults to False.
27
30
  """
28
31
 
@@ -32,8 +35,8 @@ class OptionalCaptureArgs(TypedDict):
32
35
  uuid: NotRequired[Optional[str]]
33
36
  groups: NotRequired[Optional[Dict[str, str]]]
34
37
  send_feature_flags: NotRequired[
35
- Optional[bool]
36
- ] # Optional so we can tell if the user is intentionally overriding a client setting or not
38
+ Optional[Union[bool, SendFeatureFlagsOptions]]
39
+ ] # Updated to support both boolean and options object
37
40
  disable_geoip: NotRequired[
38
41
  Optional[bool]
39
42
  ] # As above, optional so we can tell if the user is intentionally overriding a client setting or not
@@ -524,11 +524,31 @@ class Client(object):
524
524
 
525
525
  extra_properties: dict[str, Any] = {}
526
526
  feature_variants: Optional[dict[str, Union[bool, str]]] = {}
527
- if send_feature_flags:
527
+
528
+ # Parse and normalize send_feature_flags parameter
529
+ flag_options = self._parse_send_feature_flags(send_feature_flags)
530
+
531
+ if flag_options["should_send"]:
528
532
  try:
529
- feature_variants = self.get_feature_variants(
530
- distinct_id, groups, disable_geoip=disable_geoip
531
- )
533
+ if flag_options["only_evaluate_locally"] is True:
534
+ # Only use local evaluation
535
+ feature_variants = self.get_all_flags(
536
+ distinct_id,
537
+ groups=(groups or {}),
538
+ person_properties=flag_options["person_properties"],
539
+ group_properties=flag_options["group_properties"],
540
+ disable_geoip=disable_geoip,
541
+ only_evaluate_locally=True,
542
+ )
543
+ else:
544
+ # Default behavior - use remote evaluation
545
+ feature_variants = self.get_feature_variants(
546
+ distinct_id,
547
+ groups,
548
+ person_properties=flag_options["person_properties"],
549
+ group_properties=flag_options["group_properties"],
550
+ disable_geoip=disable_geoip,
551
+ )
532
552
  except Exception as e:
533
553
  self.log.exception(
534
554
  f"[FEATURE FLAGS] Unable to get feature variants: {e}"
@@ -559,6 +579,42 @@ class Client(object):
559
579
 
560
580
  return self._enqueue(msg, disable_geoip)
561
581
 
582
+ def _parse_send_feature_flags(self, send_feature_flags) -> dict:
583
+ """
584
+ Parse and normalize send_feature_flags parameter into a standard format.
585
+
586
+ Args:
587
+ send_feature_flags: Either bool or SendFeatureFlagsOptions dict
588
+
589
+ Returns:
590
+ dict: Normalized options with keys: should_send, only_evaluate_locally,
591
+ person_properties, group_properties
592
+
593
+ Raises:
594
+ TypeError: If send_feature_flags is not bool or dict
595
+ """
596
+ if isinstance(send_feature_flags, dict):
597
+ return {
598
+ "should_send": True,
599
+ "only_evaluate_locally": send_feature_flags.get(
600
+ "only_evaluate_locally"
601
+ ),
602
+ "person_properties": send_feature_flags.get("person_properties"),
603
+ "group_properties": send_feature_flags.get("group_properties"),
604
+ }
605
+ elif isinstance(send_feature_flags, bool):
606
+ return {
607
+ "should_send": send_feature_flags,
608
+ "only_evaluate_locally": None,
609
+ "person_properties": None,
610
+ "group_properties": None,
611
+ }
612
+ else:
613
+ raise TypeError(
614
+ f"Invalid type for send_feature_flags: {type(send_feature_flags)}. "
615
+ f"Expected bool or dict."
616
+ )
617
+
562
618
  def set(self, **kwargs: Unpack[OptionalSetArgs]) -> Optional[str]:
563
619
  """
564
620
  Set properties on a person profile.
@@ -751,6 +751,186 @@ class TestClient(unittest.TestCase):
751
751
 
752
752
  self.assertEqual(patch_flags.call_count, 0)
753
753
 
754
+ @mock.patch("posthog.client.flags")
755
+ def test_capture_with_send_feature_flags_options_only_evaluate_locally_true(
756
+ self, patch_flags
757
+ ):
758
+ """Test that SendFeatureFlagsOptions with only_evaluate_locally=True uses local evaluation"""
759
+ with mock.patch("posthog.client.batch_post") as mock_post:
760
+ client = Client(
761
+ FAKE_TEST_API_KEY,
762
+ on_error=self.set_fail,
763
+ personal_api_key=FAKE_TEST_API_KEY,
764
+ sync_mode=True,
765
+ )
766
+
767
+ # Set up local flags
768
+ client.feature_flags = [
769
+ {
770
+ "id": 1,
771
+ "key": "local-flag",
772
+ "active": True,
773
+ "filters": {
774
+ "groups": [
775
+ {
776
+ "properties": [{"key": "region", "value": "US"}],
777
+ "rollout_percentage": 100,
778
+ }
779
+ ],
780
+ },
781
+ }
782
+ ]
783
+
784
+ send_options = {
785
+ "only_evaluate_locally": True,
786
+ "person_properties": {"region": "US"},
787
+ }
788
+
789
+ msg_uuid = client.capture(
790
+ "test event", distinct_id="distinct_id", send_feature_flags=send_options
791
+ )
792
+
793
+ self.assertIsNotNone(msg_uuid)
794
+ self.assertFalse(self.failed)
795
+
796
+ # Verify flags() was not called (no remote evaluation)
797
+ patch_flags.assert_not_called()
798
+
799
+ # Check the message includes the local flag
800
+ mock_post.assert_called_once()
801
+ batch_data = mock_post.call_args[1]["batch"]
802
+ msg = batch_data[0]
803
+
804
+ self.assertEqual(msg["properties"]["$feature/local-flag"], True)
805
+ self.assertEqual(msg["properties"]["$active_feature_flags"], ["local-flag"])
806
+
807
+ @mock.patch("posthog.client.flags")
808
+ def test_capture_with_send_feature_flags_options_only_evaluate_locally_false(
809
+ self, patch_flags
810
+ ):
811
+ """Test that SendFeatureFlagsOptions with only_evaluate_locally=False forces remote evaluation"""
812
+ patch_flags.return_value = {"featureFlags": {"remote-flag": "remote-value"}}
813
+
814
+ with mock.patch("posthog.client.batch_post") as mock_post:
815
+ client = Client(
816
+ FAKE_TEST_API_KEY,
817
+ on_error=self.set_fail,
818
+ personal_api_key=FAKE_TEST_API_KEY,
819
+ sync_mode=True,
820
+ )
821
+
822
+ send_options = {
823
+ "only_evaluate_locally": False,
824
+ "person_properties": {"plan": "premium"},
825
+ "group_properties": {"company": {"type": "enterprise"}},
826
+ }
827
+
828
+ msg_uuid = client.capture(
829
+ "test event",
830
+ distinct_id="distinct_id",
831
+ groups={"company": "acme"},
832
+ send_feature_flags=send_options,
833
+ )
834
+
835
+ self.assertIsNotNone(msg_uuid)
836
+ self.assertFalse(self.failed)
837
+
838
+ # Verify flags() was called with the correct properties
839
+ patch_flags.assert_called_once()
840
+ call_args = patch_flags.call_args[1]
841
+ self.assertEqual(call_args["person_properties"], {"plan": "premium"})
842
+ self.assertEqual(
843
+ call_args["group_properties"], {"company": {"type": "enterprise"}}
844
+ )
845
+
846
+ # Check the message includes the remote flag
847
+ mock_post.assert_called_once()
848
+ batch_data = mock_post.call_args[1]["batch"]
849
+ msg = batch_data[0]
850
+
851
+ self.assertEqual(msg["properties"]["$feature/remote-flag"], "remote-value")
852
+
853
+ @mock.patch("posthog.client.flags")
854
+ def test_capture_with_send_feature_flags_options_default_behavior(
855
+ self, patch_flags
856
+ ):
857
+ """Test that SendFeatureFlagsOptions without only_evaluate_locally defaults to remote evaluation"""
858
+ patch_flags.return_value = {"featureFlags": {"default-flag": "default-value"}}
859
+
860
+ with mock.patch("posthog.client.batch_post") as mock_post:
861
+ client = Client(
862
+ FAKE_TEST_API_KEY,
863
+ on_error=self.set_fail,
864
+ personal_api_key=FAKE_TEST_API_KEY,
865
+ sync_mode=True,
866
+ )
867
+
868
+ send_options = {
869
+ "person_properties": {"subscription": "pro"},
870
+ }
871
+
872
+ msg_uuid = client.capture(
873
+ "test event", distinct_id="distinct_id", send_feature_flags=send_options
874
+ )
875
+
876
+ self.assertIsNotNone(msg_uuid)
877
+ self.assertFalse(self.failed)
878
+
879
+ # Verify flags() was called (default to remote evaluation)
880
+ patch_flags.assert_called_once()
881
+ call_args = patch_flags.call_args[1]
882
+ self.assertEqual(call_args["person_properties"], {"subscription": "pro"})
883
+
884
+ # Check the message includes the flag
885
+ mock_post.assert_called_once()
886
+ batch_data = mock_post.call_args[1]["batch"]
887
+ msg = batch_data[0]
888
+
889
+ self.assertEqual(
890
+ msg["properties"]["$feature/default-flag"], "default-value"
891
+ )
892
+
893
+ @mock.patch("posthog.client.flags")
894
+ def test_capture_exception_with_send_feature_flags_options(self, patch_flags):
895
+ """Test that capture_exception also supports SendFeatureFlagsOptions"""
896
+ patch_flags.return_value = {"featureFlags": {"exception-flag": True}}
897
+
898
+ with mock.patch("posthog.client.batch_post") as mock_post:
899
+ client = Client(
900
+ FAKE_TEST_API_KEY,
901
+ on_error=self.set_fail,
902
+ personal_api_key=FAKE_TEST_API_KEY,
903
+ sync_mode=True,
904
+ )
905
+
906
+ send_options = {
907
+ "only_evaluate_locally": False,
908
+ "person_properties": {"user_type": "admin"},
909
+ }
910
+
911
+ try:
912
+ raise ValueError("Test exception")
913
+ except ValueError as e:
914
+ msg_uuid = client.capture_exception(
915
+ e, distinct_id="distinct_id", send_feature_flags=send_options
916
+ )
917
+
918
+ self.assertIsNotNone(msg_uuid)
919
+ self.assertFalse(self.failed)
920
+
921
+ # Verify flags() was called with the correct properties
922
+ patch_flags.assert_called_once()
923
+ call_args = patch_flags.call_args[1]
924
+ self.assertEqual(call_args["person_properties"], {"user_type": "admin"})
925
+
926
+ # Check the message includes the flag
927
+ mock_post.assert_called_once()
928
+ batch_data = mock_post.call_args[1]["batch"]
929
+ msg = batch_data[0]
930
+
931
+ self.assertEqual(msg["event"], "$exception")
932
+ self.assertEqual(msg["properties"]["$feature/exception-flag"], True)
933
+
754
934
  def test_stringifies_distinct_id(self):
755
935
  # A large number that loses precision in node:
756
936
  # node -e "console.log(157963456373623802 + 1)" > 157963456373623800
@@ -1591,7 +1771,7 @@ class TestClient(unittest.TestCase):
1591
1771
 
1592
1772
  @mock.patch("posthog.client.Poller")
1593
1773
  @mock.patch("posthog.client.get")
1594
- def test_call_identify_fails(self, patch_get, patch_poll):
1774
+ def test_call_identify_fails(self, patch_get, patch_poller):
1595
1775
  def raise_effect():
1596
1776
  raise Exception("http exception")
1597
1777
 
@@ -1993,3 +2173,76 @@ class TestClient(unittest.TestCase):
1993
2173
  result = client.get_remote_config_payload("test-flag")
1994
2174
 
1995
2175
  self.assertIsNone(result)
2176
+
2177
+ def test_parse_send_feature_flags_method(self):
2178
+ """Test the _parse_send_feature_flags helper method"""
2179
+ client = Client(FAKE_TEST_API_KEY, sync_mode=True)
2180
+
2181
+ # Test boolean True
2182
+ result = client._parse_send_feature_flags(True)
2183
+ expected = {
2184
+ "should_send": True,
2185
+ "only_evaluate_locally": None,
2186
+ "person_properties": None,
2187
+ "group_properties": None,
2188
+ }
2189
+ self.assertEqual(result, expected)
2190
+
2191
+ # Test boolean False
2192
+ result = client._parse_send_feature_flags(False)
2193
+ expected = {
2194
+ "should_send": False,
2195
+ "only_evaluate_locally": None,
2196
+ "person_properties": None,
2197
+ "group_properties": None,
2198
+ }
2199
+ self.assertEqual(result, expected)
2200
+
2201
+ # Test options dict with all fields
2202
+ options = {
2203
+ "only_evaluate_locally": True,
2204
+ "person_properties": {"plan": "premium"},
2205
+ "group_properties": {"company": {"type": "enterprise"}},
2206
+ }
2207
+ result = client._parse_send_feature_flags(options)
2208
+ expected = {
2209
+ "should_send": True,
2210
+ "only_evaluate_locally": True,
2211
+ "person_properties": {"plan": "premium"},
2212
+ "group_properties": {"company": {"type": "enterprise"}},
2213
+ }
2214
+ self.assertEqual(result, expected)
2215
+
2216
+ # Test options dict with partial fields
2217
+ options = {"person_properties": {"user_id": "123"}}
2218
+ result = client._parse_send_feature_flags(options)
2219
+ expected = {
2220
+ "should_send": True,
2221
+ "only_evaluate_locally": None,
2222
+ "person_properties": {"user_id": "123"},
2223
+ "group_properties": None,
2224
+ }
2225
+ self.assertEqual(result, expected)
2226
+
2227
+ # Test empty dict
2228
+ result = client._parse_send_feature_flags({})
2229
+ expected = {
2230
+ "should_send": True,
2231
+ "only_evaluate_locally": None,
2232
+ "person_properties": None,
2233
+ "group_properties": None,
2234
+ }
2235
+ self.assertEqual(result, expected)
2236
+
2237
+ # Test invalid types
2238
+ with self.assertRaises(TypeError) as cm:
2239
+ client._parse_send_feature_flags("invalid")
2240
+ self.assertIn("Invalid type for send_feature_flags", str(cm.exception))
2241
+
2242
+ with self.assertRaises(TypeError) as cm:
2243
+ client._parse_send_feature_flags(123)
2244
+ self.assertIn("Invalid type for send_feature_flags", str(cm.exception))
2245
+
2246
+ with self.assertRaises(TypeError) as cm:
2247
+ client._parse_send_feature_flags(None)
2248
+ self.assertIn("Invalid type for send_feature_flags", str(cm.exception))
posthoganalytics/types.py CHANGED
@@ -9,6 +9,24 @@ FlagValue = Union[bool, str]
9
9
  BeforeSendCallback = Callable[[dict[str, Any]], Optional[dict[str, Any]]]
10
10
 
11
11
 
12
+ class SendFeatureFlagsOptions(TypedDict, total=False):
13
+ """Options for sending feature flags with capture events.
14
+
15
+ Args:
16
+ only_evaluate_locally: Whether to only use local evaluation for feature flags.
17
+ If True, only flags that can be evaluated locally will be included.
18
+ If False, remote evaluation via /flags API will be used when needed.
19
+ person_properties: Properties to use for feature flag evaluation specific to this event.
20
+ These properties will be merged with any existing person properties.
21
+ group_properties: Group properties to use for feature flag evaluation specific to this event.
22
+ Format: { group_type_name: { group_properties } }
23
+ """
24
+
25
+ only_evaluate_locally: Optional[bool]
26
+ person_properties: Optional[dict[str, Any]]
27
+ group_properties: Optional[dict[str, dict[str, Any]]]
28
+
29
+
12
30
  @dataclass(frozen=True)
13
31
  class FlagReason:
14
32
  code: str
@@ -1,4 +1,4 @@
1
- VERSION = "6.2.1"
1
+ VERSION = "6.3.0"
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.2.1
3
+ Version: 6.3.0
4
4
  Summary: Integrate PostHog into any python application.
5
5
  Home-page: https://github.com/posthog/posthog-python
6
6
  Author: Posthog
@@ -1,6 +1,6 @@
1
1
  posthoganalytics/__init__.py,sha256=N_Mq_RDLFbd02HCMWxJPTtcSYj3NWcartohQKa7MNlw,24133
2
- posthoganalytics/args.py,sha256=hRKPQ3cPGyDn4S7Ay9t2NlgoZg1cJ0GeN_Mb6OKtmfo,3145
3
- posthoganalytics/client.py,sha256=L_Ive-qlIvflqjLrote0TP2r9jBqbNsQE_Xs7gDEe4Y,65265
2
+ posthoganalytics/args.py,sha256=iZ2JWeANiAREJKhS-Qls9tIngjJOSfAVR8C4xFT5sHw,3307
3
+ posthoganalytics/client.py,sha256=y7bUrKYaCGPWnAkOfYrLEVFD7Buoc4dZor6yKB51O_E,67611
4
4
  posthoganalytics/consumer.py,sha256=CiNbJBdyW9jER3ZYCKbX-JFmEDXlE1lbDy1MSl43-a0,4617
5
5
  posthoganalytics/contexts.py,sha256=LFSFIYpUFWKTBnGMjV9n1aYHWbAzz5zLJGr2qG34PoE,9405
6
6
  posthoganalytics/exception_capture.py,sha256=1VHBfffrXXrkK0PT8iVgKPpj_R1pGAzG5f3Qw0WF79w,1783
@@ -9,9 +9,9 @@ posthoganalytics/feature_flags.py,sha256=O_kXmw3goB2E9XMBosdPeBAuo9MsnsH8PyNWq95
9
9
  posthoganalytics/poller.py,sha256=jBz5rfH_kn_bBz7wCB46Fpvso4ttx4uzqIZWvXBCFmQ,595
10
10
  posthoganalytics/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  posthoganalytics/request.py,sha256=TaeySYpcvHMf5Ftf5KqqlO0VPJpirKBCRrThlS04Kew,6124
12
- posthoganalytics/types.py,sha256=INxWBOEQc0xgPcap6FdQNSU7zuQBmKShYaGzyuHKql8,9128
12
+ posthoganalytics/types.py,sha256=2rwhiZd9lvs37MiXEBADVdMKvcCvFXfAMgIUJ8KNTBs,10005
13
13
  posthoganalytics/utils.py,sha256=-0w-OLcCaoldkbBebPzQyBzLJSo9G9yBOg8NDVz7La8,16088
14
- posthoganalytics/version.py,sha256=RTP8N5aq19xMun9DRGgVfdICas7JIcIl1NbwnBdD_0I,87
14
+ posthoganalytics/version.py,sha256=kh3XbIm02A3duSxLSxM9UICZfLJm0YJYGYgmKSdH210,87
15
15
  posthoganalytics/ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  posthoganalytics/ai/utils.py,sha256=5-2XfmetCs0v9otBoux7-IEG933wAnKLSGS6oYLqCkw,19529
17
17
  posthoganalytics/ai/anthropic/__init__.py,sha256=fFhDOiRzTXzGQlgnrRDL-4yKC8EYIl8NW4a2QNR6xRU,368
@@ -21,7 +21,7 @@ posthoganalytics/ai/anthropic/anthropic_providers.py,sha256=y1_qc8Lbip-YDmpimPGg
21
21
  posthoganalytics/ai/gemini/__init__.py,sha256=bMNBnJ6NO_PCQCwmxKIiw4adFuEQ06hFFBALt-aDW-0,174
22
22
  posthoganalytics/ai/gemini/gemini.py,sha256=oi7VIPJLMEHPqRQwvAGwLjkaF0RZhvloCqOJgsQrmJ8,13285
23
23
  posthoganalytics/ai/langchain/__init__.py,sha256=9CqAwLynTGj3ASAR80C3PmdTdrYGmu99tz0JL-HPFgI,70
24
- posthoganalytics/ai/langchain/callbacks.py,sha256=qZlHsD8QJiXbvykBIDvNlPa0lQS4zXaxTmZ0R9JHpDQ,28848
24
+ posthoganalytics/ai/langchain/callbacks.py,sha256=nfLRbAOajQ6DVSCedUUnemY3uS_icTeILEhfnSAUJ4U,28755
25
25
  posthoganalytics/ai/openai/__init__.py,sha256=_flZxkyaDZme9hxJsY31sMlq4nP1dtc75HmNgj-21Kg,197
26
26
  posthoganalytics/ai/openai/openai.py,sha256=6bC3OxH9TP7EFkCGQRfxfcormVTAwLP4Wfj3ID3RwEc,23431
27
27
  posthoganalytics/ai/openai/openai_async.py,sha256=0gEhTr-ePiOhS8h1WznQDSz_lJm1aferk5K1ZAMo-K0,23838
@@ -30,7 +30,7 @@ posthoganalytics/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
30
30
  posthoganalytics/integrations/django.py,sha256=KYtBr7CkiZQynRc2TCWWYHe-J3ie8iSUa42WPshYZdc,6795
31
31
  posthoganalytics/test/__init__.py,sha256=VYgM6xPbJbvS-xhIcDiBRs0MFC9V_jT65uNeerCz_rM,299
32
32
  posthoganalytics/test/test_before_send.py,sha256=A1_UVMewhHAvO39rZDWfS606vG_X-q0KNXvh5DAKiB8,7930
33
- posthoganalytics/test/test_client.py,sha256=fghypNGUqOY9OmycsdNK5SsyCoimxYVisFfFq2nkTCU,77840
33
+ posthoganalytics/test/test_client.py,sha256=RJURSog8fX_YEBzv4MGrX1amX0Ma7NUMlwSanfgORmQ,87343
34
34
  posthoganalytics/test/test_consumer.py,sha256=HGMfU9PzQ5ZAe_R3kHnZNsMvD7jUjHL-gie0isrvMMk,7107
35
35
  posthoganalytics/test/test_contexts.py,sha256=c--hNUIEf6SHQ7H9vdPhU1oLCN0SnD4wDbFr-eLPHDo,7013
36
36
  posthoganalytics/test/test_exception_capture.py,sha256=al37Kg6wjzL_IBCFUUXRvkP6nVrqS6IZRCOKSo29Nh8,1063
@@ -42,8 +42,8 @@ posthoganalytics/test/test_request.py,sha256=Zc0VbkjpVmj8mKokQm9rzdgTr0b1U44vvMY
42
42
  posthoganalytics/test/test_size_limited_dict.py,sha256=-5IQjIEr_-Dql24M0HusdR_XroOMrtgiT0v6ZQCRvzo,774
43
43
  posthoganalytics/test/test_types.py,sha256=bRPHdwVpP7hu7emsplU8UVyzSQptv6PaG5lAoOD_BtM,7595
44
44
  posthoganalytics/test/test_utils.py,sha256=sqUTbfweVcxxFRd3WDMFXqPMyU6DvzOBeAOc68Py9aw,9620
45
- posthoganalytics-6.2.1.dist-info/licenses/LICENSE,sha256=wGf9JBotDkSygFj43m49oiKlFnpMnn97keiZKF-40vE,2450
46
- posthoganalytics-6.2.1.dist-info/METADATA,sha256=lXJ9kXdi1F26pQLe0vANlTpvvZNqMiYb2vOEAevWA30,6024
47
- posthoganalytics-6.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
48
- posthoganalytics-6.2.1.dist-info/top_level.txt,sha256=8QsNIqIkBh1p2TXvKp0Em9ZLZKwe3uIqCETyW4s1GOE,17
49
- posthoganalytics-6.2.1.dist-info/RECORD,,
45
+ posthoganalytics-6.3.0.dist-info/licenses/LICENSE,sha256=wGf9JBotDkSygFj43m49oiKlFnpMnn97keiZKF-40vE,2450
46
+ posthoganalytics-6.3.0.dist-info/METADATA,sha256=TyFn8t0pOnWbsC11Y3J-iJM50uiDgdQwsmmz9gKmvCw,6024
47
+ posthoganalytics-6.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
48
+ posthoganalytics-6.3.0.dist-info/top_level.txt,sha256=8QsNIqIkBh1p2TXvKp0Em9ZLZKwe3uIqCETyW4s1GOE,17
49
+ posthoganalytics-6.3.0.dist-info/RECORD,,