feat: emit $is_server property on captured events#643
Conversation
|
| self.assertEqual(msg["distinct_id"], "distinct_id") | ||
| self.assertEqual(msg["properties"]["$lib"], "posthog-python") | ||
| self.assertEqual(msg["properties"]["$lib_version"], VERSION) | ||
| self.assertEqual(msg["properties"]["$is_server"], True) |
There was a problem hiding this comment.
Missing test for super_properties override
The test only verifies that $is_server is present in the happy-path test_basic_capture. Given the placement of the property before the super_properties merge, a test that constructs a client with super_properties={"$is_server": False} and asserts the outgoing event still has $is_server == True would catch the override issue and anchor the intended invariant.
Prompt To Fix With AI
This is a comment left during a code review.
Path: posthog/test/test_client.py
Line: 162
Comment:
**Missing test for super_properties override**
The test only verifies that `$is_server` is present in the happy-path `test_basic_capture`. Given the placement of the property before the `super_properties` merge, a test that constructs a client with `super_properties={"$is_server": False}` and asserts the outgoing event still has `$is_server == True` would catch the override issue and anchor the intended invariant.
How can I resolve this? If you propose a fix, please make it concise.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
There was a problem hiding this comment.
Good catch — addressed both. $is_server is now set after the super_properties merge so a user-provided super property can no longer override the SDK classification, and added test_is_server_not_overridden_by_super_properties asserting it stays True even when super_properties sets $is_server: False.
posthog-python Compliance ReportDate: 2026-06-02 23:17:52 UTC ✅ All Tests Passed!45/45 tests passed Capture Tests✅ 29/29 tests passed View Details
Feature_Flags Tests✅ 16/16 tests passed View Details
|
ioannisj
left a comment
There was a problem hiding this comment.
Approving to unblock, left a couple of comments though
| @@ -0,0 +1,5 @@ | |||
| --- | |||
| pypi/posthog: patch | |||
There was a problem hiding this comment.
This should probably be minor since we are adding a new constructor param?
There was a problem hiding this comment.
Your call here but if we change we'll need to update all other SDKs that provide a config option as well
| if self.is_server: | ||
| msg["properties"]["$is_server"] = True |
There was a problem hiding this comment.
Curious, why do we omit vs set to False?
There was a problem hiding this comment.
makes sense to me, we dont send on the client side so its the same semantics
| project_api_key = None # type: Optional[str] | ||
| poll_interval = 30 # type: int | ||
| disable_geoip = True # type: bool | ||
| is_server = True # type: bool |
There was a problem hiding this comment.
We are missing a docstring entry above
| project_api_key = None # type: Optional[str] | ||
| poll_interval = 30 # type: int | ||
| disable_geoip = True # type: bool | ||
| is_server = True # type: bool |
There was a problem hiding this comment.
Bool would be hard to change in the future without breaking changes if needed. Wondering if we should be defining as String (server, client for now) which will give us flexibility for the future. Based on the comment here for example this could also be "cli" (we'd need to rename the property of course to maybe something like $runtime_type)
I'll hold back review on other SDKs since they follow the same patters so these points can be discussed here?
There was a problem hiding this comment.
CLI is also a client side, its all about if its running in the users machine or not at the end of the day, does not matter if its a desktop app, a mobile app, a CLI, etc
its either local or cloud, not sure if we need more than a boolean but good point
Adds
$is_server: trueto every event captured by this SDK so PostHog ingestion can identify server-side events.