55from typing import (
66 Any , Callable , Iterable , Union ,
77 List , Tuple , Sequence ,
8+ Mapping ,
9+ cast ,
810)
911
1012import appdirs
@@ -39,7 +41,7 @@ def parse_api_version(value: str) -> Tuple[int, str]:
3941
4042def get_env (key : str , default : Any = _undefined , * ,
4143 clean : Callable [[str ], Any ] = lambda v : v ):
42- '''
44+ """
4345 Retrieves a configuration value from the environment variables.
4446 The given *key* is uppercased and prefixed by ``"BACKEND_"`` and then
4547 ``"SORNA_"`` if the former does not exist.
@@ -52,7 +54,7 @@ def get_env(key: str, default: Any = _undefined, *,
5254 The default is returning the value as-is.
5355
5456 :returns: The value processed by the *clean* function.
55- '''
57+ """
5658 key = key .upper ()
5759 v = os .environ .get ('BACKEND_' + key )
5860 if v is None :
@@ -73,7 +75,7 @@ def bool_env(v: str) -> bool:
7375 raise ValueError ('Unrecognized value of boolean environment variable' , v )
7476
7577
76- def _clean_urls (v : str ) -> List [URL ]:
78+ def _clean_urls (v : Union [ URL , str ] ) -> List [URL ]:
7779 if isinstance (v , URL ):
7880 return [v ]
7981 if isinstance (v , str ):
@@ -95,7 +97,7 @@ def _clean_tokens(v):
9597
9698
9799class APIConfig :
98- '''
100+ """
99101 Represents a set of API client configurations.
100102 The access key and secret key are mandatory -- they must be set in either
101103 environment variables or as the explicit arguments.
@@ -129,9 +131,9 @@ class APIConfig:
129131 access key) to be automatically mounted upon any
130132 :func:`Kernel.get_or_create()
131133 <ai.backend.client.kernel.Kernel.get_or_create>` calls.
132- '''
134+ """
133135
134- DEFAULTS = {
136+ DEFAULTS : Mapping [ str , Any ] = {
135137 'endpoint' : 'https://api.backend.ai' ,
136138 'endpoint_type' : 'api' ,
137139 'version' : f'v{ API_VERSION [0 ]} .{ API_VERSION [1 ]} ' ,
@@ -141,9 +143,12 @@ class APIConfig:
141143 'connection_timeout' : 10.0 ,
142144 'read_timeout' : None ,
143145 }
144- '''
146+ """
145147 The default values except the access and secret keys.
146- '''
148+ """
149+
150+ _group : str
151+ _hash_type : str
147152
148153 def __init__ (self , * ,
149154 endpoint : Union [URL , str ] = None ,
@@ -159,17 +164,17 @@ def __init__(self, *,
159164 skip_sslcert_validation : bool = None ,
160165 connection_timeout : float = None ,
161166 read_timeout : float = None ) -> None :
162- from . import get_user_agent # noqa; to avoid circular imports
167+ from . import get_user_agent
163168 self ._endpoints = (
164169 _clean_urls (endpoint ) if endpoint else
165170 get_env ('ENDPOINT' , self .DEFAULTS ['endpoint' ], clean = _clean_urls ))
166171 random .shuffle (self ._endpoints )
167- self ._endpoint_type = endpoint_type if endpoint_type \
172+ self ._endpoint_type = endpoint_type if endpoint_type is not None \
168173 else get_env ('ENDPOINT_TYPE' , self .DEFAULTS ['endpoint_type' ])
169- self ._domain = domain if domain else get_env ('DOMAIN' , self .DEFAULTS ['domain' ])
170- self ._group = group if group else get_env ('GROUP' , self .DEFAULTS ['group' ])
171- self ._version = version if version else self .DEFAULTS ['version' ]
172- self ._user_agent = user_agent if user_agent else get_user_agent ()
174+ self ._domain = domain if domain is not None else get_env ('DOMAIN' , self .DEFAULTS ['domain' ])
175+ self ._group = group if group is not None else get_env ('GROUP' , self .DEFAULTS ['group' ])
176+ self ._version = version if version is not None else self .DEFAULTS ['version' ]
177+ self ._user_agent = user_agent if user_agent is not None else get_user_agent ()
173178 if self ._endpoint_type == 'api' :
174179 self ._access_key = access_key if access_key is not None \
175180 else get_env ('ACCESS_KEY' , '' )
@@ -178,8 +183,8 @@ def __init__(self, *,
178183 else :
179184 self ._access_key = 'dummy'
180185 self ._secret_key = 'dummy'
181- self ._hash_type = hash_type .lower () if hash_type else \
182- self .DEFAULTS ['hash_type' ]
186+ self ._hash_type = hash_type .lower () if hash_type is not None else \
187+ cast ( str , self .DEFAULTS ['hash_type' ])
183188 arg_vfolders = set (vfolder_mounts ) if vfolder_mounts else set ()
184189 env_vfolders = set (get_env ('VFOLDER_MOUNTS' , [], clean = _clean_tokens ))
185190 self ._vfolder_mounts = [* (arg_vfolders | env_vfolders )]
@@ -198,16 +203,16 @@ def is_anonymous(self) -> bool:
198203
199204 @property
200205 def endpoint (self ) -> URL :
201- '''
206+ """
202207 The currently active endpoint URL.
203208 This may change if there are multiple configured endpoints
204209 and the current one is not accessible.
205- '''
210+ """
206211 return self ._endpoints [0 ]
207212
208213 @property
209214 def endpoints (self ) -> Sequence [URL ]:
210- ''' All configured endpoint URLs.'''
215+ """ All configured endpoint URLs."""
211216 return self ._endpoints
212217
213218 def rotate_endpoints (self ):
@@ -217,83 +222,83 @@ def rotate_endpoints(self):
217222
218223 @property
219224 def endpoint_type (self ) -> str :
220- '''
225+ """
221226 The configured endpoint type.
222- '''
227+ """
223228 return self ._endpoint_type
224229
225230 @property
226231 def domain (self ) -> str :
227- ''' The configured domain.'''
232+ """ The configured domain."""
228233 return self ._domain
229234
230235 @property
231236 def group (self ) -> str :
232- ''' The configured group.'''
237+ """ The configured group."""
233238 return self ._group
234239
235240 @property
236241 def user_agent (self ) -> str :
237- ''' The configured user agent string.'''
242+ """ The configured user agent string."""
238243 return self ._user_agent
239244
240245 @property
241246 def access_key (self ) -> str :
242- ''' The configured API access key.'''
247+ """ The configured API access key."""
243248 return self ._access_key
244249
245250 @property
246251 def secret_key (self ) -> str :
247- ''' The configured API secret key.'''
252+ """ The configured API secret key."""
248253 return self ._secret_key
249254
250255 @property
251256 def version (self ) -> str :
252- ''' The configured API protocol version.'''
257+ """ The configured API protocol version."""
253258 return self ._version
254259
255260 @property
256261 def hash_type (self ) -> str :
257- ''' The configured hash algorithm for API authentication signatures.'''
262+ """ The configured hash algorithm for API authentication signatures."""
258263 return self ._hash_type
259264
260265 @property
261- def vfolder_mounts (self ) -> Tuple [str , ... ]:
262- ''' The configured auto-mounted vfolder list.'''
266+ def vfolder_mounts (self ) -> Sequence [str ]:
267+ """ The configured auto-mounted vfolder list."""
263268 return self ._vfolder_mounts
264269
265270 @property
266271 def skip_sslcert_validation (self ) -> bool :
267- ''' Whether to skip SSL certificate validation for the API gateway.'''
272+ """ Whether to skip SSL certificate validation for the API gateway."""
268273 return self ._skip_sslcert_validation
269274
270275 @property
271276 def connection_timeout (self ) -> float :
272- ''' The maximum allowed duration for making TCP connections to the server.'''
277+ """ The maximum allowed duration for making TCP connections to the server."""
273278 return self ._connection_timeout
274279
275280 @property
276281 def read_timeout (self ) -> float :
277- ''' The maximum allowed waiting time for the first byte of the response from the server.'''
282+ """ The maximum allowed waiting time for the first byte of the response from the server."""
278283 return self ._read_timeout
279284
280285
281286def get_config ():
282- '''
287+ """
283288 Returns the configuration for the current process.
284289 If there is no explicitly set :class:`APIConfig` instance,
285290 it will generate a new one from the current environment variables
286291 and defaults.
287- '''
292+ """
288293 global _config
289294 if _config is None :
290295 _config = APIConfig ()
291296 return _config
292297
293298
294299def set_config (conf : APIConfig ):
295- '''
300+ """
296301 Sets the configuration used throughout the current process.
297- '''
302+ """
298303 global _config
299304 _config = conf
0 commit comments