Skip to content

Commit bf80051

Browse files
committed
alright
1 parent 5a7f324 commit bf80051

20 files changed

+970
-1413
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
# 6.0.0
2+
3+
This release contains a number of major breaking changes:
4+
- feat: make distinct_id an optional parameter in posthog.capture and related functions
5+
- feat: make capture and related functions return `Optional[str]`, which is the UUID of the sent event, if it was sent
6+
- fix: remove `identify` (prefer `posthog.set()`), and `page` and `screen` (prefer `posthog.capture()`)
7+
- fix: delete exception-capture specific integrations module. Prefer the general-purpose django middleware as a replacement for the django `Integration`.
8+
19
# 5.3.0 - 2025-06-19
210

311
- fix: safely handle exception values

example.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
)
7676

7777
# # Add properties to the person
78-
posthog.identify("new_distinct_id", {"email": "[email protected]"})
78+
posthog.set("new_distinct_id", {"email": "[email protected]"})
7979

8080
# Add properties to a group
8181
posthog.group_identify("company", "id:5", {"employees": 11})

posthog/__init__.py

Lines changed: 32 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@
33
from typing import Callable, Dict, List, Optional, Tuple # noqa: F401
44

55
from posthog.client import Client
6-
from posthog.exception_capture import Integrations # noqa: F401
76
from posthog.scopes import (
8-
clear_tags,
9-
get_tags,
107
new_context,
118
scoped,
129
tag,
@@ -21,8 +18,6 @@
2118
"""Context management."""
2219
new_context = new_context
2320
tag = tag
24-
get_tags = get_tags
25-
clear_tags = clear_tags
2621
scoped = scoped
2722
identify_context = identify_context
2823
set_context_session = set_context_session
@@ -44,7 +39,6 @@
4439
super_properties = None # type: Optional[Dict]
4540
# Currently alpha, use at your own risk
4641
enable_exception_autocapture = False # type: bool
47-
exception_autocapture_integrations = [] # type: List[Integrations]
4842
log_captured_exceptions = False # type: bool
4943
# Used to determine in app paths for exception autocapture. Defaults to the current working directory
5044
project_root = None # type: Optional[str]
@@ -54,27 +48,31 @@
5448
default_client = None # type: Optional[Client]
5549

5650

51+
# NOTE - this and following functions take and unpack kwargs because we needed to make
52+
# it impossible to write `posthog.capture(distinct-id, event-name)` - basically, to enforce
53+
# the breaking change made between 5.3.0 and 6.0.0. This decision can be unrolled in later
54+
# versions, without a breaking change, to get back the type information in function signatures
5755
def capture(
58-
distinct_id, # type: str
5956
event, # type: str
60-
properties=None, # type: Optional[Dict]
61-
context=None, # type: Optional[Dict]
62-
timestamp=None, # type: Optional[datetime.datetime]
63-
uuid=None, # type: Optional[str]
64-
groups=None, # type: Optional[Dict]
65-
send_feature_flags=False,
66-
disable_geoip=None, # type: Optional[bool]
57+
**kwargs,
6758
):
68-
# type: (...) -> Tuple[bool, dict]
59+
# type: (...) -> Optional[str]
60+
distinct_id = kwargs.get("distinct_id", None)
61+
properties = kwargs.get("properties", None)
62+
timestamp = kwargs.get("timestamp", None)
63+
uuid = kwargs.get("uuid", None)
64+
groups = kwargs.get("groups", None)
65+
send_feature_flags = kwargs.get("send_feature_flags", False)
66+
disable_geoip = kwargs.get("disable_geoip", None)
6967
"""
7068
Capture allows you to capture anything a user does within your system, which you can later use in PostHog to find patterns in usage, work out which features to improve or where people are giving up.
7169
7270
A `capture` call requires
73-
- `distinct id` which uniquely identifies your user
7471
- `event name` to specify the event
7572
- We recommend using [verb] [noun], like `movie played` or `movie updated` to easily identify what your events mean later on.
7673
7774
Optionally you can submit
75+
- `distinct id` which uniquely identifies your user. This overrides any context-level ID, if set
7876
- `properties`, which can be a dict with any information you'd like to add
7977
- `groups`, which is a dict of group type -> group key mappings
8078
@@ -87,19 +85,11 @@ def capture(
8785
```
8886
"""
8987

90-
if context is not None:
91-
warnings.warn(
92-
"The 'context' parameter is deprecated and will be removed in a future version.",
93-
DeprecationWarning,
94-
stacklevel=2,
95-
)
96-
9788
return _proxy(
9889
"capture",
9990
distinct_id=distinct_id,
10091
event=event,
10192
properties=properties,
102-
context=context,
10393
timestamp=timestamp,
10494
uuid=uuid,
10595
groups=groups,
@@ -108,101 +98,45 @@ def capture(
10898
)
10999

110100

111-
def identify(
112-
distinct_id, # type: str
113-
properties=None, # type: Optional[Dict]
114-
context=None, # type: Optional[Dict]
115-
timestamp=None, # type: Optional[datetime.datetime]
116-
uuid=None, # type: Optional[str]
117-
disable_geoip=None, # type: Optional[bool]
118-
):
119-
# type: (...) -> Tuple[bool, dict]
120-
"""
121-
Identify lets you add metadata on your users so you can more easily identify who they are in PostHog, and even do things like segment users by these properties.
122-
123-
An `identify` call requires
124-
- `distinct id` which uniquely identifies your user
125-
- `properties` with a dict with any key: value pairs
126-
127-
For example:
128-
```python
129-
posthog.identify('distinct id', {
130-
'email': '[email protected]',
131-
'name': 'Dwayne Johnson'
132-
})
133-
```
134-
"""
135-
136-
if context is not None:
137-
warnings.warn(
138-
"The 'context' parameter is deprecated and will be removed in a future version.",
139-
DeprecationWarning,
140-
stacklevel=2,
141-
)
142-
143-
return _proxy(
144-
"identify",
145-
distinct_id=distinct_id,
146-
properties=properties,
147-
context=context,
148-
timestamp=timestamp,
149-
uuid=uuid,
150-
disable_geoip=disable_geoip,
151-
)
152-
153-
154-
def set(
155-
distinct_id, # type: str
156-
properties=None, # type: Optional[Dict]
157-
context=None, # type: Optional[Dict]
158-
timestamp=None, # type: Optional[datetime.datetime]
159-
uuid=None, # type: Optional[str]
160-
disable_geoip=None, # type: Optional[bool]
161-
):
162-
# type: (...) -> Tuple[bool, dict]
101+
def set(**kwargs):
102+
# type: (...) -> Optional[str]
103+
distinct_id = kwargs.get("distinct_id", None)
104+
properties = kwargs.get("properties", None)
105+
timestamp = kwargs.get("timestamp", None)
106+
uuid = kwargs.get("uuid", None)
107+
disable_geoip = kwargs.get("disabled_geoip", None)
163108
"""
164109
Set properties on a user record.
165110
This will overwrite previous people property values, just like `identify`.
166111
167112
A `set` call requires
168-
- `distinct id` which uniquely identifies your user
169113
- `properties` with a dict with any key: value pairs
170114
171115
For example:
172116
```python
173-
posthog.set('distinct id', {
117+
posthog.set(distinct_id='distinct id', properties={
174118
'current_browser': 'Chrome',
175119
})
176120
```
177121
"""
178122

179-
if context is not None:
180-
warnings.warn(
181-
"The 'context' parameter is deprecated and will be removed in a future version.",
182-
DeprecationWarning,
183-
stacklevel=2,
184-
)
185-
186123
return _proxy(
187124
"set",
188125
distinct_id=distinct_id,
189126
properties=properties,
190-
context=context,
191127
timestamp=timestamp,
192128
uuid=uuid,
193129
disable_geoip=disable_geoip,
194130
)
195131

196132

197-
def set_once(
198-
distinct_id, # type: str
199-
properties=None, # type: Optional[Dict]
200-
context=None, # type: Optional[Dict]
201-
timestamp=None, # type: Optional[datetime.datetime]
202-
uuid=None, # type: Optional[str]
203-
disable_geoip=None, # type: Optional[bool]
204-
):
205-
# type: (...) -> Tuple[bool, dict]
133+
def set_once(**kwargs):
134+
# type: (...) -> Optional[str]
135+
distinct_id = kwargs.get("distinct_id", None)
136+
properties = kwargs.get("properties", None)
137+
timestamp = kwargs.get("timestamp", None)
138+
uuid = kwargs.get("uuid", None)
139+
disable_geoip = kwargs.get("disabled_geoip", None)
206140
"""
207141
Set properties on a user record, only if they do not yet exist.
208142
This will not overwrite previous people property values, unlike `identify`.
@@ -218,19 +152,10 @@ def set_once(
218152
})
219153
```
220154
"""
221-
222-
if context is not None:
223-
warnings.warn(
224-
"The 'context' parameter is deprecated and will be removed in a future version.",
225-
DeprecationWarning,
226-
stacklevel=2,
227-
)
228-
229155
return _proxy(
230156
"set_once",
231157
distinct_id=distinct_id,
232158
properties=properties,
233-
context=context,
234159
timestamp=timestamp,
235160
uuid=uuid,
236161
disable_geoip=disable_geoip,
@@ -246,7 +171,7 @@ def group_identify(
246171
uuid=None, # type: Optional[str]
247172
disable_geoip=None, # type: Optional[bool]
248173
):
249-
# type: (...) -> Tuple[bool, dict]
174+
# type: (...) -> Optional[str]
250175
"""
251176
Set properties on a group
252177
@@ -290,7 +215,7 @@ def alias(
290215
uuid=None, # type: Optional[str]
291216
disable_geoip=None, # type: Optional[bool]
292217
):
293-
# type: (...) -> Tuple[bool, dict]
218+
# type: (...) -> Optional[str]
294219
"""
295220
To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call. This will allow you to answer questions like "Which marketing channels leads to users churning after a month?" or "What do users do on our website before signing up?"
296221
@@ -330,13 +255,12 @@ def capture_exception(
330255
exception=None, # type: Optional[BaseException]
331256
distinct_id=None, # type: Optional[str]
332257
properties=None, # type: Optional[Dict]
333-
context=None, # type: Optional[Dict]
334258
timestamp=None, # type: Optional[datetime.datetime]
335259
uuid=None, # type: Optional[str]
336260
groups=None, # type: Optional[Dict]
337261
**kwargs,
338262
):
339-
# type: (...) -> Tuple[bool, dict]
263+
# type: (...) -> Optional[str]
340264
"""
341265
capture_exception allows you to capture exceptions that happen in your code. This is useful for debugging and understanding what errors your users are encountering.
342266
This function never raises an exception, even if it fails to send the event.
@@ -361,19 +285,11 @@ def capture_exception(
361285
```
362286
"""
363287

364-
if context is not None:
365-
warnings.warn(
366-
"The 'context' parameter is deprecated and will be removed in a future version.",
367-
DeprecationWarning,
368-
stacklevel=2,
369-
)
370-
371288
return _proxy(
372289
"capture_exception",
373290
exception=exception,
374291
distinct_id=distinct_id,
375292
properties=properties,
376-
context=context,
377293
timestamp=timestamp,
378294
uuid=uuid,
379295
groups=groups,
@@ -565,16 +481,6 @@ def load_feature_flags():
565481
return _proxy("load_feature_flags")
566482

567483

568-
def page(*args, **kwargs):
569-
"""Send a page call."""
570-
_proxy("page", *args, **kwargs)
571-
572-
573-
def screen(*args, **kwargs):
574-
"""Send a screen call."""
575-
_proxy("screen", *args, **kwargs)
576-
577-
578484
def flush():
579485
"""Tell the client to flush."""
580486
_proxy("flush")
@@ -613,7 +519,6 @@ def setup():
613519
# 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)
614520
enable_exception_autocapture=enable_exception_autocapture,
615521
log_captured_exceptions=log_captured_exceptions,
616-
exception_autocapture_integrations=exception_autocapture_integrations,
617522
)
618523

619524
# always set incase user changes it

0 commit comments

Comments
 (0)