posthoganalytics 6.0.4__py3-none-any.whl → 6.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- posthoganalytics/__init__.py +364 -129
- posthoganalytics/client.py +451 -44
- posthoganalytics/contexts.py +33 -3
- posthoganalytics/feature_flags.py +15 -0
- posthoganalytics/integrations/django.py +13 -1
- posthoganalytics/test/test_client.py +90 -0
- posthoganalytics/test/test_feature_flags.py +71 -0
- posthoganalytics/version.py +1 -1
- {posthoganalytics-6.0.4.dist-info → posthoganalytics-6.1.1.dist-info}/METADATA +1 -1
- {posthoganalytics-6.0.4.dist-info → posthoganalytics-6.1.1.dist-info}/RECORD +13 -13
- {posthoganalytics-6.0.4.dist-info → posthoganalytics-6.1.1.dist-info}/WHEEL +0 -0
- {posthoganalytics-6.0.4.dist-info → posthoganalytics-6.1.1.dist-info}/licenses/LICENSE +0 -0
- {posthoganalytics-6.0.4.dist-info → posthoganalytics-6.1.1.dist-info}/top_level.txt +0 -0
posthoganalytics/client.py
CHANGED
|
@@ -97,29 +97,20 @@ def add_context_tags(properties):
|
|
|
97
97
|
|
|
98
98
|
|
|
99
99
|
class Client(object):
|
|
100
|
-
"""
|
|
100
|
+
"""
|
|
101
|
+
This is the SDK reference for the PostHog Python SDK.
|
|
102
|
+
You can learn more about example usage in the [Python SDK documentation](/docs/libraries/python).
|
|
103
|
+
You can also follow [Flask](/docs/libraries/flask) and [Django](/docs/libraries/django)
|
|
104
|
+
guides to integrate PostHog into your project.
|
|
101
105
|
|
|
102
106
|
Examples:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
... )
|
|
111
|
-
|
|
112
|
-
With Redis fallback cache for high-scale applications:
|
|
113
|
-
>>> client = Client(
|
|
114
|
-
... "your-api-key",
|
|
115
|
-
... flag_fallback_cache_url="redis://localhost:6379/0/?ttl=300"
|
|
116
|
-
... )
|
|
117
|
-
|
|
118
|
-
With Redis authentication:
|
|
119
|
-
>>> client = Client(
|
|
120
|
-
... "your-api-key",
|
|
121
|
-
... flag_fallback_cache_url="redis://username:password@localhost:6379/0/?ttl=300"
|
|
122
|
-
... )
|
|
107
|
+
```python
|
|
108
|
+
from posthoganalytics import Posthog
|
|
109
|
+
posthog = Posthog('<ph_project_api_key>', host='<ph_client_api_host>')
|
|
110
|
+
posthog.debug = True
|
|
111
|
+
if settings.TEST:
|
|
112
|
+
posthog.disabled = True
|
|
113
|
+
```
|
|
123
114
|
"""
|
|
124
115
|
|
|
125
116
|
log = logging.getLogger("posthog")
|
|
@@ -152,7 +143,26 @@ class Client(object):
|
|
|
152
143
|
privacy_mode=False,
|
|
153
144
|
before_send=None,
|
|
154
145
|
flag_fallback_cache_url=None,
|
|
146
|
+
enable_local_evaluation=True,
|
|
155
147
|
):
|
|
148
|
+
"""
|
|
149
|
+
Initialize a new PostHog client instance.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
project_api_key: The project API key.
|
|
153
|
+
host: The host to use for the client.
|
|
154
|
+
debug: Whether to enable debug mode.
|
|
155
|
+
|
|
156
|
+
Examples:
|
|
157
|
+
```python
|
|
158
|
+
from posthoganalytics import Posthog
|
|
159
|
+
|
|
160
|
+
posthog = Posthog('<ph_project_api_key>', host='<ph_app_host>')
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Category:
|
|
164
|
+
Initialization
|
|
165
|
+
"""
|
|
156
166
|
self.queue = queue.Queue(max_queue_size)
|
|
157
167
|
|
|
158
168
|
# api_key: This should be the Team API Key (token), public
|
|
@@ -187,6 +197,7 @@ class Client(object):
|
|
|
187
197
|
self.log_captured_exceptions = log_captured_exceptions
|
|
188
198
|
self.exception_capture = None
|
|
189
199
|
self.privacy_mode = privacy_mode
|
|
200
|
+
self.enable_local_evaluation = enable_local_evaluation
|
|
190
201
|
|
|
191
202
|
if project_root is None:
|
|
192
203
|
try:
|
|
@@ -250,6 +261,23 @@ class Client(object):
|
|
|
250
261
|
consumer.start()
|
|
251
262
|
|
|
252
263
|
def new_context(self, fresh=False, capture_exceptions=True):
|
|
264
|
+
"""
|
|
265
|
+
Create a new context for managing shared state. Learn more about [contexts](/docs/libraries/python#contexts).
|
|
266
|
+
|
|
267
|
+
Args:
|
|
268
|
+
fresh: Whether to create a fresh context that doesn't inherit from parent.
|
|
269
|
+
capture_exceptions: Whether to automatically capture exceptions in this context.
|
|
270
|
+
|
|
271
|
+
Examples:
|
|
272
|
+
```python
|
|
273
|
+
with posthog.new_context():
|
|
274
|
+
identify_context('<distinct_id>')
|
|
275
|
+
posthog.capture('event_name')
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Category:
|
|
279
|
+
Contexts
|
|
280
|
+
"""
|
|
253
281
|
return new_context(
|
|
254
282
|
fresh=fresh, capture_exceptions=capture_exceptions, client=self
|
|
255
283
|
)
|
|
@@ -285,7 +313,17 @@ class Client(object):
|
|
|
285
313
|
disable_geoip=None,
|
|
286
314
|
) -> dict[str, Union[bool, str]]:
|
|
287
315
|
"""
|
|
288
|
-
Get feature flag variants for a
|
|
316
|
+
Get feature flag variants for a user by calling decide.
|
|
317
|
+
|
|
318
|
+
Args:
|
|
319
|
+
distinct_id: The distinct ID of the user.
|
|
320
|
+
groups: A dictionary of group information.
|
|
321
|
+
person_properties: A dictionary of person properties.
|
|
322
|
+
group_properties: A dictionary of group properties.
|
|
323
|
+
disable_geoip: Whether to disable GeoIP for this request.
|
|
324
|
+
|
|
325
|
+
Category:
|
|
326
|
+
Feature Flags
|
|
289
327
|
"""
|
|
290
328
|
resp_data = self.get_flags_decision(
|
|
291
329
|
distinct_id, groups, person_properties, group_properties, disable_geoip
|
|
@@ -301,7 +339,22 @@ class Client(object):
|
|
|
301
339
|
disable_geoip=None,
|
|
302
340
|
) -> dict[str, str]:
|
|
303
341
|
"""
|
|
304
|
-
Get feature flag payloads for a
|
|
342
|
+
Get feature flag payloads for a user by calling decide.
|
|
343
|
+
|
|
344
|
+
Args:
|
|
345
|
+
distinct_id: The distinct ID of the user.
|
|
346
|
+
groups: A dictionary of group information.
|
|
347
|
+
person_properties: A dictionary of person properties.
|
|
348
|
+
group_properties: A dictionary of group properties.
|
|
349
|
+
disable_geoip: Whether to disable GeoIP for this request.
|
|
350
|
+
|
|
351
|
+
Examples:
|
|
352
|
+
```python
|
|
353
|
+
payloads = posthog.get_feature_payloads('<distinct_id>')
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
Category:
|
|
357
|
+
Feature Flags
|
|
305
358
|
"""
|
|
306
359
|
resp_data = self.get_flags_decision(
|
|
307
360
|
distinct_id, groups, person_properties, group_properties, disable_geoip
|
|
@@ -317,7 +370,22 @@ class Client(object):
|
|
|
317
370
|
disable_geoip=None,
|
|
318
371
|
) -> FlagsAndPayloads:
|
|
319
372
|
"""
|
|
320
|
-
Get feature flags and payloads for a
|
|
373
|
+
Get feature flags and payloads for a user by calling decide.
|
|
374
|
+
|
|
375
|
+
Args:
|
|
376
|
+
distinct_id: The distinct ID of the user.
|
|
377
|
+
groups: A dictionary of group information.
|
|
378
|
+
person_properties: A dictionary of person properties.
|
|
379
|
+
group_properties: A dictionary of group properties.
|
|
380
|
+
disable_geoip: Whether to disable GeoIP for this request.
|
|
381
|
+
|
|
382
|
+
Examples:
|
|
383
|
+
```python
|
|
384
|
+
result = posthog.get_feature_flags_and_payloads('<distinct_id>')
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
Category:
|
|
388
|
+
Feature Flags
|
|
321
389
|
"""
|
|
322
390
|
resp = self.get_flags_decision(
|
|
323
391
|
distinct_id, groups, person_properties, group_properties, disable_geoip
|
|
@@ -333,7 +401,22 @@ class Client(object):
|
|
|
333
401
|
disable_geoip=None,
|
|
334
402
|
) -> FlagsResponse:
|
|
335
403
|
"""
|
|
336
|
-
Get feature flags decision
|
|
404
|
+
Get feature flags decision.
|
|
405
|
+
|
|
406
|
+
Args:
|
|
407
|
+
distinct_id: The distinct ID of the user.
|
|
408
|
+
groups: A dictionary of group information.
|
|
409
|
+
person_properties: A dictionary of person properties.
|
|
410
|
+
group_properties: A dictionary of group properties.
|
|
411
|
+
disable_geoip: Whether to disable GeoIP for this request.
|
|
412
|
+
|
|
413
|
+
Examples:
|
|
414
|
+
```python
|
|
415
|
+
decision = posthog.get_flags_decision('user123')
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
Category:
|
|
419
|
+
Feature Flags
|
|
337
420
|
"""
|
|
338
421
|
|
|
339
422
|
if distinct_id is None:
|
|
@@ -365,6 +448,52 @@ class Client(object):
|
|
|
365
448
|
def capture(
|
|
366
449
|
self, event: str, **kwargs: Unpack[OptionalCaptureArgs]
|
|
367
450
|
) -> Optional[str]:
|
|
451
|
+
"""
|
|
452
|
+
Captures an event manually. [Learn about capture best practices](https://posthog.com/docs/product-analytics/capture-events)
|
|
453
|
+
|
|
454
|
+
Args:
|
|
455
|
+
event: The event name to capture.
|
|
456
|
+
distinct_id: The distinct ID of the user.
|
|
457
|
+
properties: A dictionary of properties to include with the event.
|
|
458
|
+
timestamp: The timestamp of the event.
|
|
459
|
+
uuid: A unique identifier for the event.
|
|
460
|
+
groups: A dictionary of group information.
|
|
461
|
+
send_feature_flags: Whether to send feature flags with the event.
|
|
462
|
+
disable_geoip: Whether to disable GeoIP for this event.
|
|
463
|
+
|
|
464
|
+
Examples:
|
|
465
|
+
```python
|
|
466
|
+
# Anonymous event
|
|
467
|
+
posthog.capture('some-anon-event')
|
|
468
|
+
```
|
|
469
|
+
```python
|
|
470
|
+
# Context usage
|
|
471
|
+
from posthoganalytics import identify_context, new_context
|
|
472
|
+
with new_context():
|
|
473
|
+
identify_context('distinct_id_of_the_user')
|
|
474
|
+
posthog.capture('user_signed_up')
|
|
475
|
+
posthog.capture('user_logged_in')
|
|
476
|
+
posthog.capture('some-custom-action', distinct_id='distinct_id_of_the_user')
|
|
477
|
+
```
|
|
478
|
+
```python
|
|
479
|
+
# Set event properties
|
|
480
|
+
posthog.capture(
|
|
481
|
+
"user_signed_up",
|
|
482
|
+
distinct_id="distinct_id_of_the_user",
|
|
483
|
+
properties={
|
|
484
|
+
"login_type": "email",
|
|
485
|
+
"is_free_trial": "true"
|
|
486
|
+
}
|
|
487
|
+
)
|
|
488
|
+
```
|
|
489
|
+
```python
|
|
490
|
+
# Page view event
|
|
491
|
+
posthog.capture('$pageview', distinct_id="distinct_id_of_the_user", properties={'$current_url': 'https://example.com'})
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
Category:
|
|
495
|
+
Capture
|
|
496
|
+
"""
|
|
368
497
|
distinct_id = kwargs.get("distinct_id", None)
|
|
369
498
|
properties = kwargs.get("properties", None)
|
|
370
499
|
timestamp = kwargs.get("timestamp", None)
|
|
@@ -431,6 +560,39 @@ class Client(object):
|
|
|
431
560
|
return self._enqueue(msg, disable_geoip)
|
|
432
561
|
|
|
433
562
|
def set(self, **kwargs: Unpack[OptionalSetArgs]) -> Optional[str]:
|
|
563
|
+
"""
|
|
564
|
+
Set properties on a person profile.
|
|
565
|
+
|
|
566
|
+
Args:
|
|
567
|
+
distinct_id: The distinct ID of the user.
|
|
568
|
+
properties: A dictionary of properties to set.
|
|
569
|
+
timestamp: The timestamp of the event.
|
|
570
|
+
uuid: A unique identifier for the event.
|
|
571
|
+
disable_geoip: Whether to disable GeoIP for this event.
|
|
572
|
+
|
|
573
|
+
Examples:
|
|
574
|
+
```python
|
|
575
|
+
# Set with distinct id
|
|
576
|
+
posthog.capture(
|
|
577
|
+
'event_name',
|
|
578
|
+
distinct_id='user-distinct-id',
|
|
579
|
+
properties={
|
|
580
|
+
'$set': {'name': 'Max Hedgehog'},
|
|
581
|
+
'$set_once': {'initial_url': '/blog'}
|
|
582
|
+
}
|
|
583
|
+
)
|
|
584
|
+
```
|
|
585
|
+
```python
|
|
586
|
+
# Set using context
|
|
587
|
+
from posthoganalytics import new_context, identify_context
|
|
588
|
+
with new_context():
|
|
589
|
+
identify_context('user-distinct-id')
|
|
590
|
+
posthog.capture('event_name')
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
Category:
|
|
594
|
+
Identification
|
|
595
|
+
"""
|
|
434
596
|
distinct_id = kwargs.get("distinct_id", None)
|
|
435
597
|
properties = kwargs.get("properties", None)
|
|
436
598
|
timestamp = kwargs.get("timestamp", None)
|
|
@@ -457,6 +619,24 @@ class Client(object):
|
|
|
457
619
|
return self._enqueue(msg, disable_geoip)
|
|
458
620
|
|
|
459
621
|
def set_once(self, **kwargs: Unpack[OptionalSetArgs]) -> Optional[str]:
|
|
622
|
+
"""
|
|
623
|
+
Set properties on a person profile only if they haven't been set before.
|
|
624
|
+
|
|
625
|
+
Args:
|
|
626
|
+
distinct_id: The distinct ID of the user.
|
|
627
|
+
properties: A dictionary of properties to set once.
|
|
628
|
+
timestamp: The timestamp of the event.
|
|
629
|
+
uuid: A unique identifier for the event.
|
|
630
|
+
disable_geoip: Whether to disable GeoIP for this event.
|
|
631
|
+
|
|
632
|
+
Examples:
|
|
633
|
+
```python
|
|
634
|
+
posthog.set_once(distinct_id='user123', properties={'initial_signup_date': '2024-01-01'})
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
Category:
|
|
638
|
+
Identification
|
|
639
|
+
"""
|
|
460
640
|
distinct_id = kwargs.get("distinct_id", None)
|
|
461
641
|
properties = kwargs.get("properties", None)
|
|
462
642
|
timestamp = kwargs.get("timestamp", None)
|
|
@@ -485,18 +665,41 @@ class Client(object):
|
|
|
485
665
|
self,
|
|
486
666
|
group_type: str,
|
|
487
667
|
group_key: str,
|
|
488
|
-
properties=None,
|
|
489
|
-
timestamp=None,
|
|
490
|
-
uuid=None,
|
|
491
|
-
disable_geoip=None,
|
|
492
|
-
distinct_id=None,
|
|
493
|
-
):
|
|
668
|
+
properties: Optional[Dict[str, Any]] = None,
|
|
669
|
+
timestamp: Optional[Union[datetime, str]] = None,
|
|
670
|
+
uuid: Optional[str] = None,
|
|
671
|
+
disable_geoip: Optional[bool] = None,
|
|
672
|
+
distinct_id: Optional[ID_TYPES] = None,
|
|
673
|
+
) -> Optional[str]:
|
|
674
|
+
"""
|
|
675
|
+
Identify a group and set its properties.
|
|
676
|
+
|
|
677
|
+
Args:
|
|
678
|
+
group_type: The type of group (e.g., 'company', 'team').
|
|
679
|
+
group_key: The unique identifier for the group.
|
|
680
|
+
properties: A dictionary of properties to set on the group.
|
|
681
|
+
timestamp: The timestamp of the event.
|
|
682
|
+
uuid: A unique identifier for the event.
|
|
683
|
+
disable_geoip: Whether to disable GeoIP for this event.
|
|
684
|
+
distinct_id: The distinct ID of the user performing the action.
|
|
685
|
+
|
|
686
|
+
Examples:
|
|
687
|
+
```python
|
|
688
|
+
posthog.group_identify('company', 'company_id_in_your_db', {
|
|
689
|
+
'name': 'Awesome Inc.',
|
|
690
|
+
'employees': 11
|
|
691
|
+
})
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
Category:
|
|
695
|
+
Identification
|
|
696
|
+
"""
|
|
494
697
|
properties = properties or {}
|
|
495
698
|
|
|
496
699
|
# group_identify is purposefully always personful
|
|
497
700
|
distinct_id = get_identity_state(distinct_id)[0]
|
|
498
701
|
|
|
499
|
-
msg = {
|
|
702
|
+
msg: Dict[str, Any] = {
|
|
500
703
|
"event": "$groupidentify",
|
|
501
704
|
"properties": {
|
|
502
705
|
"$group_type": group_type,
|
|
@@ -510,7 +713,7 @@ class Client(object):
|
|
|
510
713
|
|
|
511
714
|
# NOTE - group_identify doesn't generally use context properties - should it?
|
|
512
715
|
if get_context_session_id():
|
|
513
|
-
msg["properties"]["$session_id"] = get_context_session_id()
|
|
716
|
+
msg["properties"]["$session_id"] = str(get_context_session_id())
|
|
514
717
|
|
|
515
718
|
return self._enqueue(msg, disable_geoip)
|
|
516
719
|
|
|
@@ -522,6 +725,24 @@ class Client(object):
|
|
|
522
725
|
uuid=None,
|
|
523
726
|
disable_geoip=None,
|
|
524
727
|
):
|
|
728
|
+
"""
|
|
729
|
+
Create an alias between two distinct IDs.
|
|
730
|
+
|
|
731
|
+
Args:
|
|
732
|
+
previous_id: The previous distinct ID.
|
|
733
|
+
distinct_id: The new distinct ID to alias to.
|
|
734
|
+
timestamp: The timestamp of the event.
|
|
735
|
+
uuid: A unique identifier for the event.
|
|
736
|
+
disable_geoip: Whether to disable GeoIP for this event.
|
|
737
|
+
|
|
738
|
+
Examples:
|
|
739
|
+
```python
|
|
740
|
+
posthog.alias(previous_id='distinct_id', distinct_id='alias_id')
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
Category:
|
|
744
|
+
Identification
|
|
745
|
+
"""
|
|
525
746
|
(distinct_id, personless) = get_identity_state(distinct_id)
|
|
526
747
|
|
|
527
748
|
if personless:
|
|
@@ -539,7 +760,7 @@ class Client(object):
|
|
|
539
760
|
}
|
|
540
761
|
|
|
541
762
|
if get_context_session_id():
|
|
542
|
-
msg["properties"]["$session_id"] = get_context_session_id()
|
|
763
|
+
msg["properties"]["$session_id"] = str(get_context_session_id())
|
|
543
764
|
|
|
544
765
|
return self._enqueue(msg, disable_geoip)
|
|
545
766
|
|
|
@@ -548,6 +769,28 @@ class Client(object):
|
|
|
548
769
|
exception: Optional[ExceptionArg],
|
|
549
770
|
**kwargs: Unpack[OptionalCaptureArgs],
|
|
550
771
|
):
|
|
772
|
+
"""
|
|
773
|
+
Capture an exception for error tracking.
|
|
774
|
+
|
|
775
|
+
Args:
|
|
776
|
+
exception: The exception to capture.
|
|
777
|
+
distinct_id: The distinct ID of the user.
|
|
778
|
+
properties: A dictionary of additional properties.
|
|
779
|
+
send_feature_flags: Whether to send feature flags with the exception.
|
|
780
|
+
disable_geoip: Whether to disable GeoIP for this event.
|
|
781
|
+
|
|
782
|
+
Examples:
|
|
783
|
+
```python
|
|
784
|
+
try:
|
|
785
|
+
# Some code that might fail
|
|
786
|
+
pass
|
|
787
|
+
except Exception as e:
|
|
788
|
+
posthog.capture_exception(e, 'user_distinct_id', properties=additional_properties)
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
Category:
|
|
792
|
+
Error Tracking
|
|
793
|
+
"""
|
|
551
794
|
distinct_id = kwargs.get("distinct_id", None)
|
|
552
795
|
properties = kwargs.get("properties", None)
|
|
553
796
|
send_feature_flags = kwargs.get("send_feature_flags", False)
|
|
@@ -703,7 +946,15 @@ class Client(object):
|
|
|
703
946
|
return None
|
|
704
947
|
|
|
705
948
|
def flush(self):
|
|
706
|
-
"""
|
|
949
|
+
"""
|
|
950
|
+
Force a flush from the internal queue to the server. Do not use directly, call `shutdown()` instead.
|
|
951
|
+
|
|
952
|
+
Examples:
|
|
953
|
+
```python
|
|
954
|
+
posthog.capture('event_name')
|
|
955
|
+
posthog.flush() # Ensures the event is sent immediately
|
|
956
|
+
```
|
|
957
|
+
"""
|
|
707
958
|
queue = self.queue
|
|
708
959
|
size = queue.qsize()
|
|
709
960
|
queue.join()
|
|
@@ -711,8 +962,13 @@ class Client(object):
|
|
|
711
962
|
self.log.debug("successfully flushed about %s items.", size)
|
|
712
963
|
|
|
713
964
|
def join(self):
|
|
714
|
-
"""
|
|
715
|
-
|
|
965
|
+
"""
|
|
966
|
+
End the consumer thread once the queue is empty. Do not use directly, call `shutdown()` instead.
|
|
967
|
+
|
|
968
|
+
Examples:
|
|
969
|
+
```python
|
|
970
|
+
posthog.join()
|
|
971
|
+
```
|
|
716
972
|
"""
|
|
717
973
|
for consumer in self.consumers:
|
|
718
974
|
consumer.pause()
|
|
@@ -726,7 +982,14 @@ class Client(object):
|
|
|
726
982
|
self.poller.stop()
|
|
727
983
|
|
|
728
984
|
def shutdown(self):
|
|
729
|
-
"""
|
|
985
|
+
"""
|
|
986
|
+
Flush all messages and cleanly shutdown the client. Call this before the process ends in serverless environments to avoid data loss.
|
|
987
|
+
|
|
988
|
+
Examples:
|
|
989
|
+
```python
|
|
990
|
+
posthog.shutdown()
|
|
991
|
+
```
|
|
992
|
+
"""
|
|
730
993
|
self.flush()
|
|
731
994
|
self.join()
|
|
732
995
|
|
|
@@ -799,6 +1062,17 @@ class Client(object):
|
|
|
799
1062
|
self._last_feature_flag_poll = datetime.now(tz=tzutc())
|
|
800
1063
|
|
|
801
1064
|
def load_feature_flags(self):
|
|
1065
|
+
"""
|
|
1066
|
+
Load feature flags for local evaluation.
|
|
1067
|
+
|
|
1068
|
+
Examples:
|
|
1069
|
+
```python
|
|
1070
|
+
posthog.load_feature_flags()
|
|
1071
|
+
```
|
|
1072
|
+
|
|
1073
|
+
Category:
|
|
1074
|
+
Feature Flags
|
|
1075
|
+
"""
|
|
802
1076
|
if not self.personal_api_key:
|
|
803
1077
|
self.log.warning(
|
|
804
1078
|
"[FEATURE FLAGS] You have to specify a personal_api_key to use feature flags."
|
|
@@ -807,7 +1081,11 @@ class Client(object):
|
|
|
807
1081
|
return
|
|
808
1082
|
|
|
809
1083
|
self._load_feature_flags()
|
|
810
|
-
|
|
1084
|
+
|
|
1085
|
+
# Only start the poller if local evaluation is enabled
|
|
1086
|
+
if self.enable_local_evaluation and not (
|
|
1087
|
+
self.poller and self.poller.is_alive()
|
|
1088
|
+
):
|
|
811
1089
|
self.poller = Poller(
|
|
812
1090
|
interval=timedelta(seconds=self.poll_interval),
|
|
813
1091
|
execute=self._load_feature_flags,
|
|
@@ -876,6 +1154,31 @@ class Client(object):
|
|
|
876
1154
|
send_feature_flag_events=True,
|
|
877
1155
|
disable_geoip=None,
|
|
878
1156
|
):
|
|
1157
|
+
"""
|
|
1158
|
+
Check if a feature flag is enabled for a user.
|
|
1159
|
+
|
|
1160
|
+
Args:
|
|
1161
|
+
key: The feature flag key.
|
|
1162
|
+
distinct_id: The distinct ID of the user.
|
|
1163
|
+
groups: A dictionary of group information.
|
|
1164
|
+
person_properties: A dictionary of person properties.
|
|
1165
|
+
group_properties: A dictionary of group properties.
|
|
1166
|
+
only_evaluate_locally: Whether to only evaluate locally.
|
|
1167
|
+
send_feature_flag_events: Whether to send feature flag events.
|
|
1168
|
+
disable_geoip: Whether to disable GeoIP for this request.
|
|
1169
|
+
|
|
1170
|
+
Examples:
|
|
1171
|
+
```python
|
|
1172
|
+
is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')
|
|
1173
|
+
if is_my_flag_enabled:
|
|
1174
|
+
# Do something differently for this user
|
|
1175
|
+
# Optional: fetch the payload
|
|
1176
|
+
matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')
|
|
1177
|
+
```
|
|
1178
|
+
|
|
1179
|
+
Category:
|
|
1180
|
+
Feature Flags
|
|
1181
|
+
"""
|
|
879
1182
|
response = self.get_feature_flag(
|
|
880
1183
|
key,
|
|
881
1184
|
distinct_id,
|
|
@@ -1005,8 +1308,29 @@ class Client(object):
|
|
|
1005
1308
|
"""
|
|
1006
1309
|
Get a FeatureFlagResult object which contains the flag result and payload for a key by evaluating locally or remotely
|
|
1007
1310
|
depending on whether local evaluation is enabled and the flag can be locally evaluated.
|
|
1311
|
+
This also captures the `$feature_flag_called` event unless `send_feature_flag_events` is `False`.
|
|
1312
|
+
|
|
1313
|
+
Examples:
|
|
1314
|
+
```python
|
|
1315
|
+
flag_result = posthog.get_feature_flag_result('flag-key', 'distinct_id_of_your_user')
|
|
1316
|
+
if flag_result and flag_result.get_value() == 'variant-key':
|
|
1317
|
+
# Do something differently for this user
|
|
1318
|
+
# Optional: fetch the payload
|
|
1319
|
+
matched_flag_payload = flag_result.payload
|
|
1320
|
+
```
|
|
1008
1321
|
|
|
1009
|
-
|
|
1322
|
+
Args:
|
|
1323
|
+
key: The feature flag key.
|
|
1324
|
+
distinct_id: The distinct ID of the user.
|
|
1325
|
+
groups: A dictionary of group information.
|
|
1326
|
+
person_properties: A dictionary of person properties.
|
|
1327
|
+
group_properties: A dictionary of group properties.
|
|
1328
|
+
only_evaluate_locally: Whether to only evaluate locally.
|
|
1329
|
+
send_feature_flag_events: Whether to send feature flag events.
|
|
1330
|
+
disable_geoip: Whether to disable GeoIP for this request.
|
|
1331
|
+
|
|
1332
|
+
Returns:
|
|
1333
|
+
Optional[FeatureFlagResult]: The feature flag result or None if disabled/not found.
|
|
1010
1334
|
"""
|
|
1011
1335
|
return self._get_feature_flag_result(
|
|
1012
1336
|
key,
|
|
@@ -1032,11 +1356,29 @@ class Client(object):
|
|
|
1032
1356
|
disable_geoip=None,
|
|
1033
1357
|
) -> Optional[FlagValue]:
|
|
1034
1358
|
"""
|
|
1035
|
-
Get
|
|
1036
|
-
depending on whether local evaluation is enabled and the flag can be
|
|
1037
|
-
locally evaluated.
|
|
1359
|
+
Get multivariate feature flag value for a user.
|
|
1038
1360
|
|
|
1039
|
-
|
|
1361
|
+
Args:
|
|
1362
|
+
key: The feature flag key.
|
|
1363
|
+
distinct_id: The distinct ID of the user.
|
|
1364
|
+
groups: A dictionary of group information.
|
|
1365
|
+
person_properties: A dictionary of person properties.
|
|
1366
|
+
group_properties: A dictionary of group properties.
|
|
1367
|
+
only_evaluate_locally: Whether to only evaluate locally.
|
|
1368
|
+
send_feature_flag_events: Whether to send feature flag events.
|
|
1369
|
+
disable_geoip: Whether to disable GeoIP for this request.
|
|
1370
|
+
|
|
1371
|
+
Examples:
|
|
1372
|
+
```python
|
|
1373
|
+
enabled_variant = posthog.get_feature_flag('flag-key', 'distinct_id_of_your_user')
|
|
1374
|
+
if enabled_variant == 'variant-key': # replace 'variant-key' with the key of your variant
|
|
1375
|
+
# Do something differently for this user
|
|
1376
|
+
# Optional: fetch the payload
|
|
1377
|
+
matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')
|
|
1378
|
+
```
|
|
1379
|
+
|
|
1380
|
+
Category:
|
|
1381
|
+
Feature Flags
|
|
1040
1382
|
"""
|
|
1041
1383
|
feature_flag_result = self.get_feature_flag_result(
|
|
1042
1384
|
key,
|
|
@@ -1101,6 +1443,33 @@ class Client(object):
|
|
|
1101
1443
|
send_feature_flag_events=True,
|
|
1102
1444
|
disable_geoip=None,
|
|
1103
1445
|
):
|
|
1446
|
+
"""
|
|
1447
|
+
Get the payload for a feature flag.
|
|
1448
|
+
|
|
1449
|
+
Args:
|
|
1450
|
+
key: The feature flag key.
|
|
1451
|
+
distinct_id: The distinct ID of the user.
|
|
1452
|
+
match_value: The specific flag value to get payload for.
|
|
1453
|
+
groups: A dictionary of group information.
|
|
1454
|
+
person_properties: A dictionary of person properties.
|
|
1455
|
+
group_properties: A dictionary of group properties.
|
|
1456
|
+
only_evaluate_locally: Whether to only evaluate locally.
|
|
1457
|
+
send_feature_flag_events: Whether to send feature flag events.
|
|
1458
|
+
disable_geoip: Whether to disable GeoIP for this request.
|
|
1459
|
+
|
|
1460
|
+
Examples:
|
|
1461
|
+
```python
|
|
1462
|
+
is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')
|
|
1463
|
+
|
|
1464
|
+
if is_my_flag_enabled:
|
|
1465
|
+
# Do something differently for this user
|
|
1466
|
+
# Optional: fetch the payload
|
|
1467
|
+
matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')
|
|
1468
|
+
```
|
|
1469
|
+
|
|
1470
|
+
Category:
|
|
1471
|
+
Feature Flags
|
|
1472
|
+
"""
|
|
1104
1473
|
feature_flag_result = self._get_feature_flag_result(
|
|
1105
1474
|
key,
|
|
1106
1475
|
distinct_id,
|
|
@@ -1243,6 +1612,25 @@ class Client(object):
|
|
|
1243
1612
|
only_evaluate_locally=False,
|
|
1244
1613
|
disable_geoip=None,
|
|
1245
1614
|
) -> Optional[dict[str, Union[bool, str]]]:
|
|
1615
|
+
"""
|
|
1616
|
+
Get all feature flags for a user.
|
|
1617
|
+
|
|
1618
|
+
Args:
|
|
1619
|
+
distinct_id: The distinct ID of the user.
|
|
1620
|
+
groups: A dictionary of group information.
|
|
1621
|
+
person_properties: A dictionary of person properties.
|
|
1622
|
+
group_properties: A dictionary of group properties.
|
|
1623
|
+
only_evaluate_locally: Whether to only evaluate locally.
|
|
1624
|
+
disable_geoip: Whether to disable GeoIP for this request.
|
|
1625
|
+
|
|
1626
|
+
Examples:
|
|
1627
|
+
```python
|
|
1628
|
+
posthog.get_all_flags('distinct_id_of_your_user')
|
|
1629
|
+
```
|
|
1630
|
+
|
|
1631
|
+
Category:
|
|
1632
|
+
Feature Flags
|
|
1633
|
+
"""
|
|
1246
1634
|
response = self.get_all_flags_and_payloads(
|
|
1247
1635
|
distinct_id,
|
|
1248
1636
|
groups=groups,
|
|
@@ -1264,6 +1652,25 @@ class Client(object):
|
|
|
1264
1652
|
only_evaluate_locally=False,
|
|
1265
1653
|
disable_geoip=None,
|
|
1266
1654
|
) -> FlagsAndPayloads:
|
|
1655
|
+
"""
|
|
1656
|
+
Get all feature flags and their payloads for a user.
|
|
1657
|
+
|
|
1658
|
+
Args:
|
|
1659
|
+
distinct_id: The distinct ID of the user.
|
|
1660
|
+
groups: A dictionary of group information.
|
|
1661
|
+
person_properties: A dictionary of person properties.
|
|
1662
|
+
group_properties: A dictionary of group properties.
|
|
1663
|
+
only_evaluate_locally: Whether to only evaluate locally.
|
|
1664
|
+
disable_geoip: Whether to disable GeoIP for this request.
|
|
1665
|
+
|
|
1666
|
+
Examples:
|
|
1667
|
+
```python
|
|
1668
|
+
posthog.get_all_flags_and_payloads('distinct_id_of_your_user')
|
|
1669
|
+
```
|
|
1670
|
+
|
|
1671
|
+
Category:
|
|
1672
|
+
Feature Flags
|
|
1673
|
+
"""
|
|
1267
1674
|
if self.disabled:
|
|
1268
1675
|
return {"featureFlags": None, "featureFlagPayloads": None}
|
|
1269
1676
|
|