66import os
77import platform
88import uuid
9- from typing import Iterable , Optional , Union
9+ from collections . abc import Iterable
1010
1111import certifi
1212import grpc
2424_LOGGER = logging .getLogger (__name__ )
2525
2626
27- def _certs () -> bytes :
27+ def _load_certs () -> bytes :
28+ """Loads cacert.pem."""
2829 with open (certifi .where (), "rb" ) as f :
2930 return f .read ()
3031
3132
32- def _api_key (api_key : Optional [str ] = None ) -> str :
33+ def _get_api_key (api_key : str | None = None ) -> str :
34+ """Get API Key either from provided value or environment variable."""
3335 if api_key is None :
3436 api_key = os .getenv (_DIODE_API_KEY_ENVVAR_NAME )
3537 if api_key is None :
@@ -39,7 +41,8 @@ def _api_key(api_key: Optional[str] = None) -> str:
3941 return api_key
4042
4143
42- def _tls_verify (tls_verify : Optional [bool ]) -> bool :
44+ def _get_tls_verify (tls_verify : bool | None ) -> bool :
45+ """Get TLS Verify either from provided value or environment variable."""
4346 if tls_verify is None :
4447 tls_verify_env_var = os .getenv (_DIODE_TLS_VERIFY_ENVVAR_NAME , "false" )
4548 return tls_verify_env_var .lower () in ["true" , "1" , "yes" ]
@@ -50,7 +53,7 @@ def _tls_verify(tls_verify: Optional[bool]) -> bool:
5053
5154
5255def parse_target (target : str ) -> tuple [str , str ]:
53- """Parse target."""
56+ """Parse the target into authority and path ."""
5457 if target .startswith (("http://" , "https://" )):
5558 raise ValueError ("target should not contain http:// or https://" )
5659
@@ -68,7 +71,8 @@ def parse_target(target: str) -> tuple[str, str]:
6871 return authority , path
6972
7073
71- def _sentry_dsn (sentry_dsn : Optional [str ] = None ) -> str :
74+ def _get_sentry_dsn (sentry_dsn : str | None = None ) -> str | None :
75+ """Get Sentry DSN either from provided value or environment variable."""
7276 if sentry_dsn is None :
7377 sentry_dsn = os .getenv (_DIODE_SENTRY_DSN_ENVVAR_NAME )
7478 return sentry_dsn
@@ -89,7 +93,7 @@ def __init__(
8993 target : str ,
9094 app_name : str ,
9195 app_version : str ,
92- api_key : Optional [ str ] = None ,
96+ api_key : str | None = None ,
9397 tls_verify : bool = None ,
9498 sentry_dsn : str = None ,
9599 sentry_traces_sample_rate : float = 1.0 ,
@@ -105,30 +109,33 @@ def __init__(
105109 self ._platform = platform .platform ()
106110 self ._python_version = platform .python_version ()
107111
108- api_key = _api_key (api_key )
112+ api_key = _get_api_key (api_key )
109113 self ._metadata = (
110114 ("diode-api-key" , api_key ),
111115 ("platform" , self ._platform ),
112116 ("python-version" , self ._python_version ),
113117 )
114118
115- self ._tls_verify = _tls_verify (tls_verify )
119+ self ._tls_verify = _get_tls_verify (tls_verify )
116120
117121 if self ._tls_verify :
122+ _LOGGER .debug ("Setting up gRPC secure channel" )
118123 self ._channel = grpc .secure_channel (
119124 self ._target ,
120125 grpc .ssl_channel_credentials (
121- root_certificates = _certs (),
126+ root_certificates = _load_certs (),
122127 ),
123128 )
124129 else :
130+ _LOGGER .debug ("Setting up gRPC insecure channel" )
125131 self ._channel = grpc .insecure_channel (
126132 target = self ._target ,
127133 )
128134
129135 channel = self ._channel
130136
131137 if self ._path :
138+ _LOGGER .debug (f"Setting up gRPC interceptor for path: { self ._path } " )
132139 rpc_method_interceptor = DiodeMethodClientInterceptor (subpath = self ._path )
133140
134141 intercept_channel = grpc .intercept_channel (
@@ -138,9 +145,10 @@ def __init__(
138145
139146 self ._stub = ingester_pb2_grpc .IngesterServiceStub (channel )
140147
141- self ._sentry_dsn = _sentry_dsn (sentry_dsn )
148+ self ._sentry_dsn = _get_sentry_dsn (sentry_dsn )
142149
143150 if self ._sentry_dsn is not None :
151+ _LOGGER .debug ("Setting up Sentry" )
144152 self ._setup_sentry (
145153 self ._sentry_dsn , sentry_traces_sample_rate , sentry_profiles_sample_rate
146154 )
@@ -199,8 +207,8 @@ def close(self):
199207
200208 def ingest (
201209 self ,
202- entities : Iterable [Optional [ Union [ Entity , ingester_pb2 .Entity ]] ],
203- stream : Optional [ str ] = _DEFAULT_STREAM ,
210+ entities : Iterable [Entity | ingester_pb2 .Entity | None ],
211+ stream : str | None = _DEFAULT_STREAM ,
204212 ) -> ingester_pb2 .IngestResponse :
205213 """Ingest entities."""
206214 try :
@@ -250,15 +258,30 @@ class _ClientCallDetails(
250258 ),
251259 grpc .ClientCallDetails ,
252260):
253- """Client Call Details."""
261+ """
262+ _ClientCallDetails class.
263+
264+ This class describes an RPC to be invoked and is required for custom gRPC interceptors.
265+
266+ """
254267
255268 pass
256269
257270
258271class DiodeMethodClientInterceptor (
259272 grpc .UnaryUnaryClientInterceptor , grpc .StreamUnaryClientInterceptor
260273):
261- """Diode Method Client Interceptor."""
274+ """
275+ Diode Method Client Interceptor class.
276+
277+ This class is used to intercept the client calls and modify the method details. It inherits from
278+ grpc.UnaryUnaryClientInterceptor and grpc.StreamUnaryClientInterceptor.
279+
280+ Diode's default method generated from Protocol Buffers definition is /diode.v1.IngesterService/Ingest and in order
281+ to use Diode targets with path (i.e. localhost:8081/this/is/custom/path), this interceptor is used to modify the
282+ method details, by prepending the generated method name with the path extracted from initial target.
283+
284+ """
262285
263286 def __init__ (self , subpath ):
264287 """Initiate a new interceptor."""
0 commit comments