posthoganalytics 6.0.4__tar.gz → 6.1.0__tar.gz

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.
Files changed (57) hide show
  1. {posthoganalytics-6.0.4/posthoganalytics.egg-info → posthoganalytics-6.1.0}/PKG-INFO +1 -1
  2. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/__init__.py +4 -0
  3. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/client.py +7 -1
  4. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/test/test_client.py +90 -0
  5. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/version.py +1 -1
  6. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0/posthoganalytics.egg-info}/PKG-INFO +1 -1
  7. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/LICENSE +0 -0
  8. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/MANIFEST.in +0 -0
  9. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/README.md +0 -0
  10. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/ai/__init__.py +0 -0
  11. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/ai/anthropic/__init__.py +0 -0
  12. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/ai/anthropic/anthropic.py +0 -0
  13. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/ai/anthropic/anthropic_async.py +0 -0
  14. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/ai/anthropic/anthropic_providers.py +0 -0
  15. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/ai/gemini/__init__.py +0 -0
  16. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/ai/gemini/gemini.py +0 -0
  17. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/ai/langchain/__init__.py +0 -0
  18. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/ai/langchain/callbacks.py +0 -0
  19. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/ai/openai/__init__.py +0 -0
  20. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/ai/openai/openai.py +0 -0
  21. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/ai/openai/openai_async.py +0 -0
  22. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/ai/openai/openai_providers.py +0 -0
  23. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/ai/utils.py +0 -0
  24. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/args.py +0 -0
  25. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/consumer.py +0 -0
  26. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/contexts.py +0 -0
  27. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/exception_capture.py +0 -0
  28. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/exception_utils.py +0 -0
  29. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/feature_flags.py +0 -0
  30. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/integrations/__init__.py +0 -0
  31. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/integrations/django.py +0 -0
  32. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/poller.py +0 -0
  33. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/py.typed +0 -0
  34. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/request.py +0 -0
  35. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/test/__init__.py +0 -0
  36. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/test/test_before_send.py +0 -0
  37. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/test/test_consumer.py +0 -0
  38. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/test/test_contexts.py +0 -0
  39. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/test/test_exception_capture.py +0 -0
  40. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/test/test_feature_flag.py +0 -0
  41. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/test/test_feature_flag_result.py +0 -0
  42. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/test/test_feature_flags.py +0 -0
  43. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/test/test_module.py +0 -0
  44. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/test/test_request.py +0 -0
  45. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/test/test_size_limited_dict.py +0 -0
  46. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/test/test_types.py +0 -0
  47. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/test/test_utils.py +0 -0
  48. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/types.py +0 -0
  49. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics/utils.py +0 -0
  50. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics.egg-info/SOURCES.txt +0 -0
  51. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics.egg-info/dependency_links.txt +0 -0
  52. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics.egg-info/requires.txt +0 -0
  53. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/posthoganalytics.egg-info/top_level.txt +0 -0
  54. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/pyproject.toml +0 -0
  55. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/setup.cfg +0 -0
  56. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/setup.py +0 -0
  57. {posthoganalytics-6.0.4 → posthoganalytics-6.1.0}/setup_analytics.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: posthoganalytics
3
- Version: 6.0.4
3
+ Version: 6.1.0
4
4
  Summary: Integrate PostHog into any python application.
5
5
  Home-page: https://github.com/posthog/posthog-python
6
6
  Author: Posthog
@@ -60,6 +60,9 @@ log_captured_exceptions = False # type: bool
60
60
  project_root = None # type: Optional[str]
61
61
  # Used for our AI observability feature to not capture any prompt or output just usage + metadata
62
62
  privacy_mode = False # type: bool
63
+ # Whether to enable feature flag polling for local evaluation by default. Defaults to True.
64
+ # We recommend setting this to False if you are only using the personalApiKey for evaluating remote config payloads via `get_remote_config_payload` and not using local evaluation.
65
+ enable_local_evaluation = True # type: bool
63
66
 
64
67
  default_client = None # type: Optional[Client]
65
68
 
@@ -465,6 +468,7 @@ def setup():
465
468
  # or deprecate this proxy option fully (it's already in the process of deprecation, no new clients should be using this method since like 5-6 months)
466
469
  enable_exception_autocapture=enable_exception_autocapture,
467
470
  log_captured_exceptions=log_captured_exceptions,
471
+ enable_local_evaluation=enable_local_evaluation,
468
472
  )
469
473
 
470
474
  # always set incase user changes it
@@ -152,6 +152,7 @@ class Client(object):
152
152
  privacy_mode=False,
153
153
  before_send=None,
154
154
  flag_fallback_cache_url=None,
155
+ enable_local_evaluation=True,
155
156
  ):
156
157
  self.queue = queue.Queue(max_queue_size)
157
158
 
@@ -187,6 +188,7 @@ class Client(object):
187
188
  self.log_captured_exceptions = log_captured_exceptions
188
189
  self.exception_capture = None
189
190
  self.privacy_mode = privacy_mode
191
+ self.enable_local_evaluation = enable_local_evaluation
190
192
 
191
193
  if project_root is None:
192
194
  try:
@@ -807,7 +809,11 @@ class Client(object):
807
809
  return
808
810
 
809
811
  self._load_feature_flags()
810
- if not (self.poller and self.poller.is_alive()):
812
+
813
+ # Only start the poller if local evaluation is enabled
814
+ if self.enable_local_evaluation and not (
815
+ self.poller and self.poller.is_alive()
816
+ ):
811
817
  self.poller = Poller(
812
818
  interval=timedelta(seconds=self.poll_interval),
813
819
  execute=self._load_feature_flags,
@@ -1903,3 +1903,93 @@ class TestClient(unittest.TestCase):
1903
1903
  self.assertEqual(
1904
1904
  msg["properties"]["$session_id"], "explicit-session-override"
1905
1905
  )
1906
+
1907
+ @mock.patch("posthog.client.Poller")
1908
+ @mock.patch("posthog.client.get")
1909
+ def test_enable_local_evaluation_false_disables_poller(
1910
+ self, patch_get, patch_poller
1911
+ ):
1912
+ """Test that when enable_local_evaluation=False, the poller is not started"""
1913
+ patch_get.return_value = {
1914
+ "flags": [
1915
+ {"id": 1, "name": "Beta Feature", "key": "beta-feature", "active": True}
1916
+ ],
1917
+ "group_type_mapping": {},
1918
+ "cohorts": {},
1919
+ }
1920
+
1921
+ client = Client(
1922
+ FAKE_TEST_API_KEY,
1923
+ personal_api_key="test-personal-key",
1924
+ enable_local_evaluation=False,
1925
+ )
1926
+
1927
+ # Load feature flags should not start the poller
1928
+ client.load_feature_flags()
1929
+
1930
+ # Assert that the poller was not created/started
1931
+ patch_poller.assert_not_called()
1932
+ # But the feature flags should still be loaded
1933
+ patch_get.assert_called_once()
1934
+ self.assertEqual(len(client.feature_flags), 1)
1935
+ self.assertEqual(client.feature_flags[0]["key"], "beta-feature")
1936
+
1937
+ @mock.patch("posthog.client.Poller")
1938
+ @mock.patch("posthog.client.get")
1939
+ def test_enable_local_evaluation_true_starts_poller(self, patch_get, patch_poller):
1940
+ """Test that when enable_local_evaluation=True (default), the poller is started"""
1941
+ patch_get.return_value = {
1942
+ "flags": [
1943
+ {"id": 1, "name": "Beta Feature", "key": "beta-feature", "active": True}
1944
+ ],
1945
+ "group_type_mapping": {},
1946
+ "cohorts": {},
1947
+ }
1948
+
1949
+ client = Client(
1950
+ FAKE_TEST_API_KEY,
1951
+ personal_api_key="test-personal-key",
1952
+ enable_local_evaluation=True,
1953
+ )
1954
+
1955
+ # Load feature flags should start the poller
1956
+ client.load_feature_flags()
1957
+
1958
+ # Assert that the poller was created and started
1959
+ patch_poller.assert_called_once()
1960
+ patch_get.assert_called_once()
1961
+ self.assertEqual(len(client.feature_flags), 1)
1962
+ self.assertEqual(client.feature_flags[0]["key"], "beta-feature")
1963
+
1964
+ @mock.patch("posthog.client.remote_config")
1965
+ def test_get_remote_config_payload_works_without_poller(self, patch_remote_config):
1966
+ """Test that get_remote_config_payload works without local evaluation enabled"""
1967
+ patch_remote_config.return_value = {"test": "payload"}
1968
+
1969
+ client = Client(
1970
+ FAKE_TEST_API_KEY,
1971
+ personal_api_key="test-personal-key",
1972
+ enable_local_evaluation=False,
1973
+ )
1974
+
1975
+ # Should work without poller
1976
+ result = client.get_remote_config_payload("test-flag")
1977
+
1978
+ self.assertEqual(result, {"test": "payload"})
1979
+ patch_remote_config.assert_called_once_with(
1980
+ "test-personal-key",
1981
+ client.host,
1982
+ "test-flag",
1983
+ timeout=client.feature_flags_request_timeout_seconds,
1984
+ )
1985
+
1986
+ def test_get_remote_config_payload_requires_personal_api_key(self):
1987
+ """Test that get_remote_config_payload requires personal API key"""
1988
+ client = Client(
1989
+ FAKE_TEST_API_KEY,
1990
+ enable_local_evaluation=False,
1991
+ )
1992
+
1993
+ result = client.get_remote_config_payload("test-flag")
1994
+
1995
+ self.assertIsNone(result)
@@ -1,4 +1,4 @@
1
- VERSION = "6.0.4"
1
+ VERSION = "6.1.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.0.4
3
+ Version: 6.1.0
4
4
  Summary: Integrate PostHog into any python application.
5
5
  Home-page: https://github.com/posthog/posthog-python
6
6
  Author: Posthog