3636
3737
3838class BaseAuth (ABC ):
39+ """Abstract base class for authentication methods.
40+
41+ This class defines the interface for obtaining authentication metadata
42+ and checking if the authentication method is applicable from environment
43+ variables.
44+ """
3945 @abstractmethod
4046 async def get_auth_metadata (
4147 self ,
4248 client : AsyncCloudClient ,
4349 timeout : float ,
4450 lock : asyncio .Lock
4551 ) -> tuple [str , str ] | None :
52+ """:meta private:"""
4653 # NB: we are can't create lock in Auth constructor, so we a reusing lock from client.
4754 # Look at client._lock doctstring for details.
4855 pass
4956
5057 @classmethod
5158 @abstractmethod
5259 async def applicable_from_env (cls , ** _ : Any ) -> Self | None :
60+ """:meta private:"""
5361 pass
5462
5563
5664class NoAuth (BaseAuth ):
5765 @override
5866 async def get_auth_metadata (self , client : AsyncCloudClient , timeout : float , lock : asyncio .Lock ) -> None :
67+ """:meta private:"""
5968 return None
6069
6170 @override
6271 @classmethod
6372 async def applicable_from_env (cls , ** _ : Any ) -> None :
73+ """:meta private:"""
6474 return None
6575
6676
6777class APIKeyAuth (BaseAuth ):
78+ """Authentication method using an API key.
79+
80+ Read more about the API key in `the documentation <https://yandex.cloud/docs/iam/concepts/authorization/api-key>_`.
81+ """
6882 env_var = 'YC_API_KEY'
6983
7084 def __init__ (self , api_key : str ):
@@ -76,11 +90,13 @@ def __init__(self, api_key: str):
7690
7791 @override
7892 async def get_auth_metadata (self , client : AsyncCloudClient , timeout : float , lock : asyncio .Lock ) -> tuple [str , str ]:
93+ """:meta private:"""
7994 return ('authorization' , f'Api-Key { self ._api_key } ' )
8095
8196 @override
8297 @classmethod
8398 async def applicable_from_env (cls , ** _ : Any ) -> Self | None :
99+ """:meta private:"""
84100 api_key = os .getenv (cls .env_var )
85101 if api_key :
86102 return cls (api_key )
@@ -89,15 +105,25 @@ async def applicable_from_env(cls, **_: Any) -> Self | None:
89105
90106
91107class BaseIAMTokenAuth (BaseAuth ):
108+ """Base class for the IAM token-based authentication."""
92109 def __init__ (self , token : str | None ):
110+ """Initialize with an IAM token.
111+
112+ :param token: The IAM token to use for authentication. If None, it will be set to None.
113+ """
93114 self ._token = token .strip () if token else token
94115
95116 @override
96117 async def get_auth_metadata (self , client : AsyncCloudClient , timeout : float , lock : asyncio .Lock ) -> tuple [str , str ]:
118+ """:meta private:"""
97119 return ('authorization' , f'Bearer { self ._token } ' )
98120
99121
100122class IAMTokenAuth (BaseIAMTokenAuth ):
123+ """Authentication method using an IAM token.
124+
125+ Read more about the IAM token in `the documentation <https://yandex.cloud/docs/iam/concepts/authorization/iam-token>_`.
126+ """
101127 env_var = 'YC_IAM_TOKEN'
102128
103129 def __init__ (self , token : str ):
@@ -106,6 +132,7 @@ def __init__(self, token: str):
106132 @override
107133 @classmethod
108134 async def applicable_from_env (cls , ** _ : Any ) -> Self | None :
135+ """:meta private:"""
109136 token = os .getenv (cls .env_var )
110137 if token :
111138 return cls (token )
@@ -134,12 +161,14 @@ def __init__(self, env_var_name: str | None = None):
134161
135162 @override
136163 async def get_auth_metadata (self , client : AsyncCloudClient , timeout : float , lock : asyncio .Lock ) -> tuple [str , str ]:
164+ """:meta private:"""
137165 self ._token = os .environ [self ._env_var ].strip ()
138166 return await super ().get_auth_metadata (client = client , timeout = timeout , lock = lock )
139167
140168 @override
141169 @classmethod
142170 async def applicable_from_env (cls , ** _ : Any ) -> Self | None :
171+ """:meta private:"""
143172 token = os .getenv (cls .default_env_var )
144173 if token :
145174 return cls ()
@@ -148,6 +177,12 @@ async def applicable_from_env(cls, **_: Any) -> Self | None:
148177
149178
150179class RefresheableIAMTokenAuth (BaseIAMTokenAuth ):
180+ """
181+ Auth method that supports refreshing the IAM token based on a defined refresh period.
182+
183+ This class manages an IAM token that can be refreshed automatically if it has expired,
184+ based on the specified refresh period.
185+ """
151186 _token_refresh_period = 60 * 60
152187
153188 def __init__ (self , token : str | None ) -> None :
@@ -165,6 +200,7 @@ def _need_for_token(self):
165200
166201 @override
167202 async def get_auth_metadata (self , client : AsyncCloudClient , timeout : float , lock : asyncio .Lock ) -> tuple [str , str ]:
203+ """:meta private:"""
168204 if self ._need_for_token ():
169205 async with lock :
170206 if self ._need_for_token ():
@@ -179,6 +215,14 @@ async def _get_token(self, client: AsyncCloudClient, timeout: float) -> str:
179215
180216
181217class OAuthTokenAuth (RefresheableIAMTokenAuth ):
218+ """
219+ Auth method that uses an OAuth token for authentication.
220+
221+ This class extends the RefresheableIAMTokenAuth to provide functionality
222+ for managing and using an OAuth token for authentication purposes.
223+
224+ Read more about the OAuth token in `the documentation <https://yandex.cloud/docs/iam/concepts/authorization/oauth-token>_`.
225+ """
182226 env_var = 'YC_OAUTH_TOKEN'
183227
184228 def __init__ (self , token : str ):
@@ -192,6 +236,7 @@ def __init__(self, token: str):
192236 @override
193237 @classmethod
194238 async def applicable_from_env (cls , ** _ : Any ) -> Self | None :
239+ """:meta private:"""
195240 token = os .getenv (cls .env_var )
196241 if token :
197242 return cls (token )
@@ -213,6 +258,15 @@ async def _get_token(self, client: AsyncCloudClient, timeout: float) -> str:
213258
214259
215260class YandexCloudCLIAuth (RefresheableIAMTokenAuth ):
261+ """
262+ Authentication class for Yandex Cloud CLI using IAM tokens.
263+
264+ It handles the initialization and retrieval of IAM tokens
265+ via the Yandex Cloud CLI that should be installed and configured.
266+
267+ Yandex Cloud CLI is a downloadable software for managing cloud resources via the command line.
268+ Read more in `the CLI documentation <https://yandex.cloud/docs/cli/>_`.
269+ """
216270 env_var = 'YC_PROFILE'
217271
218272 def __init__ (self , token : str | None = None , endpoint : str | None = None , yc_profile : str | None = None ):
@@ -250,6 +304,7 @@ async def _check_output(cls, command: list[str]) -> str | None:
250304
251305 @classmethod
252306 async def applicable_from_env (cls , yc_profile : str | None = None , endpoint : str | None = None , ** _ : Any ) -> Self | None :
307+ """:meta private:"""
253308 if yc_profile is None :
254309 yc_profile = os .getenv (cls .env_var )
255310
@@ -289,17 +344,30 @@ async def _get_token(self, client: AsyncCloudClient, timeout: float) -> str:
289344
290345
291346class MetadataAuth (RefresheableIAMTokenAuth ):
347+ """
348+ Authentication class for retrieving IAM tokens from metadata service.
349+
350+ This class retrieves IAM tokens from the Google Cloud metadata service.
351+ Read more in `the VM metadata documentation <https://yandex.cloud/docs/compute/concepts/vm-metadata>_`.
352+ """
292353 env_var = 'YC_METADATA_ADDR'
293354 _headers = {'Metadata-Flavor' : 'Google' }
294355 _default_addr = '169.254.169.254'
295356
296357 def __init__ (self , token : str | None = None , metadata_url : str | None = None ):
358+ """
359+ Initialize the MetadataAuth instance.
360+
361+ :param token: the initial IAM token.
362+ :param metadata_url: URL for the metadata service.
363+ """
297364 self ._metadata_url : str = metadata_url or self ._default_addr
298365 super ().__init__ (token )
299366
300367 @override
301368 @classmethod
302369 async def applicable_from_env (cls , ** _ : Any ) -> Self | None :
370+ """:meta private:"""
303371 addr = os .getenv (cls .env_var , cls ._default_addr )
304372 url = f'http://{ addr } /computeMetadata/v1/instance/service-accounts/default/token'
305373 # In case we found env var, we 99% would use this Auth, so timeout became
@@ -337,6 +405,22 @@ async def get_auth_provider(
337405 endpoint : str ,
338406 yc_profile : str | None ,
339407) -> BaseAuth :
408+ """
409+ Retrieve an appropriate authentication provider based on the provided auth parameter.
410+
411+ It determines the type of authentication to use based on the input and at environment
412+ and returns an instance of a corresponding authentication class.
413+ If nothing was clearly transmitted, then you need to look at the environment in the following order:
414+
415+ - If auth is a string, it can be an IAM token, OAuth token, or API key.
416+ - If an instance of BaseAuth, it will be used directly.
417+ - If auth is not provided or is invalid, the function will attempt to find an applicable
418+ authentication provider from environment variables.
419+
420+ :param auth: a parameter which represents the authentication token, an instance of BaseAuth, or None.
421+ :param endpoint: the endpoint for the Yandex Cloud service.
422+ :param yc_profile: a Yandex Cloud profile name.
423+ """
340424 simple_iam_regexp = re .compile (r'^t\d\.' )
341425 iam_regexp = re .compile (r't1\.[A-Z0-9a-z_-]+[=]{0,2}\.[A-Z0-9a-z_-]{86}[=]{0,2}' )
342426 simple_oauth_regexp = re .compile (r'y[0123]_[-\w]' )
0 commit comments