Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions src/tabpfn_common_utils/telemetry/core/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""
Configuration utilities for telemetry system.

This module provides functionality to download and cache telemetry configuration
from a remote server.
"""

from __future__ import annotations

import logging
import os

from datetime import datetime, timezone
from typing import Any, Dict

import requests
from tabpfn_common_utils.utils import ttl_cache


logger = logging.getLogger(__name__)


@ttl_cache(ttl_seconds=60 * 5)
def download_config() -> Dict[str, Any]:
"""Download the configuration from server.

Returns:
Dict[str, Any]: The configuration.
"""
# Bust the cache
params = {
"timestamp": datetime.now(tz=timezone.utc).isoformat(),
}

# The default configuration
default = {"enabled": False}

# This is a public URL anyone can and should read from
url = os.environ.get(
"TABPFN_TELEMETRY_CONFIG_URL",
"https://storage.googleapis.com/prior-labs-tabpfn-public/config/telemetry.json",
)
try:
resp = requests.get(url, params=params)
except Exception:
logger.debug(f"Failed to download telemetry config: {url}")
return default

# Disable telemetry by default
if resp.status_code != 200:
logger.debug(f"Failed to download telemetry config: {resp.status_code}")
return default

return resp.json()
42 changes: 4 additions & 38 deletions src/tabpfn_common_utils/telemetry/core/service.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import logging
import os
import requests

from datetime import datetime, timezone
from datetime import datetime
from posthog import Posthog
from .config import download_config
from .events import BaseTelemetryEvent
from .runtime import get_runtime
from ...utils import singleton, ttl_cache
from ...utils import singleton
from typing import Any, Dict, Optional


Expand Down Expand Up @@ -67,46 +67,12 @@ def telemetry_enabled(cls) -> bool:
return False

# Overwrite any settings based on server-side configuration
config = cls._download_config()
config = download_config()
if config["enabled"] is False:
return False

return True

@classmethod
@ttl_cache(ttl_seconds=60 * 5)
def _download_config(cls) -> Dict[str, Any]:
"""Download the configuration from server.

Returns:
Dict[str, Any]: The configuration.
"""
# Bust the cache
params = {
"timestamp": datetime.now(tz=timezone.utc).isoformat(),
}

# The default configuration
default = {"enabled": False}

# This is a public URL anyone can and should read from
url = os.environ.get(
"TABPFN_TELEMETRY_CONFIG_URL",
"https://storage.googleapis.com/prior-labs-tabpfn-public/config/telemetry.json",
)
try:
resp = requests.get(url, params=params)
except Exception:
logger.debug(f"Failed to download telemetry config: {url}")
return default

# Disable telemetry by default
if resp.status_code != 200:
logger.debug(f"Failed to download telemetry config: {resp.status_code}")
return default

return resp.json()

def capture(
self,
event: BaseTelemetryEvent,
Expand Down
27 changes: 27 additions & 0 deletions src/tabpfn_common_utils/telemetry/interactive/flows.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from datetime import datetime, timedelta, timezone

from typing import List
from ..core.config import download_config
from ..core.state import get_property, set_property
from ..core import PingEvent, capture_event
from .prompts.base import PromptSpec
Expand Down Expand Up @@ -64,6 +65,32 @@ def _trigger_prompts(delta_days: int, max_prompts: int) -> bool:
"""
utc_now = datetime.now(timezone.utc)

# Download prompt configuration
config = download_config()

# By default, don't prompt
if not config.get("prompt_user", False):
return False

# If new installation, don't prompt
install_date = get_property("install_date", data_type=datetime)
if not install_date:
set_property("install_date", utc_now)
return False

# Avoid prompt in first 24 hours
delta_hours = config.get("prompt_delta_hours", 24)
if utc_now - install_date <= timedelta(hours=delta_hours):
return False

# If used <= 5 times, don't prompt
nr_usages = get_property("nr_usages", 0, data_type=int)
set_property("nr_usages", nr_usages + 1)
Comment thread
safaricd marked this conversation as resolved.

if nr_usages < config.get("prompt_nr_usages", 5):
return False
Comment thread
safaricd marked this conversation as resolved.

# If last prompted > 30 days, prompt
last_prompted_at = get_property("last_prompted_at", data_type=datetime)
if not last_prompted_at:
return True
Expand Down