Skip to content

Commit 06f6a31

Browse files
committed
fix changelog and version
2 parents f094138 + 6ab2856 commit 06f6a31

File tree

14 files changed

+121
-48
lines changed

14 files changed

+121
-48
lines changed

CHANGELOG.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1-
# 6.2.0 - 2025-07-15
1+
# 6.3.0 - 2025-07-22
22

33
- feat: Enhanced `send_feature_flags` parameter to accept `SendFeatureFlagsOptions` object for declarative control over local/remote evaluation and custom properties
44

5+
# 6.2.1 - 2025-07-21
6+
7+
- feat: make `posthog_client` an optional argument in PostHog AI providers wrappers (`posthog.ai.*`), intuitively using the default client as the default
8+
9+
# 6.1.1 - 2025-07-16
10+
11+
- fix: correctly capture exceptions processed by Django from views or middleware
12+
513
# 6.1.0 - 2025-07-10
614

715
- feat: decouple feature flag local evaluation from personal API keys; support decrypting remote config payloads without relying on the feature flags poller
@@ -25,12 +33,14 @@
2533
# 6.0.0
2634

2735
This release contains a number of major breaking changes:
36+
2837
- feat: make distinct_id an optional parameter in posthog.capture and related functions
2938
- feat: make capture and related functions return `Optional[str]`, which is the UUID of the sent event, if it was sent
3039
- fix: remove `identify` (prefer `posthog.set()`), and `page` and `screen` (prefer `posthog.capture()`)
3140
- fix: delete exception-capture specific integrations module. Prefer the general-purpose django middleware as a replacement for the django `Integration`.
3241

3342
To migrate to this version, you'll mostly just need to switch to using named keyword arguments, rather than positional ones. For example:
43+
3444
```python
3545
# Old calling convention
3646
posthog.capture("user123", "button_clicked", {"button_id": "123"})

posthog/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,7 @@ def shutdown():
676676
_proxy("join")
677677

678678

679-
def setup():
679+
def setup() -> Client:
680680
global default_client
681681
if not default_client:
682682
if not api_key:
@@ -706,6 +706,8 @@ def setup():
706706
default_client.disabled = disabled
707707
default_client.debug = debug
708708

709+
return default_client
710+
709711

710712
def _proxy(method, *args, **kwargs):
711713
"""Create an analytics client if one doesn't exist and send to it."""

posthog/ai/anthropic/anthropic.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import time
1010
import uuid
11-
from typing import Any, Dict, Optional
11+
from typing import Any, Dict, Optional, cast
1212

1313
from posthog.ai.utils import (
1414
call_llm_and_track_usage,
@@ -17,6 +17,7 @@
1717
with_privacy_mode,
1818
)
1919
from posthog.client import Client as PostHogClient
20+
from posthog import setup
2021

2122

2223
class Anthropic(anthropic.Anthropic):
@@ -26,14 +27,14 @@ class Anthropic(anthropic.Anthropic):
2627

2728
_ph_client: PostHogClient
2829

29-
def __init__(self, posthog_client: PostHogClient, **kwargs):
30+
def __init__(self, posthog_client: Optional[PostHogClient] = None, **kwargs):
3031
"""
3132
Args:
3233
posthog_client: PostHog client for tracking usage
3334
**kwargs: Additional arguments passed to the Anthropic client
3435
"""
3536
super().__init__(**kwargs)
36-
self._ph_client = posthog_client
37+
self._ph_client = posthog_client or setup()
3738
self.messages = WrappedMessages(self)
3839

3940

posthog/ai/anthropic/anthropic_async.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import uuid
1111
from typing import Any, Dict, Optional
1212

13+
from posthog import setup
1314
from posthog.ai.utils import (
1415
call_llm_and_track_usage_async,
1516
get_model_params,
@@ -26,14 +27,14 @@ class AsyncAnthropic(anthropic.AsyncAnthropic):
2627

2728
_ph_client: PostHogClient
2829

29-
def __init__(self, posthog_client: PostHogClient, **kwargs):
30+
def __init__(self, posthog_client: Optional[PostHogClient] = None, **kwargs):
3031
"""
3132
Args:
3233
posthog_client: PostHog client for tracking usage
3334
**kwargs: Additional arguments passed to the Anthropic client
3435
"""
3536
super().__init__(**kwargs)
36-
self._ph_client = posthog_client
37+
self._ph_client = posthog_client or setup()
3738
self.messages = AsyncWrappedMessages(self)
3839

3940

posthog/ai/anthropic/anthropic_providers.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
"Please install the Anthropic SDK to use this feature: 'pip install anthropic'"
66
)
77

8+
from typing import Optional
9+
810
from posthog.ai.anthropic.anthropic import WrappedMessages
911
from posthog.ai.anthropic.anthropic_async import AsyncWrappedMessages
1012
from posthog.client import Client as PostHogClient
13+
from posthog import setup
1114

1215

1316
class AnthropicBedrock(anthropic.AnthropicBedrock):
@@ -17,9 +20,9 @@ class AnthropicBedrock(anthropic.AnthropicBedrock):
1720

1821
_ph_client: PostHogClient
1922

20-
def __init__(self, posthog_client: PostHogClient, **kwargs):
23+
def __init__(self, posthog_client: Optional[PostHogClient] = None, **kwargs):
2124
super().__init__(**kwargs)
22-
self._ph_client = posthog_client
25+
self._ph_client = posthog_client or setup()
2326
self.messages = WrappedMessages(self)
2427

2528

@@ -30,9 +33,9 @@ class AsyncAnthropicBedrock(anthropic.AsyncAnthropicBedrock):
3033

3134
_ph_client: PostHogClient
3235

33-
def __init__(self, posthog_client: PostHogClient, **kwargs):
36+
def __init__(self, posthog_client: Optional[PostHogClient] = None, **kwargs):
3437
super().__init__(**kwargs)
35-
self._ph_client = posthog_client
38+
self._ph_client = posthog_client or setup()
3639
self.messages = AsyncWrappedMessages(self)
3740

3841

@@ -43,9 +46,9 @@ class AnthropicVertex(anthropic.AnthropicVertex):
4346

4447
_ph_client: PostHogClient
4548

46-
def __init__(self, posthog_client: PostHogClient, **kwargs):
49+
def __init__(self, posthog_client: Optional[PostHogClient] = None, **kwargs):
4750
super().__init__(**kwargs)
48-
self._ph_client = posthog_client
51+
self._ph_client = posthog_client or setup()
4952
self.messages = WrappedMessages(self)
5053

5154

@@ -56,7 +59,7 @@ class AsyncAnthropicVertex(anthropic.AsyncAnthropicVertex):
5659

5760
_ph_client: PostHogClient
5861

59-
def __init__(self, posthog_client: PostHogClient, **kwargs):
62+
def __init__(self, posthog_client: Optional[PostHogClient] = None, **kwargs):
6063
super().__init__(**kwargs)
61-
self._ph_client = posthog_client
64+
self._ph_client = posthog_client or setup()
6265
self.messages = AsyncWrappedMessages(self)

posthog/ai/gemini/gemini.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"Please install the Google Gemini SDK to use this feature: 'pip install google-genai'"
1111
)
1212

13+
from posthog import setup
1314
from posthog.ai.utils import (
1415
call_llm_and_track_usage,
1516
get_model_params,
@@ -36,6 +37,8 @@ class Client:
3637
)
3738
"""
3839

40+
_ph_client: PostHogClient
41+
3942
def __init__(
4043
self,
4144
api_key: Optional[str] = None,
@@ -56,12 +59,14 @@ def __init__(
5659
posthog_groups: Default groups for all calls (can be overridden per call)
5760
**kwargs: Additional arguments (for future compatibility)
5861
"""
59-
if posthog_client is None:
62+
self._ph_client = posthog_client or setup()
63+
64+
if self._ph_client is None:
6065
raise ValueError("posthog_client is required for PostHog tracking")
6166

6267
self.models = Models(
6368
api_key=api_key,
64-
posthog_client=posthog_client,
69+
posthog_client=self._ph_client,
6570
posthog_distinct_id=posthog_distinct_id,
6671
posthog_properties=posthog_properties,
6772
posthog_privacy_mode=posthog_privacy_mode,
@@ -97,10 +102,10 @@ def __init__(
97102
posthog_groups: Default groups for all calls
98103
**kwargs: Additional arguments (for future compatibility)
99104
"""
100-
if posthog_client is None:
101-
raise ValueError("posthog_client is required for PostHog tracking")
105+
self._ph_client = posthog_client or setup()
102106

103-
self._ph_client = posthog_client
107+
if self._ph_client is None:
108+
raise ValueError("posthog_client is required for PostHog tracking")
104109

105110
# Store default PostHog settings
106111
self._default_distinct_id = posthog_distinct_id

posthog/ai/langchain/callbacks.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
from langchain_core.outputs import ChatGeneration, LLMResult
3434
from pydantic import BaseModel
3535

36-
from posthog import default_client
36+
from posthog import setup
3737
from posthog.ai.utils import get_model_params, with_privacy_mode
3838
from posthog.client import Client
3939

@@ -81,7 +81,7 @@ class CallbackHandler(BaseCallbackHandler):
8181
The PostHog LLM observability callback handler for LangChain.
8282
"""
8383

84-
_client: Client
84+
_ph_client: Client
8585
"""PostHog client instance."""
8686

8787
_distinct_id: Optional[Union[str, int, UUID]]
@@ -127,10 +127,7 @@ def __init__(
127127
privacy_mode: Whether to redact the input and output of the trace.
128128
groups: Optional additional PostHog groups to use for the trace.
129129
"""
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()
134131
self._distinct_id = distinct_id
135132
self._trace_id = trace_id
136133
self._properties = properties or {}
@@ -481,7 +478,7 @@ def _capture_trace_or_span(
481478
event_properties = {
482479
"$ai_trace_id": trace_id,
483480
"$ai_input_state": with_privacy_mode(
484-
self._client, self._privacy_mode, run.input
481+
self._ph_client, self._privacy_mode, run.input
485482
),
486483
"$ai_latency": run.latency,
487484
"$ai_span_name": run.name,
@@ -497,13 +494,13 @@ def _capture_trace_or_span(
497494
event_properties["$ai_is_error"] = True
498495
elif outputs is not None:
499496
event_properties["$ai_output_state"] = with_privacy_mode(
500-
self._client, self._privacy_mode, outputs
497+
self._ph_client, self._privacy_mode, outputs
501498
)
502499

503500
if self._distinct_id is None:
504501
event_properties["$process_person_profile"] = False
505502

506-
self._client.capture(
503+
self._ph_client.capture(
507504
distinct_id=self._distinct_id or run_id,
508505
event=event_name,
509506
properties=event_properties,
@@ -550,14 +547,16 @@ def _capture_generation(
550547
"$ai_provider": run.provider,
551548
"$ai_model": run.model,
552549
"$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+
),
554553
"$ai_http_status": 200,
555554
"$ai_latency": run.latency,
556555
"$ai_base_url": run.base_url,
557556
}
558557
if run.tools:
559558
event_properties["$ai_tools"] = with_privacy_mode(
560-
self._client,
559+
self._ph_client,
561560
self._privacy_mode,
562561
run.tools,
563562
)
@@ -589,7 +588,7 @@ def _capture_generation(
589588
_extract_raw_esponse(generation) for generation in generation_result
590589
]
591590
event_properties["$ai_output_choices"] = with_privacy_mode(
592-
self._client, self._privacy_mode, completions
591+
self._ph_client, self._privacy_mode, completions
593592
)
594593

595594
if self._properties:
@@ -598,7 +597,7 @@ def _capture_generation(
598597
if self._distinct_id is None:
599598
event_properties["$process_person_profile"] = False
600599

601-
self._client.capture(
600+
self._ph_client.capture(
602601
distinct_id=self._distinct_id or trace_id,
603602
event="$ai_generation",
604603
properties=event_properties,

posthog/ai/openai/openai.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
with_privacy_mode,
1616
)
1717
from posthog.client import Client as PostHogClient
18+
from posthog import setup
1819

1920

2021
class OpenAI(openai.OpenAI):
@@ -24,16 +25,15 @@ class OpenAI(openai.OpenAI):
2425

2526
_ph_client: PostHogClient
2627

27-
def __init__(self, posthog_client: PostHogClient, **kwargs):
28+
def __init__(self, posthog_client: Optional[PostHogClient] = None, **kwargs):
2829
"""
2930
Args:
3031
api_key: OpenAI API key.
31-
posthog_client: If provided, events will be captured via this client instead
32-
of the global posthog.
32+
posthog_client: If provided, events will be captured via this client instead of the global `posthog`.
3333
**openai_config: Any additional keyword args to set on openai (e.g. organization="xxx").
3434
"""
3535
super().__init__(**kwargs)
36-
self._ph_client = posthog_client
36+
self._ph_client = posthog_client or setup()
3737

3838
# Store original objects after parent initialization (only if they exist)
3939
self._original_chat = getattr(self, "chat", None)

posthog/ai/openai/openai_async.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import time
22
import uuid
3-
from typing import Any, Dict, List, Optional
3+
from typing import Any, Dict, List, Optional, cast
44

55
try:
66
import openai
@@ -9,6 +9,7 @@
99
"Please install the OpenAI SDK to use this feature: 'pip install openai'"
1010
)
1111

12+
from posthog import setup
1213
from posthog.ai.utils import (
1314
call_llm_and_track_usage_async,
1415
get_model_params,
@@ -24,7 +25,7 @@ class AsyncOpenAI(openai.AsyncOpenAI):
2425

2526
_ph_client: PostHogClient
2627

27-
def __init__(self, posthog_client: PostHogClient, **kwargs):
28+
def __init__(self, posthog_client: Optional[PostHogClient] = None, **kwargs):
2829
"""
2930
Args:
3031
api_key: OpenAI API key.
@@ -33,7 +34,7 @@ def __init__(self, posthog_client: PostHogClient, **kwargs):
3334
**openai_config: Any additional keyword args to set on openai (e.g. organization="xxx").
3435
"""
3536
super().__init__(**kwargs)
36-
self._ph_client = posthog_client
37+
self._ph_client = posthog_client or setup()
3738

3839
# Store original objects after parent initialization (only if they exist)
3940
self._original_chat = getattr(self, "chat", None)

0 commit comments

Comments
 (0)