6363import typing
6464from json import dumps
6565from os import environ
66+ from types import ModuleType
67+ from typing import List , MutableMapping , Optional , cast
6668from urllib import parse
6769
6870from opentelemetry .attributes import BoundedAttributes
7577from opentelemetry .util ._importlib_metadata import entry_points , version
7678from opentelemetry .util .types import AttributeValue
7779
80+ psutil : Optional [ModuleType ] = None
81+
7882try :
79- import psutil
83+ import psutil as psutil_module
84+
85+ pustil = psutil_module
8086except ImportError :
81- psutil = None
87+ pass
8288
8389LabelValue = AttributeValue
8490Attributes = typing .Mapping [str , LabelValue ]
141147TELEMETRY_AUTO_VERSION = ResourceAttributes .TELEMETRY_AUTO_VERSION
142148TELEMETRY_SDK_LANGUAGE = ResourceAttributes .TELEMETRY_SDK_LANGUAGE
143149
144- _OPENTELEMETRY_SDK_VERSION = version ("opentelemetry-sdk" )
150+ _OPENTELEMETRY_SDK_VERSION : str = version ("opentelemetry-sdk" )
145151
146152
147153class Resource :
148154 """A Resource is an immutable representation of the entity producing telemetry as Attributes."""
149155
156+ _attributes : BoundedAttributes
157+ _schema_url : str
158+
150159 def __init__ (
151160 self , attributes : Attributes , schema_url : typing .Optional [str ] = None
152161 ):
@@ -173,7 +182,7 @@ def create(
173182 if not attributes :
174183 attributes = {}
175184
176- resource_detectors = []
185+ resource_detectors : List [ ResourceDetector ] = []
177186
178187 resource = _DEFAULT_RESOURCE
179188
@@ -184,26 +193,27 @@ def create(
184193 if "otel" not in otel_experimental_resource_detectors :
185194 otel_experimental_resource_detectors .append ("otel" )
186195
196+ resource_detector : str
187197 for resource_detector in otel_experimental_resource_detectors :
188198 resource_detectors .append (
189199 next (
190200 iter (
191201 entry_points (
192202 group = "opentelemetry_resource_detector" ,
193203 name = resource_detector .strip (),
194- )
204+ ) # type: ignore
195205 )
196206 ).load ()()
197207 )
198-
199208 resource = get_aggregated_resources (
200209 resource_detectors , _DEFAULT_RESOURCE
201210 ).merge (Resource (attributes , schema_url ))
202211
203212 if not resource .attributes .get (SERVICE_NAME , None ):
204213 default_service_name = "unknown_service"
205- process_executable_name = resource .attributes .get (
206- PROCESS_EXECUTABLE_NAME , None
214+ process_executable_name = cast (
215+ Optional [str ],
216+ resource .attributes .get (PROCESS_EXECUTABLE_NAME , None ),
207217 )
208218 if process_executable_name :
209219 default_service_name += ":" + process_executable_name
@@ -241,8 +251,8 @@ def merge(self, other: "Resource") -> "Resource":
241251 Returns:
242252 The newly-created Resource.
243253 """
244- merged_attributes = self .attributes .copy ()
245- merged_attributes .update (other .attributes )
254+ merged_attributes = self .attributes .copy () # type: ignore
255+ merged_attributes .update (other .attributes ) # type: ignore
246256
247257 if self .schema_url == "" :
248258 schema_url = other .schema_url
@@ -257,8 +267,7 @@ def merge(self, other: "Resource") -> "Resource":
257267 other .schema_url ,
258268 )
259269 return self
260-
261- return Resource (merged_attributes , schema_url )
270+ return Resource (merged_attributes , schema_url ) # type: ignore
262271
263272 def __eq__ (self , other : object ) -> bool :
264273 if not isinstance (other , Resource ):
@@ -268,15 +277,18 @@ def __eq__(self, other: object) -> bool:
268277 and self ._schema_url == other ._schema_url
269278 )
270279
271- def __hash__ (self ):
280+ def __hash__ (self ) -> int :
272281 return hash (
273- f"{ dumps (self ._attributes .copy (), sort_keys = True )} |{ self ._schema_url } "
282+ f"{ dumps (self ._attributes .copy (), sort_keys = True )} |{ self ._schema_url } " # type: ignore
274283 )
275284
276- def to_json (self , indent = 4 ) -> str :
285+ def to_json (self , indent : int = 4 ) -> str :
286+ attributes : MutableMapping [str , AttributeValue ] = dict (
287+ self ._attributes
288+ )
277289 return dumps (
278290 {
279- "attributes" : dict ( self . _attributes ),
291+ "attributes" : attributes , # type: ignore
280292 "schema_url" : self ._schema_url ,
281293 },
282294 indent = indent ,
@@ -294,7 +306,7 @@ def to_json(self, indent=4) -> str:
294306
295307
296308class ResourceDetector (abc .ABC ):
297- def __init__ (self , raise_on_error = False ):
309+ def __init__ (self , raise_on_error : bool = False ) -> None :
298310 self .raise_on_error = raise_on_error
299311
300312 @abc .abstractmethod
@@ -365,16 +377,17 @@ def detect(self) -> "Resource":
365377 resource_info [PROCESS_PARENT_PID ] = os .getppid ()
366378
367379 if psutil is not None :
368- process = psutil .Process ()
369- resource_info [PROCESS_OWNER ] = process .username ()
380+ process : psutil_module .Process = psutil .Process ()
381+ username = process .username ()
382+ resource_info [PROCESS_OWNER ] = username
370383
371- return Resource (resource_info )
384+ return Resource (resource_info ) # type: ignore
372385
373386
374387def get_aggregated_resources (
375388 detectors : typing .List ["ResourceDetector" ],
376389 initial_resource : typing .Optional [Resource ] = None ,
377- timeout = 5 ,
390+ timeout : int = 5 ,
378391) -> "Resource" :
379392 """Retrieves resources from detectors in the order that they were passed
380393
0 commit comments