Skip to content

Commit

Permalink
fix: Personal api key not required (#56)
Browse files Browse the repository at this point in the history
* fix: Personal api key not required

* formatting

* Fix false
  • Loading branch information
timgl authored Apr 25, 2022
1 parent 565bb8a commit 1777b70
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 35 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

[![PyPI](https://img.shields.io/pypi/v/posthog)](https://pypi.org/project/posthog/)

Please see the main [PostHog docs](https://posthog.com/docs).

Specifically, the [Python integration](https://posthog.com/docs/integrations/python-integration) details.
Please see the [Python integration docs](https://posthog.com/docs/integrations/python-integration) for details.

## Development

Expand All @@ -14,6 +13,7 @@ Specifically, the [Python integration](https://posthog.com/docs/integrations/pyt
2. Run `source env/bin/activate` (activates the virtual environment)
3. Run `python3 -m pip install -e ".[test]"` (installs the package in develop mode, along with test dependencies)
4. Run `make test`
1. To run a specific test do `pytest -k test_no_api_key`

### Running Locally

Expand Down
49 changes: 23 additions & 26 deletions posthog/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,39 +354,36 @@ def feature_enabled(self, key, distinct_id, default=False, *, groups={}):
require("distinct_id", distinct_id, ID_TYPES)
require("groups", groups, dict)

if not self.personal_api_key:
self.log.warning("[FEATURE FLAGS] You have to specify a personal_api_key to use feature flags.")
if not self.feature_flags:
if self.feature_flags == None and self.personal_api_key:
self.load_feature_flags()
response = None

# If loading in previous line failed
if not self.feature_flags:
response = default
else:
if self.feature_flags:
for flag in self.feature_flags:
if flag["key"] == key:
feature_flag = flag
break
else:
return default

if feature_flag.get("is_simple_flag"):
response = _hash(key, distinct_id) <= ((feature_flag.get("rollout_percentage", 100) or 100) / 100)
if feature_flag.get("is_simple_flag"):
response = _hash(key, distinct_id) <= (feature_flag.get("rollout_percentage", 100) / 100)
if response == None:
try:
request_data = {
"distinct_id": distinct_id,
"personal_api_key": self.personal_api_key,
"groups": groups,
}
resp_data = decide(self.api_key, self.host, timeout=10, **request_data)
except Exception as e:
response = default
self.log.warning(
"[FEATURE FLAGS] Unable to get data for flag %s, because of the following error:" % key
)
self.log.warning(e)
else:
try:
request_data = {
"distinct_id": distinct_id,
"personal_api_key": self.personal_api_key,
"groups": groups,
}
resp_data = decide(self.api_key, self.host, timeout=10, **request_data)
response = key in resp_data["featureFlags"]
except Exception as e:
response = default
self.log.warning(
"[FEATURE FLAGS] Unable to get data for flag %s, because of the following error:" % key
)
self.log.warning(e)
if key in resp_data["featureFlags"]:
return True
else:
return default

self.capture(distinct_id, "$feature_flag_called", {"$feature_flag": key, "$feature_flag_response": response})
return response
Expand Down
28 changes: 21 additions & 7 deletions posthog/test/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,13 +404,25 @@ def test_load_feature_flags_wrong_key(self):
with freeze_time("2020-01-01T12:01:00.0000Z"):
self.assertRaises(APIError, client.load_feature_flags)

@mock.patch("posthog.client.decide")
@mock.patch("posthog.client.get")
def test_feature_enabled_simple(self, patch_get):
def test_feature_enabled_simple(self, patch_get, patch_decide):
client = Client(TEST_API_KEY)
client.feature_flags = [
{"id": 1, "name": "Beta Feature", "key": "beta-feature", "is_simple_flag": True, "rollout_percentage": 100}
]
self.assertTrue(client.feature_enabled("beta-feature", "distinct_id"))
self.assertEqual(patch_decide.call_count, 0)

@mock.patch("posthog.client.decide")
@mock.patch("posthog.client.get")
def test_feature_enabled_simple_is_false(self, patch_get, patch_decide):
client = Client(TEST_API_KEY)
client.feature_flags = [
{"id": 1, "name": "Beta Feature", "key": "beta-feature", "is_simple_flag": True, "rollout_percentage": 0}
]
self.assertFalse(client.feature_enabled("beta-feature", "distinct_id"))
self.assertEqual(patch_decide.call_count, 0)

@mock.patch("posthog.client.get")
def test_feature_enabled_simple_with_project_api_key(self, patch_get):
Expand Down Expand Up @@ -444,22 +456,24 @@ def test_feature_enabled_simple_with_none_rollout_percentage(self, patch_get):
self.assertTrue(client.feature_enabled("beta-feature", "distinct_id"))

@mock.patch("posthog.client.Poller")
@mock.patch("posthog.client.get")
def test_feature_enabled_doesnt_exist(self, patch_get, patch_poll):
@mock.patch("posthog.client.decide")
def test_feature_enabled_doesnt_exist(self, patch_decide, patch_poll):
patch_decide.return_value = {"featureFlags": []}
client = Client(TEST_API_KEY, personal_api_key="test")
client.feature_flags = []

self.assertFalse(client.feature_enabled("doesnt-exist", "distinct_id"))
self.assertTrue(client.feature_enabled("doesnt-exist", "distinct_id", True))

@mock.patch("posthog.client.Poller")
@mock.patch("posthog.client.get")
def test_personal_api_key_doesnt_exist(self, patch_get, patch_poll):
@mock.patch("posthog.client.decide")
def test_personal_api_key_doesnt_exist(self, patch_decide, patch_poll):
client = Client(TEST_API_KEY)
client.feature_flags = []

self.assertFalse(client.feature_enabled("doesnt-exist", "distinct_id"))
self.assertTrue(client.feature_enabled("doesnt-exist", "distinct_id", True))
patch_decide.return_value = {"featureFlags": ["feature-flag"]}

self.assertTrue(client.feature_enabled("feature-flag", "distinct_id"))

@mock.patch("posthog.client.Poller")
@mock.patch("posthog.client.get")
Expand Down

0 comments on commit 1777b70

Please sign in to comment.