1
- from typing import Dict , Any , Union , Optional
1
+ from typing import Dict , Any , Union , Optional , Type
2
2
import os
3
3
import logging
4
4
import atexit
5
- import functools
6
- import asyncio
7
- import time
8
5
9
6
from graphsignal .version import __version__
10
7
from graphsignal .tracer import Tracer
11
8
from graphsignal .spans import Span
12
- from graphsignal import client
13
9
14
10
logger = logging .getLogger ('graphsignal' )
15
11
@@ -23,66 +19,85 @@ def _check_configured():
23
19
'Tracer not configured, call graphsignal.configure() first' )
24
20
25
21
26
- def _check_and_set_arg (
27
- name , value , is_str = False , is_int = False , is_bool = False , is_kv = False , required = False , max_len = None ) :
28
- env_name = 'GRAPHSIGNAL_{0}' . format ( name . upper ())
22
+ def _parse_env_param ( name : str , value : Any , expected_type : Type ) -> Any :
23
+ if value is None :
24
+ return None
29
25
30
- if not value and env_name in os .environ :
31
- value = os .environ [env_name ]
32
- if value :
33
- if is_str :
34
- if max_len and len (value ) > max_len :
35
- raise ValueError ('configure: invalid format, expected string with max length {0}: {1}' .format (max_len , name ))
36
- if is_int :
37
- try :
38
- value = int (value )
39
- except :
40
- raise ValueError ('configure: invalid format, expected integer: {0}' .format (name ))
41
- elif is_bool :
42
- value = bool (value )
43
- elif is_kv :
44
- try :
45
- value = dict ([el .strip (' ' ) for el in kv .split ('=' )] for kv in value .split (',' ))
46
- except :
47
- raise ValueError ('configure: invalid format, expected comma-separated key-value list (k1=v1,k2=v2): {0}' .format (name ))
26
+ try :
27
+ if expected_type == bool :
28
+ return value if isinstance (value , bool ) else str (value ).lower () in ("true" , "1" , "yes" )
29
+ elif expected_type == int :
30
+ return int (value )
31
+ elif expected_type == float :
32
+ return float (value )
33
+ elif expected_type == str :
34
+ return str (value )
35
+ except (ValueError , TypeError ):
36
+ pass
48
37
49
- if not value and required :
50
- raise ValueError ('configure: missing argument: {0}' .format (name ))
38
+ raise ValueError (f"Invalid type for { name } : expected { expected_type .__name__ } , got { type (value ).__name__ } " )
51
39
52
- return value
40
+
41
+ def _read_config_param (name : str , expected_type : Type , provided_value : Optional [Any ] = None , required : bool = False ) -> Any :
42
+ # Check if the value was provided as an argument
43
+ if provided_value is not None :
44
+ return provided_value
45
+
46
+ # Check if the value was provided as an environment variable
47
+ env_value = os .getenv (f'GRAPHSIGNAL_{ name .upper ()} ' )
48
+ if env_value is None :
49
+ if required :
50
+ raise ValueError (f"Missing required argument: { name } " )
51
+ return None
52
+
53
+ # Parse the environment variable
54
+ return _parse_env_param (name , env_value , expected_type )
55
+
56
+
57
+ def _read_config_tags (provided_value : Optional [dict ] = None , prefix : str = "GRAPHSIGNAL_TAG_" ) -> Dict [str , str ]:
58
+ # Check if the value was provided as an argument
59
+ if provided_value is not None :
60
+ return provided_value
61
+
62
+ # Check if the value was provided as an environment variable
63
+ return {key [len (prefix ):].lower (): value for key , value in os .environ .items () if key .startswith (prefix )}
53
64
54
65
55
66
def configure (
56
- api_key : Optional [str ] = None ,
57
- api_url : Optional [str ] = None ,
58
- deployment : Optional [str ] = None ,
59
- tags : Optional [Dict [str , str ]] = None ,
60
- auto_instrument : Optional [bool ] = True ,
61
- record_payloads : Optional [bool ] = True ,
62
- profiling_rate : Optional [float ] = 0.1 ,
63
- upload_on_shutdown : Optional [bool ] = True ,
64
- debug_mode : Optional [ bool ] = False ) -> None :
67
+ api_key : Optional [str ] = None ,
68
+ api_url : Optional [str ] = None ,
69
+ deployment : Optional [str ] = None ,
70
+ tags : Optional [Dict [str , str ]] = None ,
71
+ auto_instrument : Optional [bool ] = True ,
72
+ record_payloads : Optional [bool ] = True ,
73
+ profiling_rate : Optional [float ] = 0.1 ,
74
+ debug_mode : Optional [bool ] = False
75
+ ) -> None :
65
76
global _tracer
66
77
67
78
if _tracer :
68
- logger .warning (' Tracer already configured' )
79
+ logger .warning (" Tracer already configured" )
69
80
return
70
81
71
- debug_mode = _check_and_set_arg ('debug_mode' , debug_mode , is_bool = True )
72
- api_key = _check_and_set_arg ('api_key' , api_key , is_str = True , required = True )
73
- api_url = _check_and_set_arg ('api_url' , api_url , is_str = True , required = False )
74
- deployment = _check_and_set_arg ('deployment' , deployment , is_str = True , required = True )
75
- tags = _check_and_set_arg ('tags' , tags , is_kv = True , required = False )
82
+ api_key = _read_config_param ("api_key" , str , api_key , required = True )
83
+ api_url = _read_config_param ("api_url" , str , api_url )
84
+ tags = _read_config_tags (tags )
85
+ auto_instrument = _read_config_param ("auto_instrument" , bool , auto_instrument )
86
+ record_payloads = _read_config_param ("record_payloads" , bool , record_payloads )
87
+ profiling_rate = _read_config_param ("profiling_rate" , float , profiling_rate )
88
+ debug_mode = _read_config_param ("debug_mode" , bool , debug_mode )
89
+
90
+ # left for compatibility
91
+ if deployment and isinstance (deployment , str ):
92
+ tags ['deployment' ] = deployment
76
93
77
94
_tracer = Tracer (
78
95
api_key = api_key ,
79
96
api_url = api_url ,
80
- deployment = deployment ,
81
97
tags = tags ,
82
98
auto_instrument = auto_instrument ,
83
99
record_payloads = record_payloads ,
84
100
profiling_rate = profiling_rate ,
85
- upload_on_shutdown = upload_on_shutdown ,
86
101
debug_mode = debug_mode )
87
102
_tracer .setup ()
88
103
0 commit comments