|
| 1 | +#!/usr/bin/env python |
| 2 | +""" |
| 3 | +Test script to observe ETag support for local evaluation polling. |
| 4 | +
|
| 5 | +This script starts a PostHog client with local evaluation enabled and |
| 6 | +watches the polling behavior to see ETag/304 responses in action. |
| 7 | +
|
| 8 | +Usage: |
| 9 | + 1. Copy .env.example to .env and fill in your credentials |
| 10 | + 2. Run: uv run python test_etag.py |
| 11 | +""" |
| 12 | + |
| 13 | +import logging |
| 14 | +import os |
| 15 | +import time |
| 16 | + |
| 17 | +# Set up logging BEFORE importing posthog |
| 18 | +logging.basicConfig( |
| 19 | + level=logging.DEBUG, |
| 20 | + format="%(asctime)s [%(levelname)s] %(name)s: %(message)s", |
| 21 | + datefmt="%H:%M:%S", |
| 22 | +) |
| 23 | + |
| 24 | +import posthog |
| 25 | + |
| 26 | + |
| 27 | +def load_env_file(): |
| 28 | + """Load environment variables from .env file if it exists.""" |
| 29 | + env_path = os.path.join(os.path.dirname(__file__), ".env") |
| 30 | + if os.path.exists(env_path): |
| 31 | + with open(env_path, "r") as f: |
| 32 | + for line in f: |
| 33 | + line = line.strip() |
| 34 | + if line and not line.startswith("#") and "=" in line: |
| 35 | + key, value = line.split("=", 1) |
| 36 | + os.environ.setdefault(key.strip(), value.strip()) |
| 37 | + |
| 38 | + |
| 39 | +load_env_file() |
| 40 | + |
| 41 | +project_key = os.getenv("POSTHOG_PROJECT_API_KEY", "") |
| 42 | +personal_api_key = os.getenv("POSTHOG_PERSONAL_API_KEY", "") |
| 43 | +host = os.getenv("POSTHOG_HOST", "https://us.posthog.com") |
| 44 | + |
| 45 | +if not project_key or not personal_api_key: |
| 46 | + print("Missing credentials. Set POSTHOG_PROJECT_API_KEY and POSTHOG_PERSONAL_API_KEY") |
| 47 | + print("Or copy .env.example to .env and fill in your values") |
| 48 | + exit(1) |
| 49 | + |
| 50 | +print("=" * 70) |
| 51 | +print("ETag Support Test") |
| 52 | +print("=" * 70) |
| 53 | +print(f"Host: {host}") |
| 54 | +print(f"Project Key: {project_key[:12]}...") |
| 55 | +print(f"Poll Interval: 5 seconds") |
| 56 | +print() |
| 57 | +print("Watch for these log messages:") |
| 58 | +print(" - First poll: 'GET ... completed successfully' (200 response)") |
| 59 | +print(" - Subsequent polls: 'Flags not modified (304)' (if flags unchanged)") |
| 60 | +print(" - 'GET ... returned 304 Not Modified' from request layer") |
| 61 | +print() |
| 62 | +print("Press Ctrl+C to stop") |
| 63 | +print("=" * 70) |
| 64 | +print() |
| 65 | + |
| 66 | +# Configure PostHog with short poll interval to see ETag behavior quickly |
| 67 | +posthog.api_key = project_key |
| 68 | +posthog.project_api_key = project_key |
| 69 | +posthog.personal_api_key = personal_api_key |
| 70 | +posthog.host = host |
| 71 | +posthog.debug = True |
| 72 | +posthog.poll_interval = 5 # Poll every 5 seconds to see ETag behavior |
| 73 | + |
| 74 | +try: |
| 75 | + # This triggers initial flag load and starts the poller |
| 76 | + print("Starting client and loading feature flags...") |
| 77 | + flags = posthog.get_all_flags("test-user", only_evaluate_locally=True) |
| 78 | + print(f"\nLoaded {len(flags)} flags: {list(flags.keys())[:5]}{'...' if len(flags) > 5 else ''}") |
| 79 | + print() |
| 80 | + |
| 81 | + # Keep running so we can observe the poller |
| 82 | + poll_count = 0 |
| 83 | + while True: |
| 84 | + poll_count += 1 |
| 85 | + time.sleep(6) # Slightly longer than poll interval |
| 86 | + |
| 87 | + # Show current flags after each poll |
| 88 | + flags = posthog.get_all_flags("test-user", only_evaluate_locally=True) |
| 89 | + print(f"\n--- After poll #{poll_count + 1} ---") |
| 90 | + print(f"Flags ({len(flags)}): {flags}") |
| 91 | + print() |
| 92 | + |
| 93 | +except KeyboardInterrupt: |
| 94 | + print("\n\nShutting down...") |
| 95 | + posthog.shutdown() |
| 96 | + print("Done!") |
0 commit comments