Compare commits

...
6 changed files with 60 additions and 30 deletions
+9 -1
View File
@@ -1,3 +1,11 @@
## 3.5.0 - 2024-02-29
1. - Adds a new `feature_flags_request_timeout_seconds` timeout parameter for feature flags which defaults to 3 seconds, updated from the default 10s for all other API calls.
## 3.4.2 - 2024-02-20
1. Add `historical_migration` option for bulk migration to PostHog Cloud.
## 3.4.1 - 2024-02-09
1. Use new hosts for event capture as well
@@ -123,7 +131,7 @@ Changes:
Breaking changes:
1. The minimum version requirement for PostHog servers is now 1.38. If you're using PostHog Cloud, you satisfy this requirement automatically.
2. Feature flag defaults apply only when there's an error fetching feature flag results. Earlier, if the default was set to `True`, even if a flag resolved to `False`, the default would override this.
2. Feature flag defaults apply only when there's an error fetching feature flag results. Earlier, if the default was set to `True`, even if a flag resolved to `False`, the default would override this.
**Note: These are removed in 2.0.2**
3. Feature flag remote evaluation doesn't require a personal API key.
+2
View File
@@ -18,6 +18,7 @@ personal_api_key = None # type: Optional[str]
project_api_key = None # type: Optional[str]
poll_interval = 30 # type: int
disable_geoip = True # type: bool
feature_flags_request_timeout_seconds = 3 # type: int
default_client = None # type: Optional[Client]
@@ -452,6 +453,7 @@ def _proxy(method, *args, **kwargs):
poll_interval=poll_interval,
disabled=disabled,
disable_geoip=disable_geoip,
feature_flags_request_timeout_seconds=feature_flags_request_timeout_seconds,
)
# always set incase user changes it
+29 -19
View File
@@ -49,6 +49,8 @@ class Client(object):
project_api_key=None,
disabled=False,
disable_geoip=True,
historical_migration=False,
feature_flags_request_timeout_seconds=3,
):
self.queue = queue.Queue(max_queue_size)
@@ -69,10 +71,12 @@ class Client(object):
self.group_type_mapping = None
self.cohorts = None
self.poll_interval = poll_interval
self.feature_flags_request_timeout_seconds = feature_flags_request_timeout_seconds
self.poller = None
self.distinct_ids_feature_flags_reported = SizeLimitedDict(MAX_DICT_SIZE, set)
self.disabled = disabled
self.disable_geoip = disable_geoip
self.historical_migration = historical_migration
# personal_api_key: This should be a generated Personal API Key, private
self.personal_api_key = personal_api_key
@@ -107,6 +111,7 @@ class Client(object):
gzip=gzip,
retries=max_retries,
timeout=timeout,
historical_migration=historical_migration,
)
self.consumers.append(consumer)
@@ -161,7 +166,7 @@ class Client(object):
"group_properties": group_properties,
"disable_geoip": disable_geoip,
}
resp_data = decide(self.api_key, self.host, timeout=10, **request_data)
resp_data = decide(self.api_key, self.host, timeout=self.feature_flags_request_timeout_seconds, **request_data)
return resp_data
@@ -374,7 +379,14 @@ class Client(object):
if self.sync_mode:
self.log.debug("enqueued with blocking %s.", msg["event"])
batch_post(self.api_key, self.host, gzip=self.gzip, timeout=self.timeout, batch=[msg])
batch_post(
self.api_key,
self.host,
gzip=self.gzip,
timeout=self.timeout,
batch=[msg],
historical_migration=self.historical_migration,
)
return True, msg
@@ -566,23 +578,21 @@ class Client(object):
# If loading in previous line failed
if self.feature_flags:
for flag in self.feature_flags:
if flag["key"] == key:
try:
response = self._compute_flag_locally(
flag,
distinct_id,
groups=groups,
person_properties=person_properties,
group_properties=group_properties,
)
self.log.debug(f"Successfully computed flag locally: {key} -> {response}")
except InconclusiveMatchError as e:
self.log.debug(f"Failed to compute flag {key} locally: {e}")
continue
except Exception as e:
self.log.exception(f"[FEATURE FLAGS] Error while computing variant locally: {e}")
continue
flag = self.feature_flags_by_key.get(key)
if flag:
try:
response = self._compute_flag_locally(
flag,
distinct_id,
groups=groups,
person_properties=person_properties,
group_properties=group_properties,
)
self.log.debug(f"Successfully computed flag locally: {key} -> {response}")
except InconclusiveMatchError as e:
self.log.debug(f"Failed to compute flag {key} locally: {e}")
except Exception as e:
self.log.exception(f"[FEATURE FLAGS] Error while computing variant locally: {e}")
flag_was_locally_evaluated = response is not None
if not flag_was_locally_evaluated and not only_evaluate_locally:
+10 -1
View File
@@ -36,6 +36,7 @@ class Consumer(Thread):
gzip=False,
retries=10,
timeout=15,
historical_migration=False,
):
"""Create a consumer thread."""
Thread.__init__(self)
@@ -55,6 +56,7 @@ class Consumer(Thread):
self.running = True
self.retries = retries
self.timeout = timeout
self.historical_migration = historical_migration
def run(self):
"""Runs the consumer."""
@@ -134,6 +136,13 @@ class Consumer(Thread):
@backoff.on_exception(backoff.expo, Exception, max_tries=self.retries + 1, giveup=fatal_exception)
def send_request():
batch_post(self.api_key, self.host, gzip=self.gzip, timeout=self.timeout, batch=batch)
batch_post(
self.api_key,
self.host,
gzip=self.gzip,
timeout=self.timeout,
batch=batch,
historical_migration=self.historical_migration,
)
send_request()
+9 -8
View File
@@ -315,7 +315,7 @@ class TestClient(unittest.TestCase):
patch_decide.assert_called_with(
"random_key",
"https://us-api.i.posthog.com",
timeout=10,
timeout=3,
distinct_id="distinct_id",
groups={},
person_properties=None,
@@ -335,6 +335,7 @@ class TestClient(unittest.TestCase):
on_error=self.set_fail,
personal_api_key=FAKE_TEST_API_KEY,
disable_geoip=True,
feature_flags_request_timeout_seconds=12,
)
success, msg = client.capture("distinct_id", "python test event", send_feature_flags=True, disable_geoip=False)
client.flush()
@@ -356,7 +357,7 @@ class TestClient(unittest.TestCase):
patch_decide.assert_called_with(
"random_key",
"https://us-api.i.posthog.com",
timeout=10,
timeout=12,
distinct_id="distinct_id",
groups={},
person_properties=None,
@@ -784,7 +785,7 @@ class TestClient(unittest.TestCase):
patch_decide.assert_called_with(
"random_key",
"https://us-api.i.posthog.com",
timeout=10,
timeout=3,
distinct_id="some_id",
groups={},
person_properties={"distinct_id": "some_id"},
@@ -796,7 +797,7 @@ class TestClient(unittest.TestCase):
patch_decide.assert_called_with(
"random_key",
"https://us-api.i.posthog.com",
timeout=10,
timeout=3,
distinct_id="feature_enabled_distinct_id",
groups={},
person_properties={"distinct_id": "feature_enabled_distinct_id"},
@@ -808,7 +809,7 @@ class TestClient(unittest.TestCase):
patch_decide.assert_called_with(
"random_key",
"https://us-api.i.posthog.com",
timeout=10,
timeout=3,
distinct_id="all_flags_payloads_id",
groups={},
person_properties={"distinct_id": "all_flags_payloads_id"},
@@ -844,7 +845,7 @@ class TestClient(unittest.TestCase):
patch_decide.assert_called_with(
"random_key",
"http://app2.posthog.com",
timeout=10,
timeout=3,
distinct_id="some_id",
groups={"company": "id:5", "instance": "app.posthog.com"},
person_properties={"distinct_id": "some_id", "x1": "y1"},
@@ -870,7 +871,7 @@ class TestClient(unittest.TestCase):
patch_decide.assert_called_with(
"random_key",
"http://app2.posthog.com",
timeout=10,
timeout=3,
distinct_id="some_id",
groups={"company": "id:5", "instance": "app.posthog.com"},
person_properties={"distinct_id": "override"},
@@ -887,7 +888,7 @@ class TestClient(unittest.TestCase):
patch_decide.assert_called_with(
"random_key",
"http://app2.posthog.com",
timeout=10,
timeout=3,
distinct_id="some_id",
groups={},
person_properties={"distinct_id": "some_id"},
+1 -1
View File
@@ -1,4 +1,4 @@
VERSION = "3.4.1"
VERSION = "3.5.0"
if __name__ == "__main__":
print(VERSION, end="") # noqa: T201