telemetry refactor + unit tests (#2786)

This commit is contained in:
Thomas Brandého 2024-03-13 20:38:54 +01:00 committed by GitHub
parent f52ff56440
commit 92db402539
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 85 additions and 33 deletions

View File

@ -61,23 +61,28 @@ jobs:
working-directory: ./reflex-examples/counter working-directory: ./reflex-examples/counter
shell: wsl-bash {0} shell: wsl-bash {0}
run: | run: |
export TELEMETRY_ENABLED=false
poetry run reflex export --backend-only poetry run reflex export --backend-only
- name: Check run --backend-only before init for counter example - name: Check run --backend-only before init for counter example
shell: wsl-bash {0} shell: wsl-bash {0}
run: | run: |
export TELEMETRY_ENABLED=false
dos2unix scripts/integration.sh dos2unix scripts/integration.sh
poetry run bash scripts/integration.sh ./reflex-examples/counter dev 8001 --backend-only --backend-port 8001 poetry run bash scripts/integration.sh ./reflex-examples/counter dev 8001 --backend-only --backend-port 8001
- name: Init Website for counter example - name: Init Website for counter example
working-directory: ./reflex-examples/counter working-directory: ./reflex-examples/counter
shell: wsl-bash {0} shell: wsl-bash {0}
run: | run: |
export TELEMETRY_ENABLED=false
poetry run reflex init --loglevel debug poetry run reflex init --loglevel debug
- name: Check export for counter example - name: Check export for counter example
working-directory: ./reflex-examples/counter working-directory: ./reflex-examples/counter
shell: wsl-bash {0} shell: wsl-bash {0}
run: | run: |
export TELEMETRY_ENABLED=false
poetry run reflex export --frontend-only --loglevel debug poetry run reflex export --frontend-only --loglevel debug
- name: Run Website and Check for errors - name: Run Website and Check for errors
shell: wsl-bash {0} shell: wsl-bash {0}
run: | run: |
export TELEMETRY_ENABLED=false
poetry run bash scripts/integration.sh ./reflex-examples/counter dev poetry run bash scripts/integration.sh ./reflex-examples/counter dev

View File

@ -434,19 +434,21 @@ def initialize_app_directory(app_name: str, template: constants.Templates.Kind):
) )
def get_project_hash() -> int | None: def get_project_hash(raise_on_fail: bool = False) -> int | None:
"""Get the project hash from the reflex.json file if the file exists. """Get the project hash from the reflex.json file if the file exists.
Args:
raise_on_fail: Whether to raise an error if the file does not exist.
Returns: Returns:
project_hash: The app hash. project_hash: The app hash.
""" """
if not os.path.exists(constants.Reflex.JSON): if not os.path.exists(constants.Reflex.JSON) and not raise_on_fail:
return None return None
# Open and read the file # Open and read the file
with open(constants.Reflex.JSON, "r") as file: with open(constants.Reflex.JSON, "r") as file:
data = json.load(file) data = json.load(file)
project_hash = data["project_hash"] return data["project_hash"]
return project_hash
def initialize_web_directory(): def initialize_web_directory():

View File

@ -2,15 +2,16 @@
from __future__ import annotations from __future__ import annotations
import json
import multiprocessing import multiprocessing
import platform import platform
from datetime import datetime from datetime import datetime
import httpx
import psutil import psutil
from reflex import constants from reflex import constants
from reflex.utils.prerequisites import ensure_reflex_installation_id from reflex.utils import console
from reflex.utils.prerequisites import ensure_reflex_installation_id, get_project_hash
POSTHOG_API_URL: str = "https://app.posthog.com/capture/" POSTHOG_API_URL: str = "https://app.posthog.com/capture/"
@ -57,7 +58,52 @@ def get_memory() -> int:
Returns: Returns:
The total memory in MB. The total memory in MB.
""" """
return psutil.virtual_memory().total >> 20 try:
return psutil.virtual_memory().total >> 20
except ValueError: # needed to pass ubuntu test
return 0
def _prepare_event(event: str) -> dict:
"""Prepare the event to be sent to the PostHog server.
Args:
event: The event name.
Returns:
The event data.
"""
installation_id = ensure_reflex_installation_id()
project_hash = get_project_hash(raise_on_fail=True)
if installation_id is None or project_hash is None:
console.debug(
f"Could not get installation_id or project_hash: {installation_id}, {project_hash}"
)
return {}
return {
"api_key": "phc_JoMo0fOyi0GQAooY3UyO9k0hebGkMyFJrrCw1Gt5SGb",
"event": event,
"properties": {
"distinct_id": installation_id,
"distinct_app_id": project_hash,
"user_os": get_os(),
"reflex_version": get_reflex_version(),
"python_version": get_python_version(),
"cpu_count": get_cpu_count(),
"memory": get_memory(),
},
"timestamp": datetime.utcnow().isoformat(),
}
def _send_event(event_data: dict) -> bool:
try:
httpx.post(POSTHOG_API_URL, json=event_data)
return True
except Exception:
return False
def send(event: str, telemetry_enabled: bool | None = None) -> bool: def send(event: str, telemetry_enabled: bool | None = None) -> bool:
@ -70,8 +116,6 @@ def send(event: str, telemetry_enabled: bool | None = None) -> bool:
Returns: Returns:
Whether the telemetry was sent successfully. Whether the telemetry was sent successfully.
""" """
import httpx
from reflex.config import get_config from reflex.config import get_config
# Get the telemetry_enabled from the config if it is not specified. # Get the telemetry_enabled from the config if it is not specified.
@ -82,29 +126,8 @@ 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() event_data = _prepare_event(event)
if installation_id is None: if not event_data:
return False return False
try: return _send_event(event_data)
with open(constants.Dirs.REFLEX_JSON) as f:
reflex_json = json.load(f)
project_hash = reflex_json["project_hash"]
post_hog = {
"api_key": "phc_JoMo0fOyi0GQAooY3UyO9k0hebGkMyFJrrCw1Gt5SGb",
"event": event,
"properties": {
"distinct_id": installation_id,
"distinct_app_id": project_hash,
"user_os": get_os(),
"reflex_version": get_reflex_version(),
"python_version": get_python_version(),
"cpu_count": get_cpu_count(),
"memory": get_memory(),
},
"timestamp": datetime.utcnow().isoformat(),
}
httpx.post(POSTHOG_API_URL, json=post_hog)
return True
except Exception:
return False

View File

@ -1,3 +1,5 @@
import httpx
import pytest
from packaging.version import parse as parse_python_version from packaging.version import parse as parse_python_version
from reflex.utils import telemetry from reflex.utils import telemetry
@ -28,3 +30,23 @@ def test_telemetry():
def test_disable(): def test_disable():
"""Test that disabling telemetry works.""" """Test that disabling telemetry works."""
assert not telemetry.send("test", telemetry_enabled=False) assert not telemetry.send("test", telemetry_enabled=False)
@pytest.mark.parametrize("event", ["init", "reinit", "run-dev", "run-prod", "export"])
def test_send(mocker, event):
mocker.patch("httpx.post")
mocker.patch(
"builtins.open",
mocker.mock_open(
read_data='{"project_hash": "78285505863498957834586115958872998605"}'
),
)
telemetry.send(event, telemetry_enabled=True)
httpx.post.assert_called_once()
if telemetry.get_os() == "Windows":
open.assert_called_with(".web\\reflex.json", "r")
elif telemetry.get_os() == "Linux":
open.assert_called_with("/proc/meminfo", "rb", buffering=32768)
else:
open.assert_called_with(".web/reflex.json", "r")