From 7b67befcfb16d0ecfaf3c75f3e7a6c44682e9cff Mon Sep 17 00:00:00 2001 From: Sebastian Turner Date: Sun, 18 Oct 2026 17:06:36 -0700 Subject: [PATCH] fix(flags): accept rediss:// URLs for flag_fallback_cache_url Signed-off-by: Sebastian Turner --- .sampo/changesets/flag-cache-rediss-scheme.md | 5 ++++ posthog/client.py | 5 ++-- posthog/test/test_client.py | 27 +++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 .sampo/changesets/flag-cache-rediss-scheme.md diff --git a/.sampo/changesets/flag-cache-rediss-scheme.md b/.sampo/changesets/flag-cache-rediss-scheme.md new file mode 100644 index 000000000..92e5490e1 --- /dev/null +++ b/.sampo/changesets/flag-cache-rediss-scheme.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +Accept rediss:// URLs in flag_fallback_cache_url so the flag fallback cache can use Redis over TLS. diff --git a/posthog/client.py b/posthog/client.py index 2f33a29ae..1efb521e3 100644 --- a/posthog/client.py +++ b/posthog/client.py @@ -4823,6 +4823,7 @@ def _initialize_flag_cache(self, cache_url): - "memory://local/?ttl=300&size=10000": Memory cache with TTL and size - "redis://localhost:6379/0/?ttl=300": Redis cache with TTL - "redis://username:password@host:port/?ttl=300": Redis with auth + - "rediss://username:password@host:port/?ttl=300": Redis over TLS Example usage: # Memory cache @@ -4858,7 +4859,7 @@ def _initialize_flag_cache(self, cache_url): size = int(query_params.get("size", [10000])[0]) return FlagCache(size, ttl) - elif scheme == "redis": + elif scheme in ("redis", "rediss"): try: # Not worth importing redis if we're not using it import redis @@ -4891,7 +4892,7 @@ def _initialize_flag_cache(self, cache_url): return None else: raise ValueError( - f"Unknown cache URL scheme: {scheme}. Supported schemes: memory, redis" + f"Unknown cache URL scheme: {scheme}. Supported schemes: memory, redis, rediss" ) except Exception as e: diff --git a/posthog/test/test_client.py b/posthog/test/test_client.py index 1c86a0daa..2a1923028 100644 --- a/posthog/test/test_client.py +++ b/posthog/test/test_client.py @@ -24,6 +24,7 @@ from posthog.test.logging_helpers import capture_message_only_logs from posthog.test.test_utils import FAKE_TEST_API_KEY from posthog.types import FeatureFlag, FeatureFlagResult, LegacyFlagMetadata +from posthog.utils import RedisFlagCache from posthog.version import VERSION from posthog.contexts import tag @@ -2589,6 +2590,32 @@ def test_shutdown_clears_feature_flag_called_dedupe_cache(self): self.assertEqual(len(client.distinct_ids_feature_flags_reported), 0) + @parameterized.expand( + [ + ("redis://localhost:6379/0/?ttl=120", "redis://localhost:6379/0/"), + ( + "rediss://user:secret@cache.example.com:6380/1?ttl=120", + "rediss://user:secret@cache.example.com:6380/1", + ), + ] + ) + def test_flag_fallback_cache_url_accepts_redis_schemes( + self, cache_url, expected_redis_url + ): + fake_redis = mock.Mock() + with mock.patch.dict(sys.modules, {"redis": fake_redis}): + client = Client( + FAKE_TEST_API_KEY, + send=False, + thread=0, + flag_fallback_cache_url=cache_url, + ) + + fake_redis.from_url.assert_called_once_with(expected_redis_url) + self.assertIsInstance(client.flag_cache, RedisFlagCache) + self.assertEqual(client.flag_cache.default_ttl, 120) + client.shutdown() + def test_shutdown_flushes_without_timeout(self): client = Client(FAKE_TEST_API_KEY, flush_interval=0.01)