You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs(capture): document capture_mode, capture_compression, and changeset
Adds the Sampo changeset for the opt-in capture_mode (v1 ingestion
protocol) and capture_compression, plus an AGENTS.md section mapping
capture_mode/capture_compression and their env vars to the modules and
routing that implement them, the v1 invariants to preserve, and the
sync_mode blocking-retry behavior.
User-facing usage stays in the official docs per the README convention.
Add an opt-in `capture_mode` for the Capture V1 ingestion protocol (`POST /i/v1/analytics/events`). Set `capture_mode="v1"` on the client (or the `POSTHOG_CAPTURE_MODE=v1` environment variable) to use Bearer auth, per-event results, and partial retry. Defaults to `"v0"` (the legacy `/batch/` endpoint), so existing setups are unaffected.
6
+
7
+
When using `capture_mode="v1"`, request bodies can be compressed via `capture_compression` (or `POSTHOG_CAPTURE_COMPRESSION`): `"gzip"`, `"deflate"`, or `"none"` (default). The legacy `gzip=True` flag is honored as a fallback.
Copy file name to clipboardExpand all lines: AGENTS.md
+20Lines changed: 20 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,6 +9,26 @@ Guidance for coding agents working in `posthog-python`.
9
9
- The project uses `uv` for local development. See `CONTRIBUTING.md` for setup.
10
10
- Keep edits targeted and follow existing patterns. Prefer adding or updating tests near the behavior you change.
11
11
12
+
## Capture protocol (`capture_mode`)
13
+
14
+
The client supports two ingestion wire protocols, selected by `capture_mode` (precedence: explicit `Client(capture_mode=...)` kwarg > `POSTHOG_CAPTURE_MODE` env var > default).
-`"v1"` — `POST /i/v1/analytics/events`: Bearer auth, a typed event `options` object, per-event results, and partial retry.
18
+
19
+
v1 request bodies can additionally be compressed via `capture_compression` (precedence: explicit `Client(capture_compression=...)` kwarg > `POSTHOG_CAPTURE_COMPRESSION` env var > the legacy `gzip` flag > none). Supported values are `"none"`, `"gzip"`, and `"deflate"` (zlib-wrapped, RFC 1950, to match the server's decoder and the Go/Rust SDKs). v0 keeps using its own `gzip` flag; `capture_compression` is v1-only.
20
+
21
+
Where the pieces live:
22
+
23
+
-`posthog/capture_mode.py` — the `CaptureMode` enum and `resolve_capture_mode()` precedence logic.
24
+
-`posthog/capture_compression.py` — the `CaptureCompression` enum and `resolve_capture_compression()` precedence logic (with `gzip` fallback).
25
+
-`posthog/capture_v1.py` — pure transforms (`to_v1_event`, `build_v1_batch_body`) and transport (`post_v1`, `_compress_v1`, `parse_v1_response`, `send_v1_batch`, `CaptureV1Error`).
26
+
- Routing: `Consumer._send_analytics` (async) and `Client._enqueue` (sync) pick the analytics submitter by `capture_mode`. The dedicated `$ai_*` endpoint has no v1 form and always uses the legacy submitter.
27
+
28
+
v1-specific behavior to preserve when editing: sentinel `$`-properties are lifted into `options` (coerced to native JSON types or omitted — a wrong type 400s the whole batch); top-level `$set`/`$set_once` are relocated into `properties`; only events the server tags `retry` are resent (stable `PostHog-Request-Id`/`created_at`, incrementing `PostHog-Attempt`); `429` is terminal.
29
+
30
+
Retry blocking matches v0: in the default async mode retries happen on the background consumer thread, but with `sync_mode=True` the partial-retry loop (including its backoff sleeps) runs inline on the calling thread, so a slow/erroring endpoint blocks the caller until retries are exhausted.
0 commit comments