Compare commits

...
3 Commits
Author SHA1 Message Date
David NewellandGitHub ee0305993d feat: add super properties (#138) 2024-10-03 17:07:47 +01:00
28c4802d9b Remove deprecated datetime.utcnow() in favour of datetime.now(tz=tzutc()) (#124)
Co-authored-by: Neil Kakkar <neilkakkar@gmail.com>
2024-09-24 11:09:15 +01:00
Neil KakkarandGitHub 67a343f242 fix(errors): Make sure project root exists to judge in app frames (#136)
* fix(errors): Make sure project root exists to judge in app frames

* prep release
2024-09-16 11:11:28 +01:00
6 changed files with 61 additions and 10 deletions
+20 -5
View File
@@ -1,3 +1,15 @@
## 3.7.0 - 2024-10-03
1. Adds a new `super_properties` parameter on the client that are appended to every /capture call.
## 3.6.7 - 2024-09-24
1. Remove deprecated datetime.utcnow() in favour of datetime.now(tz=tzutc())
## 3.6.6 - 2024-09-16
1. Fix manual capture support for in app frames
## 3.6.5 - 2024-09-10
1. Fix django integration support for manual exception capture.
@@ -58,7 +70,6 @@
1. Return success/failure with all capture calls from module functions
## 3.3.1 - 2024-01-10
1. Make sure we don't override any existing feature flag properties when adding locally evaluated feature flag properties.
@@ -84,6 +95,7 @@
1. Restore how feature flags work when the client library is disabled: All requests return `None` and no events are sent when the client is disabled.
2. Add a `feature_flag_definitions()` debug option, which returns currently loaded feature flag definitions. You can use this to more cleverly decide when to request local evaluation of feature flags.
## 3.0.0 - 2023-04-14
Breaking change:
@@ -124,7 +136,6 @@ posthog = Posthog('api_key', disable_geoip=False)
1. Log instead of raise error on posthog personal api key errors
2. Remove upper bound on backoff dependency
## 2.3.0 - 2023-01-31
1. Add support for returning payloads of matched feature flags
@@ -140,6 +151,7 @@ Changes:
Changes:
1. Fixes issues with date comparison.
## 2.1.1 - 2022-09-14
Changes:
@@ -152,6 +164,7 @@ Changes:
1. Feature flag defaults have been removed
2. Setup logging only when debug mode is enabled.
## 2.0.1 - 2022-08-04
- Make poll_interval configurable
@@ -164,7 +177,7 @@ 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.
**Note: These are removed in 2.0.2**
**Note: These are removed in 2.0.2**
3. Feature flag remote evaluation doesn't require a personal API key.
New Changes:
@@ -172,18 +185,20 @@ New Changes:
1. You can now evaluate feature flags locally (i.e. without sending a request to your PostHog servers) by setting a personal API key, and passing in groups and person properties to `is_feature_enabled` and `get_feature_flag` calls.
2. Introduces a `get_all_flags` method that returns all feature flags. This is useful for when you want to seed your frontend with some initial flags, given a user ID.
## 1.4.9 - 2022-06-13
- Support for sending feature flags with capture calls
## 1.4.8 - 2022-05-12
- Support multi variate feature flags
## 1.4.7 - 2022-04-25
- Allow feature flags usage without project_api_key
## 1.4.1 - 2021-05-28
- Fix packaging issues with Sentry integrations
## 1.4.0 - 2021-05-18
+4
View File
@@ -20,9 +20,12 @@ 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
super_properties = None # type: Optional[Dict]
# Currently alpha, use at your own risk
enable_exception_autocapture = False # type: bool
exception_autocapture_integrations = [] # type: List[Integrations]
# Used to determine in app paths for exception autocapture. Defaults to the current working directory
project_root = None # type: Optional[str]
default_client = None # type: Optional[Client]
@@ -502,6 +505,7 @@ def _proxy(method, *args, **kwargs):
disabled=disabled,
disable_geoip=disable_geoip,
feature_flags_request_timeout_seconds=feature_flags_request_timeout_seconds,
super_properties=super_properties,
# TODO: Currently this monitoring begins only when the Client is initialised (which happens when you do something with the SDK)
# This kind of initialisation is very annoying for exception capture. We need to figure out a way around this,
# 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)
+19 -3
View File
@@ -1,6 +1,7 @@
import atexit
import logging
import numbers
import os
import sys
from datetime import datetime, timedelta
from uuid import UUID
@@ -54,8 +55,10 @@ class Client(object):
disable_geoip=True,
historical_migration=False,
feature_flags_request_timeout_seconds=3,
super_properties=None,
enable_exception_autocapture=False,
exception_autocapture_integrations=None,
project_root=None,
):
self.queue = queue.Queue(max_queue_size)
@@ -84,10 +87,19 @@ class Client(object):
self.disabled = disabled
self.disable_geoip = disable_geoip
self.historical_migration = historical_migration
self.super_properties = super_properties
self.enable_exception_autocapture = enable_exception_autocapture
self.exception_autocapture_integrations = exception_autocapture_integrations
self.exception_capture = None
if project_root is None:
try:
project_root = os.getcwd()
except Exception:
project_root = None
self.project_root = project_root
# personal_api_key: This should be a generated Personal API Key, private
self.personal_api_key = personal_api_key
if debug:
@@ -382,7 +394,8 @@ class Client(object):
"exception": {
"values": all_exceptions_with_trace,
},
}
},
project_root=self.project_root,
)
all_exceptions_with_trace_and_in_app = event["exception"]["values"]
@@ -406,7 +419,7 @@ class Client(object):
timestamp = msg["timestamp"]
if timestamp is None:
timestamp = datetime.utcnow().replace(tzinfo=tzutc())
timestamp = datetime.now(tz=tzutc())
require("timestamp", timestamp, datetime)
require("context", msg["context"], dict)
@@ -432,6 +445,9 @@ class Client(object):
if disable_geoip:
msg["properties"]["$geoip_disable"] = True
if self.super_properties:
msg["properties"] = {**msg["properties"], **self.super_properties}
msg["distinct_id"] = stringify_id(msg.get("distinct_id", None))
msg = clean(msg)
@@ -530,7 +546,7 @@ class Client(object):
)
self.log.warning(e)
self._last_feature_flag_poll = datetime.utcnow().replace(tzinfo=tzutc())
self._last_feature_flag_poll = datetime.now(tz=tzutc())
def load_feature_flags(self):
if not self.personal_api_key:
+1 -1
View File
@@ -37,7 +37,7 @@ def post(
"""Post the `kwargs` to the API"""
log = logging.getLogger("posthog")
body = kwargs
body["sentAt"] = datetime.utcnow().replace(tzinfo=tzutc()).isoformat()
body["sentAt"] = datetime.now(tz=tzutc()).isoformat()
url = remove_trailing_slash(host or DEFAULT_HOST) + path
body["api_key"] = api_key
data = json.dumps(body, cls=DatetimeSerializer)
+16
View File
@@ -84,6 +84,21 @@ class TestClient(unittest.TestCase):
self.assertEqual(msg["properties"]["$lib"], "posthog-python")
self.assertEqual(msg["properties"]["$lib_version"], VERSION)
def test_basic_super_properties(self):
client = Client(FAKE_TEST_API_KEY, super_properties={"source": "repo-name"})
_, msg = client.capture("distinct_id", "python test event")
client.flush()
self.assertEqual(msg["event"], "python test event")
self.assertEqual(msg["properties"]["source"], "repo-name")
_, msg = client.identify("distinct_id", {"trait": "value"})
client.flush()
self.assertEqual(msg["$set"]["trait"], "value")
self.assertEqual(msg["properties"]["source"], "repo-name")
def test_basic_capture_exception(self):
with mock.patch.object(Client, "capture", return_value=None) as patch_capture:
@@ -227,6 +242,7 @@ class TestClient(unittest.TestCase):
self.assertEqual(
capture_call[2]["$exception_list"][0]["stacktrace"]["frames"][0]["module"], "posthog.test.test_client"
)
self.assertEqual(capture_call[2]["$exception_list"][0]["stacktrace"]["frames"][0]["in_app"], True)
def test_basic_capture_exception_with_no_exception_happening(self):
+1 -1
View File
@@ -1,4 +1,4 @@
VERSION = "3.6.5"
VERSION = "3.7.0"
if __name__ == "__main__":
print(VERSION, end="") # noqa: T201