Coverage for app/analytics/posthog.py: 93%
27 statements
« prev ^ index » next coverage.py v7.6.10, created at 2026-06-04 22:29 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2026-06-04 22:29 +0000
1import json
2from urllib.error import HTTPError, URLError
3from urllib.request import Request, urlopen
4from uuid import uuid4
6from app.core.config import settings
7from app.core.logger import logger
8from app.normalization import normalize_package_name
11def capture_package_requested_events(
12 packages: list[str],
13 time_range: str,
14 show_percentage: bool,
15 hx_trigger: str | None,
16 request_id: str | None = None,
17) -> None:
18 if not settings.ENABLE_SERVER_ANALYTICS:
19 return
21 if settings.POSTHOG_API_KEY is None:
22 logger.warning("Skipping PostHog package analytics: missing API key")
23 return
25 normalized_packages = sorted(
26 normalize_package_name(package) for package in packages if package.strip()
27 )
29 if not normalized_packages:
30 return
32 normalized_request_id = request_id or str(uuid4())
34 capture_url = f"{str(settings.POSTHOG_HOST).rstrip('/')}/capture/"
36 for package in normalized_packages:
37 payload = {
38 "api_key": settings.POSTHOG_API_KEY,
39 "event": "package_requested",
40 "distinct_id": "server",
41 "properties": {
42 "package": package,
43 "packages": normalized_packages,
44 "time_range": time_range,
45 "show_percentage": show_percentage,
46 "hx_trigger": hx_trigger,
47 "request_id": normalized_request_id,
48 "source": "server_htmx",
49 },
50 }
52 try:
53 req = Request(
54 capture_url,
55 data=json.dumps(payload).encode("utf-8"),
56 headers={"Content-Type": "application/json"},
57 method="POST",
58 )
59 with urlopen(req, timeout=2):
60 pass
61 logger.info(
62 "Submitted PostHog package_requested event "
63 f"for package='{package}', packages={normalized_packages}, "
64 f"time_range='{time_range}', hx_trigger='{hx_trigger}', "
65 f"request_id='{normalized_request_id}'"
66 )
67 except (HTTPError, URLError, TimeoutError) as e:
68 logger.warning(
69 f"Failed to capture PostHog event for package '{package}': {e}"
70 )