Pārlūkot izejas kodu

Rework telemetry to support installation_id (#2480)

jackie-pc 1 gadu atpakaļ
vecāks
revīzija
80c9eb34e4

+ 4 - 0
reflex/reflex.py

@@ -80,6 +80,10 @@ def _init(
 
 
     prerequisites.check_latest_package_version(constants.Reflex.MODULE_NAME)
     prerequisites.check_latest_package_version(constants.Reflex.MODULE_NAME)
 
 
+    prerequisites.initialize_reflex_user_directory()
+
+    prerequisites.ensure_reflex_installation_id()
+
     # Set up the app directory, only if the config doesn't exist.
     # Set up the app directory, only if the config doesn't exist.
     if not os.path.exists(constants.Config.FILE):
     if not os.path.exists(constants.Config.FILE):
         if template is None:
         if template is None:

+ 41 - 3
reflex/utils/prerequisites.py

@@ -16,7 +16,7 @@ import zipfile
 from fileinput import FileInput
 from fileinput import FileInput
 from pathlib import Path
 from pathlib import Path
 from types import ModuleType
 from types import ModuleType
-from typing import Callable
+from typing import Callable, Optional
 
 
 import httpx
 import httpx
 import pkg_resources
 import pkg_resources
@@ -824,10 +824,48 @@ def validate_frontend_dependencies(init=True):
         validate_bun()
         validate_bun()
 
 
 
 
-def initialize_frontend_dependencies():
-    """Initialize all the frontend dependencies."""
+def ensure_reflex_installation_id() -> Optional[int]:
+    """Ensures that a reflex distinct id has been generated and stored in the reflex directory.
+
+    Returns:
+        Distinct id.
+    """
+    try:
+        initialize_reflex_user_directory()
+        installation_id_file = os.path.join(constants.Reflex.DIR, "installation_id")
+
+        installation_id = None
+        if os.path.exists(installation_id_file):
+            try:
+                with open(installation_id_file, "r") as f:
+                    installation_id = int(f.read())
+            except Exception:
+                # If anything goes wrong at all... just regenerate.
+                # Like what? Examples:
+                #     - file not exists
+                #     - file not readable
+                #     - content not parseable as an int
+                pass
+
+        if installation_id is None:
+            installation_id = random.getrandbits(128)
+            with open(installation_id_file, "w") as f:
+                f.write(str(installation_id))
+        # If we get here, installation_id is definitely set
+        return installation_id
+    except Exception as e:
+        console.debug(f"Failed to ensure reflex installation id: {e}")
+        return None
+
+
+def initialize_reflex_user_directory():
+    """Initialize the reflex user directory."""
     # Create the reflex directory.
     # Create the reflex directory.
     path_ops.mkdir(constants.Reflex.DIR)
     path_ops.mkdir(constants.Reflex.DIR)
+
+
+def initialize_frontend_dependencies():
+    """Initialize all the frontend dependencies."""
     # validate dependencies before install
     # validate dependencies before install
     validate_frontend_dependencies()
     validate_frontend_dependencies()
     # Install the frontend dependencies.
     # Install the frontend dependencies.

+ 8 - 2
reflex/utils/telemetry.py

@@ -10,6 +10,7 @@ from datetime import datetime
 import psutil
 import psutil
 
 
 from reflex import constants
 from reflex import constants
+from reflex.utils.prerequisites import ensure_reflex_installation_id
 
 
 
 
 def get_os() -> str:
 def get_os() -> str:
@@ -79,15 +80,20 @@ def send(event: str, telemetry_enabled: bool | None = None) -> bool:
     if not telemetry_enabled:
     if not telemetry_enabled:
         return False
         return False
 
 
+    installation_id = ensure_reflex_installation_id()
+    if installation_id is None:
+        return False
+
     try:
     try:
         with open(constants.Dirs.REFLEX_JSON) as f:
         with open(constants.Dirs.REFLEX_JSON) as f:
             reflex_json = json.load(f)
             reflex_json = json.load(f)
-            distinct_id = reflex_json["project_hash"]
+            project_hash = reflex_json["project_hash"]
         post_hog = {
         post_hog = {
             "api_key": "phc_JoMo0fOyi0GQAooY3UyO9k0hebGkMyFJrrCw1Gt5SGb",
             "api_key": "phc_JoMo0fOyi0GQAooY3UyO9k0hebGkMyFJrrCw1Gt5SGb",
             "event": event,
             "event": event,
             "properties": {
             "properties": {
-                "distinct_id": distinct_id,
+                "distinct_id": installation_id,
+                "distinct_app_id": project_hash,
                 "user_os": get_os(),
                 "user_os": get_os(),
                 "reflex_version": get_reflex_version(),
                 "reflex_version": get_reflex_version(),
                 "python_version": get_python_version(),
                 "python_version": get_python_version(),

+ 1 - 1
tests/utils/test_utils.py

@@ -485,7 +485,7 @@ def test_create_reflex_dir(mocker, is_windows):
         "reflex.utils.prerequisites.path_ops.mkdir", mocker.Mock()
         "reflex.utils.prerequisites.path_ops.mkdir", mocker.Mock()
     )
     )
 
 
-    prerequisites.initialize_frontend_dependencies()
+    prerequisites.initialize_reflex_user_directory()
 
 
     assert create_cmd.called
     assert create_cmd.called