3232from __future__ import annotations
3333
3434import datetime
35- import hashlib
3635import os
3736from contextlib import suppress
38- from dataclasses import asdict , dataclass
3937from enum import Enum
4038from functools import lru_cache
4139from pathlib import Path
42- from typing import TYPE_CHECKING , Any , cast
40+ from typing import Any , cast
4341
4442import requests
4543import ulid
4644import yaml
4745
4846from airbyte import exceptions as exc
4947from airbyte ._util import meta
48+ from airbyte ._util .connector_info import (
49+ ConnectorRuntimeInfo ,
50+ WriterRuntimeInfo ,
51+ )
52+ from airbyte ._util .hashing import one_way_hash
5053from airbyte .version import get_version
5154
5255
53- if TYPE_CHECKING :
54- from airbyte ._writers .base import AirbyteWriterInterface
55- from airbyte .caches .base import CacheBase
56- from airbyte .destinations .base import Destination
57- from airbyte .sources .base import Source
58-
59-
6056DEBUG = True
6157"""Enable debug mode for telemetry code."""
6258
6359
64- HASH_SEED = "PyAirbyte:"
65- """Additional seed for randomizing one-way hashed strings."""
66-
67-
6860PYAIRBYTE_APP_TRACKING_KEY = (
6961 os .environ .get ("AIRBYTE_TRACKING_KEY" , "" ) or "cukeSffc0G6gFQehKDhhzSurDzVSZ2OP"
7062)
@@ -185,83 +177,6 @@ class EventType(str, Enum):
185177 CHECK = "check"
186178
187179
188- @dataclass
189- class CacheTelemetryInfo :
190- type : str
191-
192- @classmethod
193- def from_cache (cls , cache : CacheBase | None ) -> CacheTelemetryInfo :
194- if not cache :
195- return cls (type = "streaming" )
196-
197- return cls (type = type (cache ).__name__ )
198-
199-
200- @dataclass
201- class SourceTelemetryInfo :
202- name : str
203- executor_type : str
204- version : str | None
205-
206- @classmethod
207- def from_source (cls , source : Source | str ) -> SourceTelemetryInfo :
208- if isinstance (source , str ):
209- return cls (
210- name = str (source ),
211- executor_type = UNKNOWN ,
212- version = UNKNOWN ,
213- )
214-
215- # Else, `source` should be a `Source` object at this point
216- return cls (
217- name = source .name ,
218- executor_type = type (source .executor ).__name__ ,
219- version = source .executor .reported_version ,
220- )
221-
222-
223- @dataclass
224- class DestinationTelemetryInfo :
225- name : str
226- executor_type : str
227- version : str | None
228-
229- @classmethod
230- def from_destination (
231- cls ,
232- destination : Destination | AirbyteWriterInterface | str | None ,
233- ) -> DestinationTelemetryInfo :
234- if not destination :
235- return cls (name = UNKNOWN , executor_type = UNKNOWN , version = UNKNOWN )
236-
237- if isinstance (destination , str ):
238- return cls (name = destination , executor_type = UNKNOWN , version = UNKNOWN )
239-
240- if hasattr (destination , "executor" ):
241- return cls (
242- name = destination .name ,
243- executor_type = type (destination .executor ).__name__ ,
244- version = destination .executor .reported_version ,
245- )
246-
247- return cls (
248- name = repr (destination ),
249- executor_type = UNKNOWN ,
250- version = UNKNOWN ,
251- )
252-
253-
254- def one_way_hash (
255- string_to_hash : Any , # noqa: ANN401 # Allow Any type
256- / ,
257- ) -> str :
258- """Return a one-way hash of the given string.
259-
260- To ensure a unique domain of hashes, we prepend a seed to the string before hashing.
261- """
262- return hashlib .sha256 ((HASH_SEED + str (string_to_hash )).encode ()).hexdigest ()
263-
264-
265180@lru_cache
266181def get_env_flags () -> dict [str , Any ]:
267182 flags : dict [str , bool | str ] = {
@@ -283,9 +198,9 @@ def get_env_flags() -> dict[str, Any]:
283198
284199def send_telemetry (
285200 * ,
286- source : Source | str | None ,
287- destination : Destination | AirbyteWriterInterface | str | None ,
288- cache : CacheBase | None ,
201+ source : ConnectorRuntimeInfo | None ,
202+ destination : ConnectorRuntimeInfo | None ,
203+ cache : WriterRuntimeInfo | None ,
289204 state : EventState ,
290205 event_type : EventType ,
291206 number_of_records : int | None = None ,
@@ -297,8 +212,6 @@ def send_telemetry(
297212
298213 payload_props : dict [str , str | int | dict ] = {
299214 "session_id" : PYAIRBYTE_SESSION_ID ,
300- "cache" : asdict (CacheTelemetryInfo .from_cache (cache )),
301- "destination" : asdict (DestinationTelemetryInfo .from_destination (destination )),
302215 "state" : state ,
303216 "version" : get_version (),
304217 "python_version" : meta .get_python_version (),
@@ -308,7 +221,13 @@ def send_telemetry(
308221 }
309222
310223 if source :
311- payload_props ["source" ] = asdict (SourceTelemetryInfo .from_source (source ))
224+ payload_props ["source" ] = source .to_dict ()
225+
226+ if destination :
227+ payload_props ["destination" ] = destination .to_dict ()
228+
229+ if cache :
230+ payload_props ["cache" ] = cache .to_dict ()
312231
313232 if exception :
314233 if isinstance (exception , exc .AirbyteError ):
@@ -345,8 +264,8 @@ def log_config_validation_result(
345264 treated as a source name.
346265 """
347266 send_telemetry (
348- source = name if not name .startswith ("destination-" ) else None ,
349- destination = name if name .startswith ("destination-" ) else None ,
267+ source = ConnectorRuntimeInfo ( name = name ) if not name .startswith ("destination-" ) else None ,
268+ destination = ConnectorRuntimeInfo ( name = name ) if name .startswith ("destination-" ) else None ,
350269 cache = None ,
351270 state = state ,
352271 event_type = EventType .VALIDATE ,
@@ -365,8 +284,8 @@ def log_connector_check_result(
365284 treated as a source name.
366285 """
367286 send_telemetry (
368- source = name if not name .startswith ("destination-" ) else None ,
369- destination = name if name .startswith ("destination-" ) else None ,
287+ source = ConnectorRuntimeInfo ( name = name ) if not name .startswith ("destination-" ) else None ,
288+ destination = ConnectorRuntimeInfo ( name = name ) if name .startswith ("destination-" ) else None ,
370289 cache = None ,
371290 state = state ,
372291 event_type = EventType .CHECK ,
@@ -381,7 +300,7 @@ def log_install_state(
381300) -> None :
382301 """Log an install event."""
383302 send_telemetry (
384- source = name ,
303+ source = ConnectorRuntimeInfo ( name = name ) ,
385304 destination = None ,
386305 cache = None ,
387306 state = state ,
0 commit comments