@@ -54,7 +54,26 @@ def _parse_response(
5454 return StreamResponse (response , data )
5555
5656
57- class TelemetryEndpointMixin :
57+ class TelemetryEndpointMixin (ABC ):
58+ """
59+ Mixin that prepares request metadata for telemetry/tracing.
60+
61+ Note for type-checkers/IDEs:
62+ - This mixin is designed to be used alongside clients that provide
63+ `base_url`, `api_key`, and an `_endpoint_name(path)` method
64+ (see `BaseClient` and `AsyncBaseClient`).
65+ - We declare these attributes here so static analysis tools understand
66+ they are available at runtime via the concrete client classes.
67+ """
68+
69+ # Provided by BaseConfig in concrete clients
70+ base_url : Optional [str ]
71+ api_key : Optional [str ]
72+
73+ # Provided by concrete clients (e.g. BaseClient/AsyncBaseClient)
74+ def _endpoint_name (self , path : str ) -> str : # pragma: no cover - interface hint
75+ raise NotImplementedError
76+
5877 def _normalize_endpoint_from_path (self , path : str ) -> str :
5978 # Convert /api/v2/video/call/{type}/{id} -> api.v2.video.call.$type.$id
6079 norm_parts = []
@@ -82,6 +101,13 @@ def _prepare_request(self, method: str, path: str, query_params, kwargs):
82101 method = method ,
83102 url = url_full ,
84103 )
104+ # Enrich with contextual IDs when available (set by decorators)
105+ call_cid = getattr (self , "_call_cid" , None )
106+ if call_cid :
107+ span_attrs ["stream.call_cid" ] = call_cid
108+ channel_cid = getattr (self , "_channel_cid" , None )
109+ if channel_cid :
110+ span_attrs ["stream.channel_cid" ] = channel_cid
85111 return url_path , url_full , endpoint , span_attrs
86112
87113
@@ -113,10 +139,8 @@ def __exit__(self, exc_type, exc_val, exc_tb):
113139 self .close ()
114140
115141 def _endpoint_name (self , path : str ) -> str :
116- op = current_operation (None )
117- if op :
118- return op
119- return self ._normalize_endpoint_from_path (path )
142+ op = getattr (self , "_operation_name" , None )
143+ return op or current_operation (self ._normalize_endpoint_from_path (path ))
120144
121145 def _request_sync (
122146 self , method : str , path : str , * , query_params = None , args = (), kwargs = None
@@ -281,10 +305,8 @@ async def aclose(self):
281305 await self .client .aclose ()
282306
283307 def _endpoint_name (self , path : str ) -> str :
284- op = current_operation (None )
285- if op :
286- return op
287- return self ._normalize_endpoint_from_path (path )
308+ op = getattr (self , "_operation_name" , None )
309+ return op or current_operation (self ._normalize_endpoint_from_path (path ))
288310
289311 async def _request_async (
290312 self , method : str , path : str , * , query_params = None , args = (), kwargs = None
0 commit comments