Skip to content

Commit 281ba8a

Browse files
matinclaude
andcommitted
Hash IP address, lazy fetch, narrow exception
- SHA256 hash (first 16 chars) instead of raw IP for privacy - Lazy fetch on first telemetry event (not at construction) - Catch RequestException only, not all exceptions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent e9c40cf commit 281ba8a

File tree

2 files changed

+16
-10
lines changed

2 files changed

+16
-10
lines changed

src/garth/telemetry.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -123,19 +123,24 @@ class Telemetry(BaseSettings):
123123

124124
def model_post_init(self, __context):
125125
self._attached_sessions = set()
126-
self._public_ip = (
127-
self._fetch_public_ip() if self.enabled else "disabled"
128-
)
126+
self._ip_hash: str | None = None
127+
128+
@property
129+
def ip_hash(self) -> str:
130+
if self._ip_hash is None:
131+
self._ip_hash = self._fetch_ip_hash()
132+
return self._ip_hash
129133

130134
@staticmethod
131-
def _fetch_public_ip() -> str:
135+
def _fetch_ip_hash() -> str:
136+
import hashlib
137+
132138
try:
133-
import requests as _requests
139+
import requests as _req
134140

135-
return _requests.get(
136-
"https://api.ipify.org", timeout=3
137-
).text.strip()
138-
except Exception:
141+
ip = _req.get("https://api.ipify.org", timeout=3).text.strip()
142+
return hashlib.sha256(ip.encode()).hexdigest()[:16]
143+
except _req.RequestException:
139144
return "unknown"
140145

141146
def _default_callback(self, data: dict):
@@ -158,7 +163,7 @@ def _response_hook(self, response: Response, *args, **kwargs):
158163
data = {
159164
"session_id": self.session_id,
160165
"garth_version": __version__,
161-
"public_ip": self._public_ip,
166+
"ip_hash": self.ip_hash,
162167
"method": request.method,
163168
"url": request.url,
164169
"status_code": response.status_code,

tests/test_telemetry.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ def capture_callback(data):
8383
)
8484

8585
assert authed_client.telemetry.enabled is True
86+
authed_client.telemetry._ip_hash = "test"
8687

8788
profile = authed_client.connectapi("/userprofile-service/socialProfile")
8889
assert profile is not None

0 commit comments

Comments
 (0)