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
5 changes: 5 additions & 0 deletions .sampo/changesets/ardent-earl-tuoni.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
pypi/posthog: patch
---

Fix internal imports for posthoganalytics mirror
50 changes: 50 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# AGENTS.md

Guidance for coding agents working in `posthog-python`.

## Repo context

- This repository contains the PostHog Python SDK, published as `posthog`.
- The main runtime package is `posthog/`; tests live under `posthog/test/`.
- The project uses `uv` for local development. See `CONTRIBUTING.md` for setup.
- Keep edits targeted and follow existing patterns. Prefer adding or updating tests near the behavior you change.

## Validation

Useful checks:

```bash
uv run ruff format --check .
uv run ruff check .
uv run mypy --no-site-packages --config-file mypy.ini . | uv run mypy-baseline filter
uv run pytest --verbose --timeout=30
uv run python -W error -c "import posthog"
```

For focused changes, run the smallest relevant `uv run pytest ...` command first.

If public API surface changes, update/check `references/public_api_snapshot.txt` with:

```bash
make public_api_snapshot
make public_api_check
```

## `posthoganalytics` mirror package

This repo also publishes `posthoganalytics`, a generated mirror of `posthog` used by the PostHog app. The mirror is created by copying `posthog/` to `posthoganalytics/` and rewriting absolute imports such as `from posthog.foo import ...` to `from posthoganalytics.foo import ...`.

Important when editing SDK-internal code:

- Prefer relative imports for imports within the SDK package, especially in runtime modules under `posthog/`.
- Good: `from .client import Client`, `from .exception_utils import extract_exception_properties`
- Risky: `from posthog.client import Client`
- Absolute `posthog...` imports inside SDK modules can break the `posthoganalytics` mirror when it is imported inside an application that also has its own `posthog` package/module on `sys.path`.
- Test mirror-sensitive changes by running the normal focused tests and, when relevant, `make prep_local` to generate a local `posthoganalytics` copy for testing in the PostHog app.
- Do not commit generated `posthoganalytics/` directories; they are build/local artifacts.

## Release/build notes

- `make build_release` builds the `posthog` distribution.
- `make build_release_analytics` builds the `posthoganalytics` distribution and temporarily rewrites/copies package files; ensure the working tree is clean before and after running it.
- Release flow publishes both packages; see `RELEASING.md`.
7 changes: 3 additions & 4 deletions posthog/contexts.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,14 @@ def _default_capture_exceptions(client: Optional["Client"] = None) -> bool:
if client is not None:
return client.enable_exception_autocapture

import posthog
from . import default_client, enable_exception_autocapture

default_client = getattr(posthog, "default_client", None)
if default_client is not None:
client_default = getattr(default_client, "enable_exception_autocapture", None)
if isinstance(client_default, bool):
return client_default

return posthog.enable_exception_autocapture
return enable_exception_autocapture


@contextmanager
Expand Down Expand Up @@ -197,7 +196,7 @@ def new_context(
Category:
Contexts
"""
from posthog import capture_exception
from . import capture_exception

current_context = _get_current_context()
resolved_capture_exceptions = (
Expand Down
8 changes: 4 additions & 4 deletions posthog/integrations/celery.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@
import time
from typing import Any, Callable, Optional

from posthog import contexts
from posthog.client import Client
from .. import contexts
from ..client import Client


CONTEXT_DISTINCT_ID_HEADER = "X-POSTHOG-DISTINCT-ID"
Expand Down Expand Up @@ -198,9 +198,9 @@ def shutdown(self) -> None:
if self.client:
self.client.flush()
else:
import posthog
from .. import flush

posthog.flush()
flush()

self.uninstrument()
self._shut_down = True
Expand Down
4 changes: 2 additions & 2 deletions posthog/integrations/django.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import re
from typing import TYPE_CHECKING, Optional, cast

from posthog import contexts
from posthog.client import Client
from .. import contexts
from ..client import Client

try:
from asgiref.sync import iscoroutinefunction, markcoroutinefunction
Expand Down
Loading