Generated banner for Feature Flags Python
Generated logo for Feature Flags Python

Feature Flags Python

PostHogOfficialCreated by PostHog

  • Skill
  • Tool integration
  • Data and AI
  • MIT
  • Low risk

From the author

PostHog feature flags for Python applications
— the description by PostHog

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides guidance and best practices for implementing PostHog feature flags within Python applications. It covers the necessary setup, configuration of the PostHog Python SDK, and architectural patterns for managing feature flags effectively. The skill emphasizes server-side evaluation, secure handling of environment variables, and proper lifecycle management of the PostHog client to ensure reliable performance and data integrity.

What it does

  • Provides instructions for installing and configuring the PostHog Python SDK.
  • Outlines patterns for implementing boolean and multivariate feature flags in Python code.
  • Defines best practices for flag naming, targeting, and lifecycle management.
  • Explains how to handle client lifecycle events like shutdown to ensure event flushing.
  • Offers guidance on secure configuration using environment variables.
  • Provides strategies for local evaluation to improve performance and reduce API latency.

When to use it

  • When you need to implement feature toggles or experiments in a Python-based backend.
  • When you want to perform server-side feature flag evaluation to prevent UI flickering.
  • When you need to ensure consistent user experiences across different sessions and devices.
  • When you are setting up a new Python project that requires controlled feature releases.

Advantages

  • Enables safe, incremental feature rollouts and A/B testing.
  • Reduces latency by supporting local flag evaluation.
  • Promotes clean code through centralized flag management patterns.
  • Ensures data privacy by distinguishing between PII and safe event properties.

Usage examples

“How do I initialize the PostHog client in my Python application?”
The agent provides the code to instantiate the Posthog class with your API key, including the required enable_exception_autocapture=True setting and atexit registration for shutdown.
“What is the best way to check a feature flag in my Python logic?”
The agent explains how to use the posthog_client.feature_enabled() method and recommends wrapping flag checks in a dedicated function if the flag is used in multiple locations.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/posthog/feature-flags-python/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip feature-flags-python.zip -d .agents/skills

Documentation by PostHog

PostHog feature flags for Python

This skill helps you add PostHog feature flags to Python applications.

Reference files

  • references/python.md - Python feature flags installation - docs

  • references/adding-feature-flag-code.md - Adding feature flag code - docs

  • references/best-practices.md - Feature flag best practices - docs

Consult the documentation for API details and framework-specific patterns.

Key principles

  • Environment variables: Always use environment variables for PostHog keys. Never hardcode them.

  • Minimal changes: Add feature flag code alongside existing logic. Don't replace or restructure existing code.

  • Boolean flags first: Default to boolean flag checks unless the user specifically asks for multivariate flags.

  • Server-side when possible: Prefer server-side flag evaluation to avoid UI flicker.

PostHog MCP tools

Check if a PostHog MCP server is connected. If available, look for tools related to feature flag management (creating, listing, updating, deleting flags). Use these tools to manage flags directly in PostHog rather than requiring the user to do it manually in the dashboard.

Framework guidelines

  • Remember that source code is available in the venv/site-packages directory

  • posthog is the Python SDK package name

  • Install dependencies with pip install posthog or pip install -r requirements.txt and do NOT use unquoted version specifiers like >= directly in shell commands

  • In CLIs and scripts: MUST call posthog.shutdown() before exit or all events are lost

  • Always use the Posthog() class constructor (instance-based API) instead of module-level posthog.api_key config

  • Always include enable_exception_autocapture=True in the Posthog() constructor to automatically track exceptions

  • NEVER send PII in capture() event properties — no emails, full names, phone numbers, physical addresses, IP addresses, or user-generated content

  • PII belongs in identify() person properties, NOT in capture() event properties. Safe event properties are metadata like message_length, form_type, boolean flags.

  • Register posthog_client.shutdown with atexit.register() to ensure all events are flushed on exit

  • The Python SDK has NO identify() method — use posthog_client.set(distinct_id=user_id, properties={...}) to set person properties, or use identify_context(user_id) within a context

Files

references/best-practices.md

Feature flag best practices - Docs

1. Use a reverse proxy

Ad blockers have the potential to disable your feature flags, which can lead to bad experiences, such as users seeing the wrong version of your app, or missing a new feature rollout.

To avoid this, deploy a reverse proxy, which enables you to make requests and send events to PostHog Cloud using your own domain.

This means that requests are less likely to be intercepted by tracking blockers, and your feature flags are more likely to work as intended. You'll also capture more usage data.

PostHog offers a free managed reverse proxy, or you can run your own. See our reverse proxy docs for more.

2. Call your flag in as few places as possible

It should be easy to understand how feature flags affect your code. The more locations a flag is in, the more likely it is to cause problems. For example, a developer could remove the flag in one place but forget to remove it in another.

If you expect to use a feature flag in multiple places, it's a good idea to wrap the flag in a single function or method. For example:

JavaScript

PostHog AI

function useBetaFeature() {
    return posthog.isFeatureEnabled('beta-feature')
}

3. Targeting

PostHog evaluates flags based on the user's distinct ID, having different IDs can cause the same user to receive different flag values across different sessions, devices, and platforms. By identifying them, you can ensure consistent flag values.

The same applies to identifying groups for group-level flags.

For flags targeting anonymous users, such as signup flows or landing page experiments, consider using device bucketing instead. This evaluates the flag based on the device ID, ensuring a consistent experience on the device even after the user logs in.

4. Use server-side local evaluation for faster flags

Evaluating feature flags requires making a request to PostHog for each flag. However, you can improve performance by evaluating flags locally. Instead of making a request for each flag, PostHog will periodically request and store feature flag definitions locally, enabling you to evaluate flags without making additional requests.

Evaluate flags locally when possible, since this enables you to resolve flags faster and with fewer API calls. See our docs on local evaluation for more details.

5. Bootstrap flags on the client to make them available immediately

Since there is a delay between initializing PostHog and fetching feature flags, feature flags are not always available immediately. This makes them unusable if you want to do something like redirecting a user to a different page based on a feature flag.

To have your feature flags available immediately, you can initialize PostHog with precomputed values until it has had a chance to fetch them. This is called bootstrapping.

See our docs on bootstrapping for more details on how to do this.

6. Naming tips

Good naming conventions for your flags makes them easier to understand and maintain. Below are tips for naming your flags:

  • Use descriptive names. For example, is_v2_billing_dashboard_enabled is much clearer than is_dashboard_enabled.

  • Use name "types". This helps organize them and makes their purpose clear. Types might include experiments, releases, and permissions. For example, instead of new-billing, they would be new-billing-experiment or new-billing-release.

  • Name flags to reflect their return type. For example, is_premium_user for a boolean, enabled_integrations for an array, or selected_theme for a single string.

  • Use positive language for boolean flags. For example, is_premium_user instead of is_not_premium_user. This helps avoid double negatives when checking the flag value (e.g. if !is_not_premium_user is confusing).

7. Roll out progressively

When testing a change behind a feature flag, it is best to roll it out to a small group of users and increase that group over time. This is also known as a phased rollout. It enables you to identify any potential issues ahead of the full release.

For example, at PostHog we often roll out the flag to just the responsible developer. It then moves on to the internal team, then beta users, and finally into a full rollout. This enables us to test in production, get multiple rounds of feedback, identify issues, and polish the feature before the full release.

8. Clean up after yourself

Leaving flags in your code for too long can confuse future developers and create technical debt, especially if it's already rolled out and integrated. Be sure to remove stale flags once they are completely rolled out or no longer needed.

When you have many flags to clean up, use bulk delete to select and delete multiple flags at once. Select flags using checkboxes (shift-click to select a range), or filter by name or status and use "select all matching" to select all flags that match your criteria. PostHog validates that flags aren't used by experiments, early access features, or other dependent flags before deletion.

9. Fallback to working code

It's possible that a feature flag will return an unexpected value. For example, if the flag is disabled or failed to load due to a network error.

In this case, its best to check that the feature flag returns a valid expected value before using it. If it isn't, fallback to working code.

10. Use dependencies for complex rollouts

For sophisticated feature rollouts, consider using feature flag dependencies where one flag's activation depends on another flag's state. This is useful for:

  • Enabling complex features only after foundational components are active

  • Running experiments only on users with specific features enabled

  • Creating safety mechanisms where critical flags must be enabled first

When using dependencies, keep the dependency chains simple and avoid circular dependencies.

11. Reducing your bill

We aim to be significantly cheaper than our competitors. To help you reduce your bill, we've created a dedicated guide to estimating and reducing your feature flag costs.

12. Consistent flag evaluations across frontend and backend

For feature flags with flag persistence enabled and used across both your frontend and backend, you will need to do one of the following to ensure the evaluation result of the flag is consistent between both environments:

  1. Identify the user on the frontend and use the same identified distinct ID when evaluating the flag on the backend.

JavaScript

PostHog AI

// Frontend: Identify the user
posthog.identify('user123')
// Backend: Use the same distinct ID
const flagValue = await posthog.getFeatureFlag('my-flag', 'user123')
  1. If you are unable to call identify on the frontend, and only have access to the anonymous distinct ID when evaluating the flag on the backend, you can include the anonymous distinct ID as a person property override in the getFeatureFlag call.

JavaScript

PostHog AI

// Frontend: Get the anonymous ID (before identify is called)
const anonId = posthog.getAnonymousId()
// Backend: Pass the anonymous ID as a person property override
const flagValue = await posthog.getFeatureFlag(
  'my-flag',
  'user123', // identified distinct ID
  {
    personProperties: {
      $anon_distinct_id: anonId
    }
  }
)
Community questions

Ask a question

Was this page useful?

HelpfulCould be better

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs an MCP server, Needs an API key, Needs Python

Security

What our scanner noticed· Low risk

  • Instructions that use the network

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
PostHog
Publisher
PostHog (Official)
Source
PostHog/skills · skills/posthog/feature-flags/skills/python · commit a5d30e7
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced
Also distributed in
PostHog/skills

AutoGineer is not affiliated with or endorsed by PostHog or PostHog.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download feature-flags-python.zip