PostHog Python SDK

raw JSON →
7.9.12 verified Tue May 12 auth: no python install: verified

The PostHog Python SDK makes it easy to capture events, evaluate feature flags, track errors, and more in your Python applications. It supports event tracking, user identification, group analytics, and local evaluation for feature flags. The library is actively maintained, with frequent updates, and the current version is 7.9.12.

pip install posthog
error ModuleNotFoundError: No module named 'posthog'
cause The `posthog` Python package has not been installed in the current Python environment.
fix
Install the PostHog Python library using pip: pip install posthog
error ImportError: cannot import name 'Posthog' from partially initialized module 'posthog' (most likely due to a circular import)
cause This error commonly occurs when you have a local Python file or directory named `posthog.py` or `posthog` within your project's import path, which conflicts with the installed `posthog` library.
fix
Rename your local file or directory (e.g., posthog.py to my_posthog_utils.py) to avoid the name collision with the official PostHog package.
error 401 Unauthorized
cause This HTTP status code indicates that the API key provided during the PostHog client initialization is incorrect, missing, or unauthorized, preventing events from being accepted by the PostHog instance.
fix
Verify that the api_key and host (if self-hosting) passed to posthog.init() are correct and match your PostHog project settings. Ensure environment variables are loaded correctly if used.
breaking Version 6.x introduced breaking changes, most notably deprecating the global `posthog.identify()` method in favor of a new `contexts` API. The `capture()` method signature also changed, requiring keyword arguments instead of positional ones for `distinct_id`.
fix Migrate from `identify()` to `identify_context()` within a `new_context()` block. Update all `capture()` and `capture_exception()` calls to use keyword arguments for parameters like `distinct_id` and `event`.
breaking PostHog Python SDK versions 7.x.x and higher no longer support Python 3.9. Projects using Python 3.9 will need to upgrade their Python version to 3.10 or newer to use the latest SDK versions.
fix Upgrade your Python environment to 3.10 or higher before upgrading to PostHog SDK version 7.0.0+.
gotcha In serverless environments (e.g., AWS Lambda, Google Cloud Functions), buffered events might be lost if the function terminates before the PostHog client can flush its queue. By default, events are sent on background threads.
fix Ensure `posthog.shutdown()` is explicitly called before the function exits, or initialize the client with `sync_mode=True` (e.g., `posthog = Posthog(..., sync_mode=True)`) to send events synchronously.
gotcha The primary `posthog` client is designed with background threads for non-blocking `capture()` calls, but it is not inherently `async/await` compatible. Developers expecting full `asyncio` integration might find this limiting.
fix For true asynchronous use cases, consider existing asynchronous forks (e.g., `posthog-async` - note this is a separate package) or specific async integrations provided by PostHog (e.g., for LLM clients). The core client's `capture()` is non-blocking but not `awaitable`.
gotcha PostHog JavaScript snippets can be blocked by ad blockers in browsers, potentially leading to incomplete data. While this is a frontend concern, it can impact the comprehensiveness of analytics data if not addressed.
fix For production environments, consider setting up a reverse proxy to circumvent ad blockers and ensure more reliable data ingestion.
gotcha Hardcoding your PostHog `project_api_key` and `host` directly in your application code is a security risk, especially for production deployments.
fix Always use environment variables (e.g., `os.environ.get('POSTHOG_PROJECT_API_KEY')`) to securely pass your API key and host to the PostHog client upon initialization.
gotcha The PostHog client will raise a `posthog.request.APIError` (with a 401 status code) if the `project_api_key` provided upon initialization is invalid or has expired, preventing events from being sent or feature flags from being fetched.
fix Ensure the `project_api_key` used to initialize the PostHog client is correct and active for your PostHog project. Verify it against your project settings in PostHog. Double-check for typos and ensure your `host` configuration is also correct.
python os / libc status wheel install import disk
3.10 alpine (musl) wheel - 0.65s 24.3M
3.10 alpine (musl) - - 0.70s 24.9M
3.10 slim (glibc) wheel 2.5s 0.47s 25M
3.10 slim (glibc) - - 0.53s 25M
3.11 alpine (musl) wheel - 0.83s 27.0M
3.11 alpine (musl) - - 0.97s 27.7M
3.11 slim (glibc) wheel 2.6s 0.74s 27M
3.11 slim (glibc) - - 0.74s 28M
3.12 alpine (musl) wheel - 0.77s 18.6M
3.12 alpine (musl) - - 0.82s 19.3M
3.12 slim (glibc) wheel 2.3s 0.75s 19M
3.12 slim (glibc) - - 0.80s 20M
3.13 alpine (musl) wheel - 0.73s 18.4M
3.13 alpine (musl) - - 0.79s 19.0M
3.13 slim (glibc) wheel 2.3s 0.74s 19M
3.13 slim (glibc) - - 0.80s 19M
3.9 alpine (musl) wheel - 0.68s 23.4M
3.9 alpine (musl) - - 0.69s 23.4M
3.9 slim (glibc) wheel 2.9s 0.62s 24M
3.9 slim (glibc) - - 0.57s 24M

This quickstart demonstrates how to initialize the PostHog client with environment variables, capture a custom event, and evaluate a feature flag. It also includes an important step for graceful shutdown to ensure all buffered events are sent.

import os
from posthog import Posthog

# Initialize PostHog client using environment variables for API key and host
# Replace 'your_project_api_key' and 'https://us.i.posthog.com' with your actual values
# or ensure POSTHOG_PROJECT_API_KEY and POSTHOG_HOST are set in your environment.
posthog = Posthog(
    project_api_key=os.environ.get('POSTHOG_PROJECT_API_KEY', 'your_project_api_key'),
    host=os.environ.get('POSTHOG_HOST', 'https://us.i.posthog.com')
)

# Capture a custom event
distinct_id = "user_123_unique_id" # A unique identifier for the user or entity

posthog.capture(
    distinct_id=distinct_id,
    event="user_signed_up",
    properties={
        "plan": "free",
        "signup_method": "email_password"
    }
)

# Evaluate a feature flag
is_new_feature_enabled = posthog.feature_enabled(
    'new-feature-flag-key',
    distinct_id # Feature flags usually require a distinct_id
)

if is_new_feature_enabled:
    print(f"New feature is enabled for {distinct_id}!")
else:
    print(f"New feature is NOT enabled for {distinct_id}.")

# In serverless environments or scripts, ensure events are flushed before exiting.
# For long-running applications (e.g., web servers), this is often handled automatically
# by background threads, but explicit shutdown is good practice for reliability.
posthog.shutdown()
print("PostHog client shut down and events flushed.")