Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: set posthoganalytics key in asgi #28627

Merged
merged 6 commits into from
Feb 13, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
22 changes: 21 additions & 1 deletion posthog/asgi.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import os

from django.conf import settings
from django.core.asgi import get_asgi_application
from django.http.response import HttpResponse

Expand All @@ -18,4 +20,22 @@
return inner


application = lifetime_wrapper(get_asgi_application())
# PostHogConfig.ready() handles setting the global analytics key in WSGI. The same code couldn't run
# in ASGI because ready() doesn't expose an async interface.
def wrap_debug_analytics(func):
async def inner(scope, receive, send):
if not getattr(inner, "debug_analytics_initialized", False):
from posthog.utils import aset_debugging_analytics_key

This comment was marked as resolved.


await aset_debugging_analytics_key()
# Set a flag to indicate that the analytics key has been set, so we don't run the code on every request.
inner.debug_analytics_initialized = True

Check failure on line 32 in posthog/asgi.py

View workflow job for this annotation

GitHub Actions / Python code quality checks

"Callable[[Any, Any, Any], Any]" has no attribute "debug_analytics_initialized"
return await func(scope, receive, send)

return inner


if settings.DEBUG:
application = lifetime_wrapper(wrap_debug_analytics(get_asgi_application()))
else:
application = lifetime_wrapper(get_asgi_application())
33 changes: 32 additions & 1 deletion posthog/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@
from rest_framework import serializers
from rest_framework.request import Request
from sentry_sdk import configure_scope
from posthog.exceptions_capture import capture_exception

from posthog.cloud_utils import get_cached_instance_license, is_cloud
from posthog.constants import AvailableFeature
from posthog.exceptions import (
RequestParsingError,
UnspecifiedCompressionFallbackParsingError,
)
from posthog.exceptions_capture import capture_exception
from posthog.git import get_git_branch, get_git_commit_short
from posthog.metrics import KLUDGES_COUNTER
from posthog.redis import get_client
Expand Down Expand Up @@ -517,6 +517,37 @@ def get_self_capture_api_token(user: Optional[Union["AbstractBaseUser", "Anonymo
return None


async def aset_debugging_analytics_key():
"""
ASGI alternative to get_self_capture_api_token.
"""
from django.apps import apps

User = apps.get_model("posthog", "User")
Team = apps.get_model("posthog", "Team")
try:
user = (
await User.objects.filter(last_login__isnull=False)
.order_by("-last_login")
.select_related("current_team")
.afirst()
)
# Get the current user's team (or first team in the instance) to set self capture configs
team = None
if user and getattr(user, "team", None):
team = user.current_team
else:
Twixes marked this conversation as resolved.
Show resolved Hide resolved
team = await Team.objects.only("api_token").afirst()
local_api_key = team.api_token
except:

This comment was marked as resolved.

local_api_key = None
# apps.ready() is already called, so reset the already set config.
if local_api_key is not None:
posthoganalytics.api_key = local_api_key
posthoganalytics.host = settings.SITE_URL
posthoganalytics.disabled = False


def get_default_event_name(team: "Team"):
from posthog.models import EventDefinition

Expand Down
Loading