deepctl-telemetry 0.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- deepctl_telemetry/__init__.py +13 -0
- deepctl_telemetry/client.py +109 -0
- deepctl_telemetry/notice.py +48 -0
- deepctl_telemetry-0.0.2.dist-info/METADATA +59 -0
- deepctl_telemetry-0.0.2.dist-info/RECORD +7 -0
- deepctl_telemetry-0.0.2.dist-info/WHEEL +5 -0
- deepctl_telemetry-0.0.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Opt-out phone-home telemetry for deepctl."""
|
|
2
|
+
|
|
3
|
+
from .client import init_telemetry, is_enabled
|
|
4
|
+
from .notice import install_help_notice, render_notice
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"init_telemetry",
|
|
8
|
+
"install_help_notice",
|
|
9
|
+
"is_enabled",
|
|
10
|
+
"render_notice",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
__version__ = "0.0.2" # x-release-please-version
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"""Sentry-backed telemetry client with strict opt-out."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import platform
|
|
7
|
+
import sys
|
|
8
|
+
from typing import TYPE_CHECKING, Any
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from deepctl_core import Config
|
|
12
|
+
from sentry_sdk.types import Event, Hint
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
SENTRY_DSN = (
|
|
16
|
+
"https://d7a2aabbf772218e3bbe89266999af70"
|
|
17
|
+
"@o206115.ingest.us.sentry.io/4510993603362816"
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
DSN_ENV_VAR = "DEEPCTL_TELEMETRY_DSN"
|
|
21
|
+
DISABLE_ENV_VAR = "DEEPCTL_TELEMETRY_DISABLED"
|
|
22
|
+
|
|
23
|
+
_initialized = False
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def is_enabled(config: Config) -> bool:
|
|
27
|
+
"""Whether telemetry should phone home for this invocation.
|
|
28
|
+
|
|
29
|
+
Resolution order: env override (DEEPCTL_TELEMETRY_DISABLED=1 wins),
|
|
30
|
+
then the user's config (`telemetry.enabled`, default `True`).
|
|
31
|
+
"""
|
|
32
|
+
if os.environ.get(DISABLE_ENV_VAR, "").lower() in {"1", "true", "yes"}:
|
|
33
|
+
return False
|
|
34
|
+
return bool(config.get("telemetry.enabled", True))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def init_telemetry(config: Config) -> bool:
|
|
38
|
+
"""Initialize the Sentry SDK if telemetry is enabled.
|
|
39
|
+
|
|
40
|
+
Idempotent — safe to call multiple times. Returns whether init ran.
|
|
41
|
+
"""
|
|
42
|
+
global _initialized
|
|
43
|
+
if _initialized:
|
|
44
|
+
return True
|
|
45
|
+
if not is_enabled(config):
|
|
46
|
+
return False
|
|
47
|
+
|
|
48
|
+
dsn = os.environ.get(DSN_ENV_VAR) or SENTRY_DSN
|
|
49
|
+
|
|
50
|
+
try:
|
|
51
|
+
import sentry_sdk
|
|
52
|
+
except ImportError:
|
|
53
|
+
return False
|
|
54
|
+
|
|
55
|
+
try:
|
|
56
|
+
cli_version = _read_cli_version()
|
|
57
|
+
except Exception:
|
|
58
|
+
cli_version = "unknown"
|
|
59
|
+
|
|
60
|
+
sentry_sdk.init(
|
|
61
|
+
dsn=dsn,
|
|
62
|
+
release=f"deepctl@{cli_version}",
|
|
63
|
+
environment="production",
|
|
64
|
+
send_default_pii=False,
|
|
65
|
+
traces_sample_rate=0.0,
|
|
66
|
+
profiles_sample_rate=0.0,
|
|
67
|
+
max_breadcrumbs=20,
|
|
68
|
+
before_send=_scrub_event,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
sentry_sdk.set_tag("cli.os", platform.system().lower())
|
|
72
|
+
sentry_sdk.set_tag("cli.arch", platform.machine().lower())
|
|
73
|
+
sentry_sdk.set_tag(
|
|
74
|
+
"cli.python",
|
|
75
|
+
f"{sys.version_info.major}.{sys.version_info.minor}",
|
|
76
|
+
)
|
|
77
|
+
sentry_sdk.set_tag("cli.version", cli_version)
|
|
78
|
+
|
|
79
|
+
_initialized = True
|
|
80
|
+
return True
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _read_cli_version() -> str:
|
|
84
|
+
import importlib.metadata
|
|
85
|
+
|
|
86
|
+
return importlib.metadata.version("deepctl")
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _scrub_event(event: Event, _hint: Hint) -> Event | None:
|
|
90
|
+
"""Drop request bodies, headers, and any user-identifying data.
|
|
91
|
+
|
|
92
|
+
Sentry SDK already filters most PII via send_default_pii=False, but
|
|
93
|
+
Auth tokens, project IDs, and file paths can still leak through
|
|
94
|
+
breadcrumbs and exception messages. This is a defense-in-depth scrub.
|
|
95
|
+
"""
|
|
96
|
+
request: dict[str, Any] = event.get("request") or {}
|
|
97
|
+
if "headers" in request:
|
|
98
|
+
request["headers"] = {}
|
|
99
|
+
if "cookies" in request:
|
|
100
|
+
request["cookies"] = {}
|
|
101
|
+
if "data" in request:
|
|
102
|
+
request["data"] = "[Filtered]"
|
|
103
|
+
|
|
104
|
+
user: dict[str, Any] = event.get("user") or {}
|
|
105
|
+
user.pop("email", None)
|
|
106
|
+
user.pop("ip_address", None)
|
|
107
|
+
user.pop("username", None)
|
|
108
|
+
|
|
109
|
+
return event
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""Subtle telemetry notice appended to `--help` output."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
|
|
7
|
+
import click
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from deepctl_core import Config
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
NOTICE_ON = (
|
|
14
|
+
"Telemetry is on (anonymous error reports). "
|
|
15
|
+
"Disable: dg config set telemetry.enabled false"
|
|
16
|
+
)
|
|
17
|
+
NOTICE_OFF = "Telemetry is off."
|
|
18
|
+
|
|
19
|
+
_installed = False
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def render_notice(config: Config) -> str:
|
|
23
|
+
"""Return the dim one-line notice for the current telemetry state."""
|
|
24
|
+
from .client import is_enabled
|
|
25
|
+
|
|
26
|
+
text = NOTICE_ON if is_enabled(config) else NOTICE_OFF
|
|
27
|
+
return click.style(text, dim=True)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def install_help_notice(config: Config) -> None:
|
|
31
|
+
"""Monkey-patch Click so every `--help` ends with the telemetry notice.
|
|
32
|
+
|
|
33
|
+
Click formats help via `Command.get_help(ctx)`. We wrap that method
|
|
34
|
+
once at startup so every command (including subcommands and plugin
|
|
35
|
+
commands) picks up the footer without needing per-command wiring.
|
|
36
|
+
"""
|
|
37
|
+
global _installed
|
|
38
|
+
if _installed:
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
original_get_help = click.Command.get_help
|
|
42
|
+
notice = render_notice(config)
|
|
43
|
+
|
|
44
|
+
def get_help_with_notice(self: click.Command, ctx: click.Context) -> str:
|
|
45
|
+
return original_get_help(self, ctx) + "\n\n" + notice
|
|
46
|
+
|
|
47
|
+
click.Command.get_help = get_help_with_notice # type: ignore[method-assign]
|
|
48
|
+
_installed = True
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: deepctl-telemetry
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: Opt-out phone-home telemetry for deepctl
|
|
5
|
+
Author-email: Deepgram <devrel@deepgram.com>
|
|
6
|
+
Maintainer-email: Deepgram <devrel@deepgram.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Keywords: deepgram,cli,telemetry,sentry
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
Requires-Dist: deepctl-core>=0.1.10
|
|
18
|
+
Requires-Dist: sentry-sdk>=2.0.0
|
|
19
|
+
Requires-Dist: click>=8.0.0
|
|
20
|
+
Requires-Dist: rich>=13.0.0
|
|
21
|
+
|
|
22
|
+
# deepctl-telemetry
|
|
23
|
+
|
|
24
|
+
> Part of [deepctl](https://github.com/deepgram/cli) — Official Deepgram CLI
|
|
25
|
+
|
|
26
|
+
Opt-out phone-home telemetry for deepctl
|
|
27
|
+
|
|
28
|
+
This package provides internal APIs for deepctl and its command packages. It is not intended for direct use.
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
This package is included with deepctl and does not need to be installed separately.
|
|
33
|
+
|
|
34
|
+
### Install deepctl
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Install with pip
|
|
38
|
+
pip install deepctl
|
|
39
|
+
|
|
40
|
+
# Or install with uv
|
|
41
|
+
uv tool install deepctl
|
|
42
|
+
|
|
43
|
+
# Or install with pipx
|
|
44
|
+
pipx install deepctl
|
|
45
|
+
|
|
46
|
+
# Or run without installing
|
|
47
|
+
uvx deepctl --help
|
|
48
|
+
pipx run deepctl --help
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Dependencies
|
|
52
|
+
|
|
53
|
+
- `sentry-sdk>=2.0.0`
|
|
54
|
+
- `click>=8.0.0`
|
|
55
|
+
- `rich>=13.0.0`
|
|
56
|
+
|
|
57
|
+
## License
|
|
58
|
+
|
|
59
|
+
MIT — see [LICENSE](../../LICENSE)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
deepctl_telemetry/__init__.py,sha256=l5Zba-BzAA11XF35xbnf1mgbYrzKXoGRHy9BNL7Zogc,305
|
|
2
|
+
deepctl_telemetry/client.py,sha256=VNwJISePtQTQ4igNgc2rMg7zZcay44HIurGZxpUbW08,2930
|
|
3
|
+
deepctl_telemetry/notice.py,sha256=SdpDV-a0jNRZkitnKOlfN0-whJAzwMeXgGz9iimr7gY,1357
|
|
4
|
+
deepctl_telemetry-0.0.2.dist-info/METADATA,sha256=A_sHNVzJROSK6ucTut3YO4WyAH-YHZC2lAgjsSEF3Gw,1462
|
|
5
|
+
deepctl_telemetry-0.0.2.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
6
|
+
deepctl_telemetry-0.0.2.dist-info/top_level.txt,sha256=II7mx3AjWibH9PFEoWhcsXgeacQZPazJ_iNkAXnfSBw,18
|
|
7
|
+
deepctl_telemetry-0.0.2.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
deepctl_telemetry
|