@@ -19,21 +19,50 @@ class ClientConfig:
1919 headers : Optional [Mapping [str , str ]] = None
2020
2121 def __post_init__ (self ) -> None :
22- if not isinstance (self .api_key , str ):
23- raise HyperbrowserError ("api_key must be a string" )
24- self .api_key = self .api_key .strip ()
25- if not self .api_key :
26- raise HyperbrowserError ("api_key must not be empty" )
27- if any (
28- ord (character ) < 32 or ord (character ) == 127 for character in self .api_key
29- ):
30- raise HyperbrowserError ("api_key must not contain control characters" )
22+ self .api_key = self .normalize_api_key (self .api_key )
3123 self .base_url = self .normalize_base_url (self .base_url )
3224 self .headers = normalize_headers (
3325 self .headers ,
3426 mapping_error_message = "headers must be a mapping of string pairs" ,
3527 )
3628
29+ @staticmethod
30+ def normalize_api_key (
31+ api_key : str ,
32+ * ,
33+ empty_error_message : str = "api_key must not be empty" ,
34+ ) -> str :
35+ if not isinstance (api_key , str ):
36+ raise HyperbrowserError ("api_key must be a string" )
37+ try :
38+ normalized_api_key = api_key .strip ()
39+ if not isinstance (normalized_api_key , str ):
40+ raise TypeError ("normalized api_key must be a string" )
41+ except HyperbrowserError :
42+ raise
43+ except Exception as exc :
44+ raise HyperbrowserError (
45+ "Failed to normalize api_key" ,
46+ original_error = exc ,
47+ ) from exc
48+ if not normalized_api_key :
49+ raise HyperbrowserError (empty_error_message )
50+ try :
51+ contains_control_character = any (
52+ ord (character ) < 32 or ord (character ) == 127
53+ for character in normalized_api_key
54+ )
55+ except HyperbrowserError :
56+ raise
57+ except Exception as exc :
58+ raise HyperbrowserError (
59+ "Failed to validate api_key characters" ,
60+ original_error = exc ,
61+ ) from exc
62+ if contains_control_character :
63+ raise HyperbrowserError ("api_key must not contain control characters" )
64+ return normalized_api_key
65+
3766 @staticmethod
3867 def _decode_url_component_with_limit (value : str , * , component_label : str ) -> str :
3968 decoded_value = value
@@ -264,10 +293,14 @@ def normalize_base_url(base_url: str) -> str:
264293 @classmethod
265294 def from_env (cls ) -> "ClientConfig" :
266295 api_key = os .environ .get ("HYPERBROWSER_API_KEY" )
267- if api_key is None or not api_key . strip () :
296+ if api_key is None :
268297 raise HyperbrowserError (
269298 "HYPERBROWSER_API_KEY environment variable is required"
270299 )
300+ api_key = cls .normalize_api_key (
301+ api_key ,
302+ empty_error_message = "HYPERBROWSER_API_KEY environment variable is required" ,
303+ )
271304
272305 base_url = cls .resolve_base_url_from_env (
273306 os .environ .get ("HYPERBROWSER_BASE_URL" )
0 commit comments