Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 6.2.1 - 2025-06-21

- feat: make `posthog_client` an optional argument in PostHog AI providers wrappers (`posthog.ai.*`), intuitively using the default client as the default

# 6.1.1 - 2025-07-16

- fix: correctly capture exceptions processed by Django from views or middleware
Expand Down
4 changes: 3 additions & 1 deletion posthog/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ def shutdown():
_proxy("join")


def setup():
def setup() -> Client:
global default_client
if not default_client:
if not api_key:
Expand Down Expand Up @@ -706,6 +706,8 @@ def setup():
default_client.disabled = disabled
default_client.debug = debug

return default_client


def _proxy(method, *args, **kwargs):
"""Create an analytics client if one doesn't exist and send to it."""
Expand Down
7 changes: 4 additions & 3 deletions posthog/ai/anthropic/anthropic.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import time
import uuid
from typing import Any, Dict, Optional
from typing import Any, Dict, Optional, cast

from posthog.ai.utils import (
call_llm_and_track_usage,
Expand All @@ -17,6 +17,7 @@
with_privacy_mode,
)
from posthog.client import Client as PostHogClient
from posthog import setup


class Anthropic(anthropic.Anthropic):
Expand All @@ -26,14 +27,14 @@ class Anthropic(anthropic.Anthropic):

_ph_client: PostHogClient

def __init__(self, posthog_client: PostHogClient, **kwargs):
def __init__(self, posthog_client: Optional[PostHogClient] = None, **kwargs):
"""
Args:
posthog_client: PostHog client for tracking usage
**kwargs: Additional arguments passed to the Anthropic client
"""
super().__init__(**kwargs)
self._ph_client = posthog_client
self._ph_client = posthog_client or setup()
self.messages = WrappedMessages(self)


Expand Down
5 changes: 3 additions & 2 deletions posthog/ai/anthropic/anthropic_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import uuid
from typing import Any, Dict, Optional

from posthog import setup
from posthog.ai.utils import (
call_llm_and_track_usage_async,
get_model_params,
Expand All @@ -26,14 +27,14 @@ class AsyncAnthropic(anthropic.AsyncAnthropic):

_ph_client: PostHogClient

def __init__(self, posthog_client: PostHogClient, **kwargs):
def __init__(self, posthog_client: Optional[PostHogClient] = None, **kwargs):
"""
Args:
posthog_client: PostHog client for tracking usage
**kwargs: Additional arguments passed to the Anthropic client
"""
super().__init__(**kwargs)
self._ph_client = posthog_client
self._ph_client = posthog_client or setup()
self.messages = AsyncWrappedMessages(self)


Expand Down
19 changes: 11 additions & 8 deletions posthog/ai/anthropic/anthropic_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
"Please install the Anthropic SDK to use this feature: 'pip install anthropic'"
)

from typing import Optional

from posthog.ai.anthropic.anthropic import WrappedMessages
from posthog.ai.anthropic.anthropic_async import AsyncWrappedMessages
from posthog.client import Client as PostHogClient
from posthog import setup


class AnthropicBedrock(anthropic.AnthropicBedrock):
Expand All @@ -17,9 +20,9 @@ class AnthropicBedrock(anthropic.AnthropicBedrock):

_ph_client: PostHogClient

def __init__(self, posthog_client: PostHogClient, **kwargs):
def __init__(self, posthog_client: Optional[PostHogClient] = None, **kwargs):
super().__init__(**kwargs)
self._ph_client = posthog_client
self._ph_client = posthog_client or setup()
self.messages = WrappedMessages(self)


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

_ph_client: PostHogClient

def __init__(self, posthog_client: PostHogClient, **kwargs):
def __init__(self, posthog_client: Optional[PostHogClient] = None, **kwargs):
super().__init__(**kwargs)
self._ph_client = posthog_client
self._ph_client = posthog_client or setup()
self.messages = AsyncWrappedMessages(self)


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

_ph_client: PostHogClient

def __init__(self, posthog_client: PostHogClient, **kwargs):
def __init__(self, posthog_client: Optional[PostHogClient] = None, **kwargs):
super().__init__(**kwargs)
self._ph_client = posthog_client
self._ph_client = posthog_client or setup()
self.messages = WrappedMessages(self)


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

_ph_client: PostHogClient

def __init__(self, posthog_client: PostHogClient, **kwargs):
def __init__(self, posthog_client: Optional[PostHogClient] = None, **kwargs):
super().__init__(**kwargs)
self._ph_client = posthog_client
self._ph_client = posthog_client or setup()
self.messages = AsyncWrappedMessages(self)
15 changes: 10 additions & 5 deletions posthog/ai/gemini/gemini.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"Please install the Google Gemini SDK to use this feature: 'pip install google-genai'"
)

from posthog import setup
from posthog.ai.utils import (
call_llm_and_track_usage,
get_model_params,
Expand All @@ -36,6 +37,8 @@ class Client:
)
"""

_ph_client: PostHogClient

def __init__(
self,
api_key: Optional[str] = None,
Expand All @@ -56,12 +59,14 @@ def __init__(
posthog_groups: Default groups for all calls (can be overridden per call)
**kwargs: Additional arguments (for future compatibility)
"""
if posthog_client is None:
self._ph_client = posthog_client or setup()

if self._ph_client is None:
raise ValueError("posthog_client is required for PostHog tracking")

self.models = Models(
api_key=api_key,
posthog_client=posthog_client,
posthog_client=self._ph_client,
posthog_distinct_id=posthog_distinct_id,
posthog_properties=posthog_properties,
posthog_privacy_mode=posthog_privacy_mode,
Expand Down Expand Up @@ -97,10 +102,10 @@ def __init__(
posthog_groups: Default groups for all calls
**kwargs: Additional arguments (for future compatibility)
"""
if posthog_client is None:
raise ValueError("posthog_client is required for PostHog tracking")
self._ph_client = posthog_client or setup()

self._ph_client = posthog_client
if self._ph_client is None:
raise ValueError("posthog_client is required for PostHog tracking")

# Store default PostHog settings
self._default_distinct_id = posthog_distinct_id
Expand Down
8 changes: 4 additions & 4 deletions posthog/ai/openai/openai.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
with_privacy_mode,
)
from posthog.client import Client as PostHogClient
from posthog import setup


class OpenAI(openai.OpenAI):
Expand All @@ -24,16 +25,15 @@ class OpenAI(openai.OpenAI):

_ph_client: PostHogClient

def __init__(self, posthog_client: PostHogClient, **kwargs):
def __init__(self, posthog_client: Optional[PostHogClient] = None, **kwargs):
"""
Args:
api_key: OpenAI API key.
posthog_client: If provided, events will be captured via this client instead
of the global posthog.
posthog_client: If provided, events will be captured via this client instead of the global `posthog`.
**openai_config: Any additional keyword args to set on openai (e.g. organization="xxx").
"""
super().__init__(**kwargs)
self._ph_client = posthog_client
self._ph_client = posthog_client or setup()

# Store original objects after parent initialization (only if they exist)
self._original_chat = getattr(self, "chat", None)
Expand Down
7 changes: 4 additions & 3 deletions posthog/ai/openai/openai_async.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import time
import uuid
from typing import Any, Dict, List, Optional
from typing import Any, Dict, List, Optional, cast

try:
import openai
Expand All @@ -9,6 +9,7 @@
"Please install the OpenAI SDK to use this feature: 'pip install openai'"
)

from posthog import setup
from posthog.ai.utils import (
call_llm_and_track_usage_async,
get_model_params,
Expand All @@ -24,7 +25,7 @@ class AsyncOpenAI(openai.AsyncOpenAI):

_ph_client: PostHogClient

def __init__(self, posthog_client: PostHogClient, **kwargs):
def __init__(self, posthog_client: Optional[PostHogClient] = None, **kwargs):
"""
Args:
api_key: OpenAI API key.
Expand All @@ -33,7 +34,7 @@ def __init__(self, posthog_client: PostHogClient, **kwargs):
**openai_config: Any additional keyword args to set on openai (e.g. organization="xxx").
"""
super().__init__(**kwargs)
self._ph_client = posthog_client
self._ph_client = posthog_client or setup()

# Store original objects after parent initialization (only if they exist)
self._original_chat = getattr(self, "chat", None)
Expand Down
11 changes: 7 additions & 4 deletions posthog/ai/openai/openai_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
from posthog.ai.openai.openai_async import WrappedChat as AsyncWrappedChat
from posthog.ai.openai.openai_async import WrappedEmbeddings as AsyncWrappedEmbeddings
from posthog.ai.openai.openai_async import WrappedResponses as AsyncWrappedResponses
from typing import Optional

from posthog.client import Client as PostHogClient
from posthog import setup


class AzureOpenAI(openai.AzureOpenAI):
Expand All @@ -25,7 +28,7 @@ class AzureOpenAI(openai.AzureOpenAI):

_ph_client: PostHogClient

def __init__(self, posthog_client: PostHogClient, **kwargs):
def __init__(self, posthog_client: Optional[PostHogClient] = None, **kwargs):
"""
Args:
api_key: Azure OpenAI API key.
Expand All @@ -34,7 +37,7 @@ def __init__(self, posthog_client: PostHogClient, **kwargs):
**openai_config: Any additional keyword args to set on Azure OpenAI (e.g. azure_endpoint="xxx").
"""
super().__init__(**kwargs)
self._ph_client = posthog_client
self._ph_client = posthog_client or setup()

# Store original objects after parent initialization (only if they exist)
self._original_chat = getattr(self, "chat", None)
Expand Down Expand Up @@ -63,7 +66,7 @@ class AsyncAzureOpenAI(openai.AsyncAzureOpenAI):

_ph_client: PostHogClient

def __init__(self, posthog_client: PostHogClient, **kwargs):
def __init__(self, posthog_client: Optional[PostHogClient] = None, **kwargs):
"""
Args:
api_key: Azure OpenAI API key.
Expand All @@ -72,7 +75,7 @@ def __init__(self, posthog_client: PostHogClient, **kwargs):
**openai_config: Any additional keyword args to set on Azure OpenAI (e.g. azure_endpoint="xxx").
"""
super().__init__(**kwargs)
self._ph_client = posthog_client
self._ph_client = posthog_client or setup()

# Store original objects after parent initialization (only if they exist)
self._original_chat = getattr(self, "chat", None)
Expand Down
2 changes: 1 addition & 1 deletion posthog/version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VERSION = "6.1.1"
VERSION = "6.2.1"

if __name__ == "__main__":
print(VERSION, end="") # noqa: T201
Loading