Repository navigation
feat: add runtime opt-out for capture - #1047
Draft
posthog[bot] wants to merge 1 commit into
Draft
posthog[bot] wants to merge 1 commit into
posthog[bot] wants to merge 1 commit into
Conversation
The capture contract requires an opt-out state that drops events silently with no network request, but the SDK only had the constructor-time `disabled` kill switch, which cannot be toggled at runtime. Add `opt_out_capturing()`, `opt_in_capturing()` and `is_opted_out()` on `Client` (and the matching module-level helpers). The gate lives in `_enqueue`, so every event-producing API short-circuits while opted out. Feature flag evaluation and other non-capture APIs are unaffected. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: da91345a-57f0-47dd-a7ae-1f0a25bbc6fd
Contributor
posthog-python Compliance ReportDate: 2026-10-10T06:15:57.636143+00:00 ✅ All Tests Passed!121/121 tests passed Capture_V1 Tests✅ 95/95 tests passed View Details
Capture_Ai Tests✅ 5/5 tests passed View Details
Feature_Flags Tests✅ 17/17 tests passed View Details
Feature_Flags_Local_Evaluation Tests✅ 4/4 tests passed View Details
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
💡 Motivation and Context
Why: This came out of the cross-SDK compliance matrix in PostHog/sdk-specs — posthog-python is marked 🟡 Partial on the Capture contract because it has no runtime opt-out.
The capture spec requires an opt-out short-circuit:
The acceptance scenario
Capture honors opt-out state(acceptance/public/capture.feature) is tagged@both, so it applies to server SDKs too.The matrix note (
compliance/posthog-python.md, n4 — Capture):What changed
Client.opt_out_capturing(),Client.opt_in_capturing()andClient.is_opted_out(), plus the matching module-level helpers on the global client.Client._enqueue, which every event-producing API (capture,capture_ai,capture_exception,set,set_once,group_identify,alias) already funnels through — so one check covers them all, and events are dropped before anything is queued or sent.*_capturingnaming and the browser SDK'sopt_in_capturing()/opt_out_capturing()surface.Backwards compatibility
Purely additive. Three new methods, no signature or behavior change for any existing caller — a client that never calls
opt_out_capturing()behaves exactly as before. The state is independent of the constructor-timedisabledkill switch:opt_in_capturing()does not re-enable a client constructed withdisabled=True(covered by a test).Note the state is in-memory per client and does not survive a process restart, which is what the spec describes for server SDKs ("in-memory server-side"). Applications that need it to persist should store the user's choice themselves and re-apply it at startup; this is documented on the methods.
💚 How did you test it?
posthog/test/test_client.py: events dropped with no network request while opted out (acrosscapture/set/alias/group_identify), capture resumes afteropt_in_capturing(),opt_in_capturing()does not revive adisabled=Trueclient, and feature flags keep working while opted out.posthog/test/test_module.pycovering the global-client helpers.ruff format --check .,ruff check .,mypy ... | mypy-baseline filter(clean),python -W error -c "import posthog",make public_api_check, and the fullpytestsuite — 4545 passed. The only 8 failures are pre-existing AI integration tests (posthog/test/ai/openai,anthropic,langchain) that need live provider credentials; they are untouched by this change.references/public_api_snapshot.txtregenerated viamake public_api_snapshot(3 new functions, 3 new methods).📝 Checklist
If releasing new changes
sampo addto generate a changeset file🤖 Agent context
Autonomy: Fully autonomous
Produced by a scheduled agent run that reads the compliance matrices in
PostHog/sdk-specs, ranks the open 🟡/❌ cells, and implements one backward-compatible gap per run. Tooling: Claude Code with shell, GitHub CLI and the repo's ownmake/uvchecks.Decisions along the way: several higher-ranked candidates were dropped after checking the actual repos — the .NET malformed-payload gap and the Ruby
FeatureFlagEvaluations#enabled?default-value gap are already fixed on theirmainbranches (the matrix notes are stale), and the posthog-js exception-metadata and posthog-go MCP exception gaps already have work in flight. Within this change, the gate was placed in_enqueuerather than in each public capture method so no path can be missed, and the scope was kept to capture only (flags untouched) to match the spec's wording and the*_capturingnaming.Follow-up work
opt-in/is-opt-outspecs are currently scopedclient; if the server-side half of this behavior should be specified too, that is a change forsdk-specs, not this repo.Created with PostHog Desktop
🤖 Generated with Claude Code