Add OpenFeature (Python) feature flags provider docs#18006
Merged
gustavohstrassburger merged 1 commit intoJul 1, 2026
Conversation
Documents the official PostHog OpenFeature provider for Python (`openfeature-provider-posthog`), which the posthog-python provider README now points to as the single source of truth. - New page contents/docs/feature-flags/installation/openfeature.mdx covering install, usage/registration, evaluation-context mapping, supported flag types, and provider options. - Register it in the feature-flags Installation nav (after Python). Generated-By: PostHog Code Task-Id: 392fb0da-49bb-4c96-96c7-1b39b0348d32
Contributor
|
Vale prose linter → found 3 errors, 1 warnings, 0 suggestions in your markdown Full report → Copy the linter results into an LLM to batch-fix issues. Linter being weird? Update the rules!
|
| Line | Severity | Message | Rule |
|---|---|---|---|
| 11:118 | warning | Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. | PostHogBase.ProductNames |
| 49:38 | error | Hi, Andy here... use an en dash ( – ) with spaces. On Mac, holding down the Option and hyphen key will give you an en dash. | PostHogBase.EnDash |
| 79:25 | error | Hi, Andy here... use an en dash ( – ) with spaces. On Mac, holding down the Option and hyphen key will give you an en dash. | PostHogBase.EnDash |
| 80:30 | error | Hi, Andy here... use an en dash ( – ) with spaces. On Mac, holding down the Option and hyphen key will give you an en dash. | PostHogBase.EnDash |
Contributor
Deploy preview
|
Contributor
Bundle reportTotal JS (gzip)6.22 MiB (+0.0 KiB / +0.0%) Eager graph (static-import closure per entrypoint)
Largest modules in the
|
| Module | Size |
|---|---|
css ./node_modules/.pnpm/css-loader@5.2.7_webpack@5.101.3/node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[8].oneOf[1].use[1]!./node_modules/.pnpm/postcss-loader@4.3.0_postcss@8.5.6_webpack@5.101.3/node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[8].oneOf[1].use[2]!./src/styles/global.css |
710.3 KiB |
./src/components/Stickers/Stickers.tsx |
696.4 KiB |
./.cache/caches/gatsby-plugin-mdx/mdx-scopes-dir/31a094f140f119e73085d847ae81b99b.js + 2 modules |
553.6 KiB |
./node_modules/.pnpm/@radix-ui+react-icons@1.3.2_react@18.3.1/node_modules/@radix-ui/react-icons/dist/react-icons.esm.js |
481.4 KiB |
./node_modules/.pnpm/@codemirror+view@6.38.2/node_modules/@codemirror/view/dist/index.js |
458.1 KiB |
./node_modules/.pnpm/rehype-raw@7.0.0/node_modules/rehype-raw/lib/index.js + 29 modules |
395.1 KiB |
./node_modules/.pnpm/@posthog+icons@0.36.6_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.cjs.js |
364.8 KiB |
./node_modules/.pnpm/@posthog+icons@0.36.6_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
354.8 KiB |
./src/hooks/useCustomers.tsx + 54 modules |
353.9 KiB |
./node_modules/.pnpm/react-markdown@8.0.7_@types+react@16.14.66_react@18.3.1/node_modules/react-markdown/lib/react-markdown.js + 88 modules |
351.4 KiB |
./node_modules/.pnpm/cloudinary-core@2.14.0_lodash@4.17.21/node_modules/cloudinary-core/cloudinary-core.js |
281.9 KiB |
./src/components/ProductComparisonTable/index.tsx + 116 modules |
267.6 KiB |
./node_modules/.pnpm/@codesandbox+sandpack-react@2.20.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@codesandbox/sandpack-react/dist/index.mjs |
266.6 KiB |
./node_modules/.pnpm/d3@7.9.0/node_modules/d3/src/index.js + 208 modules |
247.4 KiB |
./src/components/Pricing/PricingSlider/Slider.tsx + 87 modules |
239.9 KiB |
Eager-graph budgets are report-only until a baseline is established. Sizes are gzip of public/**/*.js; eager size is webpack module source bytes.
gustavohstrassburger
added a commit
to PostHog/posthog-python
that referenced
this pull request
Jun 29, 2026
Per review: don't keep a separate provider README that drifts — point to the PostHog docs (single source of truth) instead. Companion docs page is added in PostHog/posthog.com#18006. - Delete openfeature-provider/README.md. - pyproject: drop the `readme` field (it referenced the deleted file) and add a Documentation URL so the PyPI page links straight to the docs. - Root README: the OpenFeature entry now links to https://posthog.com/docs/feature-flags/installation/openfeature instead of the in-repo provider README. uv build + twine check still pass (only a non-fatal missing-long_description warning, expected without a README). Generated-By: PostHog Code Task-Id: 392fb0da-49bb-4c96-96c7-1b39b0348d32
gustavohstrassburger
added a commit
to PostHog/posthog-python
that referenced
this pull request
Jun 30, 2026
* Add official PostHog OpenFeature provider Adds an official PostHog provider for the OpenFeature Python SDK, shipped as a separate distribution (`openfeature-provider-posthog`) under the OpenFeature namespace package `openfeature.contrib.provider.posthog`, living in this repo alongside the SDK. The provider wraps a configured `posthog.Posthog` client and resolves all five OpenFeature flag types via the modern, non-deprecated `get_feature_flag_result` (one call yields value + variant + payload + reason): - boolean -> `enabled` - string -> the multivariate variant key - int/float -> the variant parsed as a number - object -> the flag's JSON payload (full object/JSON support) Evaluation context maps `targeting_key` -> `distinct_id`, reserved attributes `groups`/`group_properties` -> PostHog groups, and all other attributes -> `person_properties`. A missing targeting key raises `TargetingKeyMissingError` unless `default_distinct_id` is set; type mismatches raise `TypeMismatchError` so the OpenFeature client returns the caller's default per spec. Repo wiring: - New `openfeature-provider` CI job (mirrors the django5 integration job): uv sync, pytest, ruff, mypy, build + twine check in the sub-project's own env. - `mypy.ini`: exclude `openfeature-provider/.*` from the root mypy pass (the namespace tree is type-checked in its own env where openfeature-sdk is present). - README link to the provider. The new top-level `openfeature/` tree is isolated from the `posthog` build (explicit packages list) and from the `posthog.*`-scoped public-API snapshot. Generated-By: PostHog Code Task-Id: 392fb0da-49bb-4c96-96c7-1b39b0348d32 * Address review: reason mapping, init logging, parametrized tests - _map_reason: a disabled (enabled=False) result now maps to Reason.DEFAULT (the flag is active but no targeting condition matched), reserving Reason.DISABLED for when the reason text says the flag itself is off. PostHog returns None (-> FlagNotFoundError) for archived/missing flags. - initialize: log a WARNING (with exc_info) instead of silently swallowing a load_feature_flags() failure, so a misconfigured personal_api_key / host / permissions is visible while still falling back to remote evaluation. - tests: collapse the boolean reason-mapping and number-parsing cases into @pytest.mark.parametrize, and add coverage for the initialize logging paths. Generated-By: PostHog Code Task-Id: 392fb0da-49bb-4c96-96c7-1b39b0348d32 * Address review: add missing tests and optimize _map_reason * Address review: non-enrollment returns default, _details helper, docs Addresses review feedback from @haacked and @marandaneto. - Correctness (haacked + marandaneto): a user who matches no condition or a disabled flag (enabled=False, with no variant/object payload) is no longer reported as a TYPE_MISMATCH error. The string/integer/float/object resolvers now return the caller's default with a normal reason (DEFAULT/DISABLED) in that case, and only raise TypeMismatchError for a genuine mismatch (enabled=True but the value can't be coerced to the requested type). Applied consistently across string, number, and object. - Refactor (haacked): extract a shared `_details()` helper for the repeated reason/flag_metadata wiring across the typed resolvers. - Tests (haacked): add non-dict `groups`/`group_properties` coercion cases asserting they are forwarded as None; add detail tests asserting unmatched string/number/object resolution returns the default with no error_code. - Docs (marandaneto): slim the README to a minimal quickstart and point to https://posthog.com/docs/feature-flags as the single source of truth. Generated-By: PostHog Code Task-Id: 392fb0da-49bb-4c96-96c7-1b39b0348d32 * Wire openfeature-provider into release + CI, pin posthog Implements the remaining review suggestions from @marandaneto. - Release (release.yml): publish `openfeature-provider-posthog` as a second distribution. Sampo already auto-discovers the package (it has its own pyproject), so the new steps only build/publish/tag the provider when this release actually bumped its version (a changeset targeting `pypi/openfeature-provider-posthog`). posthog-only releases skip them, and they run after the posthog publish/tag/release so they can never block the core release. Uses the same PyPI OIDC trusted-publishing action as posthog/posthoganalytics (a trusted publisher for the new project must be registered before the first provider release). - Sampo: add openfeature-provider/CHANGELOG.md for Sampo to maintain. - CI (ci.yml): add a clean-env smoke test that installs the built wheel and imports openfeature.contrib.provider.posthog, catching namespace-packaging regressions that source-tree tests miss. - pyproject: pin posthog to the tested major (>=7.0.0,<8.0.0); the local-branch build via [tool.uv.sources] was already in place. Generated-By: PostHog Code Task-Id: 392fb0da-49bb-4c96-96c7-1b39b0348d32 * Make openfeature-provider a uv workspace member so Sampo manages it Fixes the release/versioning gap @marandaneto found: `sampo add -p pypi/openfeature-provider-posthog` failed with "not found in the workspace". Sampo's PyPI adapter only discovers packages listed in the root pyproject's [tool.uv.workspace] members (plus the root) — there is no auto-discovery — so the provider was invisible to Sampo and the release detection never triggered. - Root pyproject: declare a uv workspace with `members = ["openfeature-provider"]`. Sampo now discovers `pypi/openfeature-provider-posthog`, so `sampo add` works and `sampo release` bumps openfeature-provider/pyproject.toml from a changeset. The root uv.lock change is purely additive (only the member + openfeature-sdk; no churn to existing posthog pins), and the main `posthog` build is unaffected (explicit packages list). - Provider pyproject: resolve posthog via `{ workspace = true }` instead of a path source; drop the now-redundant standalone uv.lock (the workspace shares the root lock). - CI: the provider job now matrixes Python 3.10–3.14 (matching the main package, per @marandaneto/@haacked) and uses workspace-aware commands (`--package openfeature-provider-posthog`, `uv build --out-dir dist`). - release.yml: build the provider with `--package ... --out-dir dist` so its artifacts stay isolated from the posthog dist. Verified locally: root posthog sync + import, provider sync/tests (37)/ruff/mypy/ build/twine/clean-env-import across the workspace, and the django5 integration project (not a member) still syncs standalone. Sampo itself couldn't be run here (no cargo), but the config matches exactly what its pip adapter parses. Generated-By: PostHog Code Task-Id: 392fb0da-49bb-4c96-96c7-1b39b0348d32 * Release matrix for N packages; docs-only README + provider CONTRIBUTING Addresses further review from @marandaneto. - release.yml: restructure into the canonical PostHog multi-package shape (cf. posthog-ruby). A single approval-gated `version-bump` job (environment "Release") bumps versions, commits, and regenerates references; a separate `publish` job with no environment runs a `package` matrix (fail-fast, max-parallel 1) over posthog, posthoganalytics, and openfeature-provider-posthog. Each entry detects whether its version changed in the release commit and only then builds/publishes/tags. Keeping the approval on version-bump (not the matrix) preserves a single approval per release. NOTE: the no-environment publish job means each package's PyPI trusted publisher must point at the `publish` job (not an environment) — a one-time PyPI-side config matraneto/maintainers control. - README: drop the install/quickstart snippets that drift; point to https://posthog.com/docs/feature-flags (OpenFeature section) as the single source of truth. - Move the development instructions out of the README into a dedicated openfeature-provider/CONTRIBUTING.md with the workspace-aware commands. Generated-By: PostHog Code Task-Id: 392fb0da-49bb-4c96-96c7-1b39b0348d32 * Drop provider README; point to docs directly Per review: don't keep a separate provider README that drifts — point to the PostHog docs (single source of truth) instead. Companion docs page is added in PostHog/posthog.com#18006. - Delete openfeature-provider/README.md. - pyproject: drop the `readme` field (it referenced the deleted file) and add a Documentation URL so the PyPI page links straight to the docs. - Root README: the OpenFeature entry now links to https://posthog.com/docs/feature-flags/installation/openfeature instead of the in-repo provider README. uv build + twine check still pass (only a non-fatal missing-long_description warning, expected without a README). Generated-By: PostHog Code Task-Id: 392fb0da-49bb-4c96-96c7-1b39b0348d32 * Fix pyproject readme ref and root README docs link Follow-up to dropping the provider README (these were left unstaged in the prior commit, which deleted the README but not its references): - openfeature-provider/pyproject.toml: drop the `readme = "README.md"` field (it pointed at the now-deleted file and would break the build) and add a Documentation URL to [project.urls] so PyPI links straight to the docs. - README.md: the OpenFeature entry links to https://posthog.com/docs/feature-flags/installation/openfeature. Generated-By: PostHog Code Task-Id: 392fb0da-49bb-4c96-96c7-1b39b0348d32 * Address review: provider changelog title + robust release notes Addresses @marandaneto's 2026-06-30 review comments: - openfeature-provider/CHANGELOG.md: title is now `# openfeature-provider-posthog` (was `# Changelog`), so Sampo's `## <version>` sections sit under a package-named heading. - release.yml: make the GitHub release-notes extraction robust (the previous awk | sed | tac | sed | tac pipeline was fragile). It now falls back to a "See <CHANGELOG>" pointer when the changelog is missing or has no section yet (e.g. a package's first release), so a release is never blocked on notes. Verified against the provider changelog (no section -> fallback), the root posthog changelog (extracts the latest section), and a missing file. Not changed, with rationale: - posthog tag prefix kept as `v` (not `posthog-v`): the Sampo config sets `short_tags = "posthog"` which intentionally tags the posthog package as `v{version}`, matching existing `vX.Y.Z` tags. Switching to `posthog-v` would diverge from both. - Did not move the root CHANGELOG.md to posthog/CHANGELOG.md: Sampo writes a package's changelog in its manifest directory, and the posthog package's manifest is the repo root, so root CHANGELOG.md *is* the posthog changelog. The posthog-ruby layout works because its gem lives in a posthog-ruby/ subdir; replicating it here would require relocating the entire posthog package. Generated-By: PostHog Code Task-Id: 392fb0da-49bb-4c96-96c7-1b39b0348d32 * Name-prefix the posthog release tag (posthog-v) like other multi-package repos Per @marandaneto's review and matching posthog-ruby's multi-package convention. posthog-ruby tags every package with its name prefix once it went multi-package (`posthog-ruby-v3.15.1`, `posthog-rails-v3.15.0`) and carries no `short_tags` in its Sampo config. This mirrors that: - release.yml: posthog package now tags as `posthog-v{version}` (was `v{version}`), so all published packages are consistently name-prefixed (`posthog-v…`, `openfeature-provider-posthog-v…`). posthoganalytics stays untagged (it is a same-version mirror of posthog). - .sampo/config.toml: drop `short_tags = "posthog"`. Tags are created manually in release.yml, so this was inert, but it implied `v{version}` for posthog and was inconsistent with the new prefix; removing it aligns Sampo's default tag format with the workflow and with posthog-ruby. Generated-By: PostHog Code Task-Id: 392fb0da-49bb-4c96-96c7-1b39b0348d32 * Add changeset for openfeature-provider-posthog initial release Queues the provider's first release. Sets the manifest to 0.0.0 (the "nothing released yet" state) and adds a minor changeset so Sampo's release bumps it to 0.1.0 — the intended first published version. On merge to main this triggers the release workflow, which (per the per-package detect gate) publishes ONLY openfeature-provider-posthog 0.1.0 and tags it openfeature-provider-posthog-v0.1.0; posthog/posthoganalytics are untouched because the root pyproject doesn't change in this release. The provider's PyPI pending trusted publisher (no environment) is already registered. Generated-By: PostHog Code Task-Id: 392fb0da-49bb-4c96-96c7-1b39b0348d32 * Add branch-only TestPyPI dry-run to rehearse the provider publish Lets you validate the release end-to-end before merging, without touching prod. Adds a `dry-run-testpypi` job to release.yml gated on `github.event_name == 'workflow_dispatch' && github.ref != 'refs/heads/main'`. When the workflow is manually dispatched on a non-main branch, it runs `sampo release` (version bump only, no commit), builds openfeature-provider-posthog, and publishes it to TestPyPI via OIDC — exercising the Sampo workspace bump and the trusted-publisher handshake. It never touches main, prod PyPI, git tags, or GitHub releases. Because release.yml already lives on main with workflow_dispatch, dispatching it against this branch runs the branch's copy (incl. this job) — so no merge is needed to test. On real push-to-main releases the job is skipped (ref == main), so the production flow is unaffected. Requires a TestPyPI trusted publisher for openfeature-provider-posthog (workflow release.yml, no environment). Generated-By: PostHog Code Task-Id: 392fb0da-49bb-4c96-96c7-1b39b0348d32
marandaneto
approved these changes
Jul 1, 2026
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.
What
Adds docs for the official PostHog OpenFeature provider for Python (
openfeature-provider-posthog).This is the companion to PostHog/posthog-python#695, which adds the provider. Per review feedback, the provider's README is kept minimal and points here as the single source of truth (so install/usage snippets don't drift in the package repo).
Changes
contents/docs/feature-flags/installation/openfeature.mdx— install, usage/registration with the OpenFeature SDK, evaluation-context → PostHog mapping (targeting_key→distinct_id,groups/group_properties, person properties), supported flag types (boolean/string/number/object), and provider options.src/navs/index.js.Notes
openfeature-provider-posthogships (tracked in the posthog-python PR).🤖 Generated with Claude Code