-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path_track_cli.py
More file actions
114 lines (94 loc) · 3.77 KB
/
_track_cli.py
File metadata and controls
114 lines (94 loc) · 3.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
from __future__ import annotations
import os
import json
import time
import uuid
import threading
from enum import Enum
from typing import Any, TypeVar, Callable
from functools import wraps
import click
import httpx
import machineid
from together import __version__
from together.lib.utils import log_debug
F = TypeVar("F", bound=Callable[..., Any])
SESSION_ID = int(str(uuid.uuid4().int)[0:13])
def is_tracking_enabled() -> bool:
# Users can opt-out of tracking with the environment variable.
if os.getenv("TOGETHER_TELEMETRY_DISABLED"):
log_debug("Analytics tracking disabled by environment variable")
return False
return True
class CliTrackingEvents(Enum):
CommandStarted = "cli_command_started"
CommandCompleted = "cli_commmand_completed"
CommandFailed = "cli_command_failed"
CommandUserAborted = "cli_command_user_aborted"
ApiRequest = "cli_command_api_request"
def track_cli(event_name: CliTrackingEvents, args: dict[str, Any]) -> None:
"""Track a CLI event. Non-Blocking."""
if is_tracking_enabled() == False:
return
def send_event() -> None:
ANALYTICS_API_ENV_VAR = os.getenv("TOGETHER_TELEMETRY_API")
ANALYTICS_API = (
ANALYTICS_API_ENV_VAR
if ANALYTICS_API_ENV_VAR
else "https://api.together.dev/together/gateway/pub/v1/httpRequest"
)
try:
client = httpx.Client()
client.post(
ANALYTICS_API,
headers={"content-type": "application/json", "user-agent": f"together-cli:{__version__}"},
content=json.dumps(
{
"event_source": "cli",
"event_type": event_name.value,
"event_properties": {
"is_ci": os.getenv("CI") is not None,
**args,
},
"context": {
"session_id": str(SESSION_ID),
"runtime": {
"name": "together-cli",
"version": __version__,
},
},
"identity": {
"device_id": machineid.id().lower(),
},
"event_options": {
"time": int(time.time() * 1000),
},
}
),
)
except Exception as e:
log_debug("Error sending analytics event", error=e)
# No-op - this is not critical and we don't want to block the CLI
pass
threading.Thread(target=send_event).start()
def auto_track_command(command: str) -> Callable[[F], F]:
"""Decorator for click commands to automatically track CLI commands start/completion/failure."""
def decorator(f: F) -> F:
@wraps(f)
def wrapper(*args: Any, **kwargs: Any) -> Any:
track_cli(CliTrackingEvents.CommandStarted, {"command": command, "arguments": kwargs})
try:
return f(*args, **kwargs)
except click.Abort:
# Doesn't seem like this is working any more
track_cli(
CliTrackingEvents.CommandUserAborted,
{"command": command, "arguments": kwargs},
)
except Exception as e:
track_cli(CliTrackingEvents.CommandFailed, {"command": command, "arguments": kwargs, "error": str(e)})
raise e
finally:
track_cli(CliTrackingEvents.CommandCompleted, {"command": command, "arguments": kwargs})
return wrapper # type: ignore
return decorator # type: ignore