diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6e489b50..552763b7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,58 +1,249 @@ name: "Release" on: - push: - branches: - - master - paths: - - "posthog/version.py" + pull_request: + types: [closed] + branches: [master] workflow_dispatch: +permissions: + contents: read + +# Concurrency control: only one release process can run at a time +# This prevents race conditions if multiple PRs with 'release' label merge simultaneously +concurrency: + group: release + cancel-in-progress: false + jobs: + check-release-label: + name: Check for release label + runs-on: ubuntu-latest + # Run when PR with 'release' label is merged to master + if: | + github.event_name == 'workflow_dispatch' || + (github.event_name == 'pull_request' && + github.event.pull_request.merged == true && + contains(github.event.pull_request.labels.*.name, 'release')) + outputs: + should-release: ${{ steps.check.outputs.should-release }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: master + fetch-depth: 0 + + - name: Check release conditions + id: check + run: | + changeset_count=$(find .sampo/changesets -name '*.md' 2>/dev/null | wc -l) + if [ "$changeset_count" -gt 0 ]; then + echo "should-release=true" >> "$GITHUB_OUTPUT" + echo "Found $changeset_count changeset(s), ready to release" + else + echo "should-release=false" >> "$GITHUB_OUTPUT" + echo "No changesets to release" + fi + + notify-approval-needed: + name: Notify Slack - Approval Needed + needs: check-release-label + if: needs.check-release-label.outputs.should-release == 'true' + uses: posthog/.github/.github/workflows/notify-approval-needed.yml@main + with: + slack_channel_id: ${{ vars.SLACK_APPROVALS_CLIENT_LIBRARIES_CHANNEL_ID }} + slack_user_group_id: ${{ vars.GROUP_CLIENT_LIBRARIES_SLACK_GROUP_ID }} + secrets: + slack_bot_token: ${{ secrets.SLACK_CLIENT_LIBRARIES_BOT_TOKEN }} + posthog_project_api_key: ${{ secrets.POSTHOG_PROJECT_API_KEY }} + release: - name: Publish release + name: Release and publish + needs: [check-release-label, notify-approval-needed] runs-on: ubuntu-latest + # Use `always()` to ensure the job runs even if notify-approval-needed is skipped, + # but still depend on it to access `needs.notify-approval-needed.outputs.slack_ts` + if: always() && needs.check-release-label.outputs.should-release == 'true' + environment: "Release" # This will require an approval from a maintainer, they are notified in Slack above permissions: contents: write + actions: write id-token: write steps: - - name: Checkout the repository - uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 + - name: Notify Slack - Approved + if: needs.notify-approval-needed.outputs.slack_ts != '' + uses: posthog/.github/.github/actions/slack-thread-reply@main + with: + slack_bot_token: ${{ secrets.SLACK_CLIENT_LIBRARIES_BOT_TOKEN }} + slack_channel_id: ${{ vars.SLACK_APPROVALS_CLIENT_LIBRARIES_CHANNEL_ID }} + thread_ts: ${{ needs.notify-approval-needed.outputs.slack_ts }} + message: "✅ Release approved! Version bump in progress..." + emoji_reaction: "white_check_mark" + + - name: Get GitHub App token + id: releaser + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.GH_APP_POSTHOG_PYTHON_RELEASER_APP_ID }} + private-key: ${{ secrets.GH_APP_POSTHOG_PYTHON_RELEASER_PRIVATE_KEY }} + + - name: Checkout repository + uses: actions/checkout@v4 with: + ref: master fetch-depth: 0 + token: ${{ steps.releaser.outputs.token }} - name: Set up Python - uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 + uses: actions/setup-python@v5 with: python-version: 3.11.11 - name: Install uv - uses: astral-sh/setup-uv@0c5e2b8115b80b4c7c5ddf6ffdd634974642d182 # v5.4.1 + uses: astral-sh/setup-uv@v5 with: - enable-cache: true - pyproject-file: 'pyproject.toml' - - - name: Detect version - run: echo "REPO_VERSION=$(python3 posthog/version.py)" >> $GITHUB_ENV + enable-cache: true + pyproject-file: "pyproject.toml" - - name: Prepare for building release + - name: Install Rust + uses: dtolnay/rust-toolchain@0b1efabc08b657293548b77fb76cc02d26091c7e + with: + toolchain: 1.91.1 + components: cargo + + - name: Cache Sampo CLI + id: cache-sampo + uses: actions/cache@v3 + with: + path: ~/.cargo/bin/sampo + key: sampo-${{ runner.os }}-${{ runner.arch }} + + - name: Install Sampo CLI + if: steps.cache-sampo.outputs.cache-hit != 'true' + run: cargo install sampo + + - name: Install dependencies run: uv sync --extra dev - - name: Push releases to PyPI + - name: Configure Git + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + - name: Prepare release with Sampo + id: sampo-release env: - TWINE_USERNAME: __token__ - run: uv run make release && uv run make release_analytics + GITHUB_TOKEN: ${{ steps.releaser.outputs.token }} + run: | + sampo release + new_version=$(python3 -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])") + echo "new_version=$new_version" >> "$GITHUB_OUTPUT" - - name: Create GitHub release + - name: Sync version to posthog/version.py + run: | + echo 'VERSION = "${{ steps.sampo-release.outputs.new_version }}"' > posthog/version.py + + - name: Commit release changes + id: commit-release env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ steps.releaser.outputs.token }} run: | - gh release create "v${{ env.REPO_VERSION }}" \ - --title "${{ env.REPO_VERSION }}" \ - --generate-notes - - - name: Dispatch generate-references for posthog-python + git add -A + if git diff --staged --quiet; then + echo "No changes to commit" + echo "committed=false" >> "$GITHUB_OUTPUT" + else + git commit -m "chore: Release v${{ steps.sampo-release.outputs.new_version }}" + git push origin master + echo "committed=true" >> "$GITHUB_OUTPUT" + fi + + # Publishing is done manually (not via `sampo publish`) because we need to + # publish both `posthog` and `posthoganalytics` packages to PyPI. + # Sampo only knows about the `posthog` package, so we handle both here. + # Both packages use PyPI OIDC trusted publishing (no API tokens needed). + - name: Build posthog + if: steps.commit-release.outputs.committed == 'true' + run: uv run make build_release + + - name: Publish posthog to PyPI + if: steps.commit-release.outputs.committed == 'true' + uses: pypa/gh-action-pypi-publish@release/v1 + + # The `posthoganalytics` package is a mirror of `posthog` published under + # a different name for backwards compatibility. The make target handles + # copying, renaming imports, and building the dist automatically. + - name: Build posthoganalytics + if: steps.commit-release.outputs.committed == 'true' + run: uv run make build_release_analytics + + - name: Publish posthoganalytics to PyPI + if: steps.commit-release.outputs.committed == 'true' + uses: pypa/gh-action-pypi-publish@release/v1 + + # We skip `sampo publish` (which normally creates the tag) because we + # need to publish both posthog and posthoganalytics manually, so we + # create the tag ourselves. + - name: Tag release + if: steps.commit-release.outputs.committed == 'true' + run: git tag "v${{ steps.sampo-release.outputs.new_version }}" + + - name: Push tags + if: steps.commit-release.outputs.committed == 'true' + run: git push origin --tags + + - name: Create GitHub Release + if: steps.commit-release.outputs.committed == 'true' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: gh release create "v${{ steps.sampo-release.outputs.new_version }}" --generate-notes + + - name: Dispatch generate-references + if: steps.commit-release.outputs.committed == 'true' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh workflow run generate-references.yml --ref master + run: gh workflow run generate-references.yml --ref master + + # Notify in case of a failure + - name: Send failure event to PostHog + if: ${{ failure() }} + uses: PostHog/posthog-github-action@v0.1 + with: + posthog-token: "${{ secrets.POSTHOG_PROJECT_API_KEY }}" + event: "posthog-python-github-release-workflow-failure" + properties: >- + { + "commitSha": "${{ github.sha }}", + "jobStatus": "${{ job.status }}", + "ref": "${{ github.ref }}", + "version": "v${{ steps.sampo-release.outputs.new_version }}" + } + + - name: Notify Slack - Failed + if: ${{ failure() && needs.notify-approval-needed.outputs.slack_ts != '' }} + uses: posthog/.github/.github/actions/slack-thread-reply@main + with: + slack_bot_token: ${{ secrets.SLACK_CLIENT_LIBRARIES_BOT_TOKEN }} + slack_channel_id: ${{ vars.SLACK_APPROVALS_CLIENT_LIBRARIES_CHANNEL_ID }} + thread_ts: ${{ needs.notify-approval-needed.outputs.slack_ts }} + message: "❌ Failed to release `posthog-python@v${{ steps.sampo-release.outputs.new_version }}`! " + emoji_reaction: "x" + + notify-released: + name: Notify Slack - Released + needs: [check-release-label, notify-approval-needed, release] + runs-on: ubuntu-latest + if: always() && needs.release.result == 'success' && needs.notify-approval-needed.outputs.slack_ts != '' + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Notify Slack - Released + uses: posthog/.github/.github/actions/slack-thread-reply@main + with: + slack_bot_token: ${{ secrets.SLACK_CLIENT_LIBRARIES_BOT_TOKEN }} + slack_channel_id: ${{ vars.SLACK_APPROVALS_CLIENT_LIBRARIES_CHANNEL_ID }} + thread_ts: ${{ needs.notify-approval-needed.outputs.slack_ts }} + message: "🚀 posthog-python released successfully!" + emoji_reaction: "rocket" diff --git a/.sampo/changesets/sullen-knight-goulven.md b/.sampo/changesets/sullen-knight-goulven.md new file mode 100644 index 00000000..72c91fe3 --- /dev/null +++ b/.sampo/changesets/sullen-knight-goulven.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +Add sampo to the project diff --git a/.sampo/config.toml b/.sampo/config.toml new file mode 100644 index 00000000..e099fcb1 --- /dev/null +++ b/.sampo/config.toml @@ -0,0 +1,19 @@ +# Sampo configuration +version = 1 + +[git] +default_branch = "master" +short_tags = "posthog" # Tag with v1.2.3 rather than posthog-v1.2.3 + +[github] +repository = "posthog/posthog-python" + +[changelog] +# Options for release notes generation. +# show_commit_hash = true (default) +# show_acknowledgments = true (default) + +[packages] +# Options for package discovery and filtering. +# ignore_unpublished = false (default) +# ignore = ["internal-*", "examples/*"] diff --git a/CHANGELOG.md b/CHANGELOG.md index 665f3a21..4b60a52e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,77 +1,79 @@ -# 7.9.1 - 2026-02-17 +# posthog + +## 7.9.1 - 2026-02-17 fix(llma): make prompt fetches deterministic by requiring project_api_key and sending it as token query param -# 7.9.0 - 2026-02-17 +## 7.9.0 - 2026-02-17 feat: Support device_id as bucketing identifier for local evaluation -# 7.8.6 - 2026-02-09 +## 7.8.6 - 2026-02-09 fix: limit collections scanning in code variables -# 7.8.5 - 2026-02-09 +## 7.8.5 - 2026-02-09 fix: further optimize code variables pattern matching -# 7.8.4 - 2026-02-09 +## 7.8.4 - 2026-02-09 fix: do not pattern match long values in code variables -# 7.8.3 - 2026-02-06 +## 7.8.3 - 2026-02-06 fix: openAI input image sanitization -# 7.8.2 - 2026-02-04 +## 7.8.2 - 2026-02-04 fix(llma): fix prompts default url -# 7.8.1 - 2026-02-03 +## 7.8.1 - 2026-02-03 fix(llma): small fixes for prompt management -# 7.8.0 - 2026-01-28 +## 7.8.0 - 2026-01-28 feat(llma): add prompt management Adds the Prompt Management feature. At the time of release, this feature is in a closed alpha. -# 7.7.0 - 2026-01-15 +## 7.7.0 - 2026-01-15 feat(ai): Add OpenAI Agents SDK integration Automatic tracing for agent workflows, handoffs, tool calls, guardrails, and custom spans. Includes `$ai_total_tokens`, `$ai_error_type` categorization, and `$ai_framework` property. -# 7.6.0 - 2026-01-12 +## 7.6.0 - 2026-01-12 feat: add device_id to flags request payload Add device_id parameter to all feature flag methods, allowing the server to track device identifiers for flag evaluation. The device_id can be passed explicitly or set via context using `set_context_device_id()`. -# 7.5.1 - 2026-01-07 +## 7.5.1 - 2026-01-07 fix: avoid return from finally block to fix Python 3.14 SyntaxWarning (#361) - thanks @jodal -# 7.5.0 - 2026-01-06 +## 7.5.0 - 2026-01-06 feat: Capture Langchain, OpenAI and Anthropic errors as exceptions (if exception autocapture is enabled) feat: Add reference to exception in LLMA trace and span events -# 7.4.3 - 2026-01-02 +## 7.4.3 - 2026-01-02 Fixes cache creation cost for Langchain with Anthropic -# 7.4.2 - 2025-12-22 +## 7.4.2 - 2025-12-22 feat: add `in_app_modules` option to control code variables capturing -# 7.4.1 - 2025-12-19 +## 7.4.1 - 2025-12-19 fix: extract model from response for OpenAI stored prompts When using OpenAI stored prompts, the model is defined in the OpenAI dashboard rather than passed in the API request. This fix adds a fallback to extract the model from the response object when not provided in kwargs, ensuring generations show up with the correct model and enabling cost calculations. -# 7.4.0 - 2025-12-16 +## 7.4.0 - 2025-12-16 feat: Add automatic retries for feature flag requests @@ -83,32 +85,32 @@ Feature flag API requests now automatically retry on transient failures: Rate limit (429) and quota (402) errors are not retried. -# 7.3.1 - 2025-12-06 +## 7.3.1 - 2025-12-06 fix: remove unused $exception_message and $exception_type -# 7.3.0 - 2025-12-05 +## 7.3.0 - 2025-12-05 feat: improve code variables capture masking -# 7.2.0 - 2025-12-01 +## 7.2.0 - 2025-12-01 feat: add $feature_flag_evaluated_at properties to $feature_flag_called events -# 7.1.0 - 2025-11-26 +## 7.1.0 - 2025-11-26 Add support for the async version of Gemini. -# 7.0.2 - 2025-11-18 +## 7.0.2 - 2025-11-18 Add support for Python 3.14. Projects upgrading to Python 3.14 should ensure any Pydantic models passed into the SDK use Pydantic v2, as Pydantic v1 is not compatible with Python 3.14. -# 7.0.1 - 2025-11-15 +## 7.0.1 - 2025-11-15 Try to use repr() when formatting code variables -# 7.0.0 - 2025-11-11 +## 7.0.0 - 2025-11-11 NB Python 3.9 is no longer supported @@ -122,155 +124,155 @@ NB Python 3.9 is no longer supported - langchain-community: 0.3.29 → 0.4.1 - langgraph: 0.6.6 → 1.0.2 -# 6.9.3 - 2025-11-10 +## 6.9.3 - 2025-11-10 - feat(ph-ai): PostHog properties dict in GenerationMetadata -# 6.9.2 - 2025-11-10 +## 6.9.2 - 2025-11-10 - fix(llma): fix cache token double subtraction in Langchain for non-Anthropic providers causing negative costs -# 6.9.1 - 2025-11-07 +## 6.9.1 - 2025-11-07 - fix(error-tracking): pass code variables config from init to client -# 6.9.0 - 2025-11-06 +## 6.9.0 - 2025-11-06 - feat(error-tracking): add local variables capture -# 6.8.0 - 2025-11-03 +## 6.8.0 - 2025-11-03 - feat(llma): send web search calls to be used for LLM cost calculations -# 6.7.14 - 2025-11-03 +## 6.7.14 - 2025-11-03 - fix(django): Handle request.user access in async middleware context to prevent SynchronousOnlyOperation errors in Django 5+ (fixes #355) - test(django): Add Django 5 integration test suite with real ASGI application testing async middleware behavior -# 6.7.13 - 2025-11-02 +## 6.7.13 - 2025-11-02 - fix(llma): cache cost calculation in the LangChain callback -# 6.7.12 - 2025-11-02 +## 6.7.12 - 2025-11-02 - fix(django): Restore process_exception method to capture view and downstream middleware exceptions (fixes #329) - fix(ai/langchain): Add LangChain 1.0+ compatibility for CallbackHandler imports (fixes #362) -# 6.7.11 - 2025-10-28 +## 6.7.11 - 2025-10-28 - feat(ai): Add `$ai_framework` property for framework integrations (e.g. LangChain) -# 6.7.10 - 2025-10-24 +## 6.7.10 - 2025-10-24 - fix(django): Make middleware truly hybrid - compatible with both sync (WSGI) and async (ASGI) Django stacks without breaking sync-only deployments -# 6.7.9 - 2025-10-22 +## 6.7.9 - 2025-10-22 - fix(flags): multi-condition flags with static cohorts returning wrong variants -# 6.7.8 - 2025-10-16 +## 6.7.8 - 2025-10-16 - fix(llma): missing async for OpenAI's streaming implementation -# 6.7.7 - 2025-10-14 +## 6.7.7 - 2025-10-14 - fix: remove deprecated attribute $exception_personURL from exception events -# 6.7.6 - 2025-09-16 +## 6.7.6 - 2025-09-16 - fix: don't sort condition sets with variant overrides to the top - fix: Prevent core Client methods from raising exceptions -# 6.7.5 - 2025-09-16 +## 6.7.5 - 2025-09-16 - feat: Django middleware now supports async request handling. -# 6.7.4 - 2025-09-05 +## 6.7.4 - 2025-09-05 - fix: Missing system prompts for some providers -# 6.7.3 - 2025-09-04 +## 6.7.3 - 2025-09-04 - fix: missing usage tokens in Gemini -# 6.7.2 - 2025-09-03 +## 6.7.2 - 2025-09-03 - fix: tool call results in streaming providers -# 6.7.1 - 2025-09-01 +## 6.7.1 - 2025-09-01 - fix: Add base64 inline image sanitization -# 6.7.0 - 2025-08-26 +## 6.7.0 - 2025-08-26 - feat: Add support for feature flag dependencies -# 6.6.1 - 2025-08-21 +## 6.6.1 - 2025-08-21 - fix: Prevent `NoneType` error when `group_properties` is `None` -# 6.6.0 - 2025-08-15 +## 6.6.0 - 2025-08-15 - feat: Add `flag_keys_to_evaluate` parameter to optimize feature flag evaluation performance by only evaluating specified flags - feat: Add `flag_keys_filter` option to `send_feature_flags` for selective flag evaluation in capture events -# 6.5.0 - 2025-08-08 +## 6.5.0 - 2025-08-08 - feat: Add `$context_tags` to an event to know which properties were included as tags -# 6.4.1 - 2025-08-06 +## 6.4.1 - 2025-08-06 - fix: Always pass project API key in `remote_config` requests for deterministic project routing -# 6.4.0 - 2025-08-05 +## 6.4.0 - 2025-08-05 - feat: support Vertex AI for Gemini -# 6.3.4 - 2025-08-04 +## 6.3.4 - 2025-08-04 - fix: set `$ai_tools` for all providers and `$ai_output_choices` for all non-streaming provider flows properly -# 6.3.3 - 2025-08-01 +## 6.3.3 - 2025-08-01 - fix: `get_feature_flag_result` now correctly returns FeatureFlagResult when payload is empty string instead of None -# 6.3.2 - 2025-07-31 +## 6.3.2 - 2025-07-31 - fix: Anthropic's tool calls are now handled properly -# 6.3.0 - 2025-07-22 +## 6.3.0 - 2025-07-22 - feat: Enhanced `send_feature_flags` parameter to accept `SendFeatureFlagsOptions` object for declarative control over local/remote evaluation and custom properties -# 6.2.1 - 2025-07-21 +## 6.2.1 - 2025-07-21 - feat: make `posthog_client` an optional argument in PostHog AI providers wrappers (`posthog.ai.*`), intuitively using the default client as the default -# 6.1.1 - 2025-07-16 +## 6.1.1 - 2025-07-16 - fix: correctly capture exceptions processed by Django from views or middleware -# 6.1.0 - 2025-07-10 +## 6.1.0 - 2025-07-10 - feat: decouple feature flag local evaluation from personal API keys; support decrypting remote config payloads without relying on the feature flags poller -# 6.0.4 - 2025-07-09 +## 6.0.4 - 2025-07-09 - fix: add POSTHOG_MW_CLIENT setting to django middleware, to support custom clients for exception capture. -# 6.0.3 - 2025-07-07 +## 6.0.3 - 2025-07-07 - feat: add a feature flag evaluation cache (local storage or redis) to support returning flag evaluations when the service is down -# 6.0.2 - 2025-07-02 +## 6.0.2 - 2025-07-02 - fix: send_feature_flags changed to default to false in `Client::capture_exception` -# 6.0.1 +## 6.0.1 - fix: response `$process_person_profile` property when passed to capture -# 6.0.0 +## 6.0.0 This release contains a number of major breaking changes: @@ -297,15 +299,15 @@ with posthog.new_context(): Generally, arguments are now appropriately typed, and docstrings have been updated. If something is unclear, please open an issue, or submit a PR! -# 5.4.0 - 2025-06-20 +## 5.4.0 - 2025-06-20 - feat: add support to session_id context on page method -# 5.3.0 - 2025-06-19 +## 5.3.0 - 2025-06-19 - fix: safely handle exception values -# 5.2.0 - 2025-06-19 +## 5.2.0 - 2025-06-19 - feat: construct artificial stack traces if no traceback is available on a captured exception diff --git a/Makefile b/Makefile index b6d867fa..51fc5a71 100644 --- a/Makefile +++ b/Makefile @@ -5,12 +5,26 @@ test: coverage run -m pytest coverage report -release: +build_release: rm -rf dist/* python setup.py sdist bdist_wheel - twine upload dist/* -release_analytics: +# Builds the `posthoganalytics` PyPI package, which is a mirror of `posthog` +# published under a different name for internal use by posthog/posthog. +# +# The process works in three phases: +# 1. posthog -> posthoganalytics: Copy the source, rewrite all imports, +# remove the original posthog/ dir, and build the dist. +# 2. posthoganalytics -> posthog: Reverse the import rewrites, copy +# everything back into posthog/, and clean up. +# 3. Restore pyproject.toml from backup (setup_analytics.py modifies it). +# +# This ensures the working tree is left in the same state it started in. +# +# NOTE: This target clears dist/ before building. In the release workflow, +# `build_release` (posthog) must be published BEFORE running this target, +# otherwise the posthog dist artifacts will be lost. +build_release_analytics: rm -rf dist rm -rf build rm -rf posthoganalytics @@ -21,7 +35,6 @@ release_analytics: find ./posthoganalytics -name "*.bak" -delete rm -rf posthog python setup_analytics.py sdist bdist_wheel - twine upload dist/* mkdir posthog find ./posthoganalytics -type f -name "*.py" -exec sed -i.bak -e 's/from posthoganalytics /from posthog /g' {} \; find ./posthoganalytics -type f -name "*.py" -exec sed -i.bak -e 's/from posthoganalytics\./from posthog\./g' {} \; @@ -54,4 +67,4 @@ prep_local: @echo "Local copy created at ../posthog-python-local" @echo "Install with: pip install -e ../posthog-python-local" -.PHONY: test lint release e2e_test prep_local +.PHONY: test lint build_release build_release_analytics e2e_test prep_local diff --git a/README_ANALYTICS.md b/README_ANALYTICS.md new file mode 100644 index 00000000..ac20c308 --- /dev/null +++ b/README_ANALYTICS.md @@ -0,0 +1,11 @@ +# posthoganalytics + +> **Do not use this package.** Use [`posthog`](https://pypi.org/project/posthog/) instead. + +```bash +pip install posthog +``` + +This package exists solely for internal use by [posthog/posthog](https://github.com/posthog/posthog) to avoid import conflicts with the local `posthog` package in that repository. It is an automatically generated mirror of `posthog` — same code, same versions, just published under a different name. + +If you are not working on the PostHog main repository, you should never need this package. All documentation, issues, and development happen in [`posthog-python`](https://github.com/posthog/posthog-python). diff --git a/posthog/version.py b/posthog/version.py index df267ac2..daf813d7 100644 --- a/posthog/version.py +++ b/posthog/version.py @@ -1,4 +1 @@ VERSION = "7.9.1" - -if __name__ == "__main__": - print(VERSION, end="") # noqa: T201 diff --git a/pyproject.toml b/pyproject.toml index 0e3e8001..df120021 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "posthog" -dynamic = ["version"] +version = "7.9.1" description = "Integrate PostHog into any python application." authors = [{ name = "PostHog", email = "hey@posthog.com" }] maintainers = [{ name = "PostHog", email = "hey@posthog.com" }] @@ -93,9 +93,6 @@ packages = [ "posthog.integrations", ] -[tool.setuptools.dynamic] -version = { attr = "posthog.version.VERSION" } - [tool.pytest.ini_options] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" diff --git a/setup_analytics.py b/setup_analytics.py index f4854180..4c10473c 100644 --- a/setup_analytics.py +++ b/setup_analytics.py @@ -23,6 +23,7 @@ # Override specific values config["project"]["name"] = "posthoganalytics" +config["project"]["readme"] = "README_ANALYTICS.md" config["tool"]["setuptools"]["dynamic"]["version"] = { "attr": "posthoganalytics.version.VERSION" }