Skip to content

Commit 85a7b10

Browse files
authored
Add docstrings for _auth.py (#108)
1 parent 2e0c8ff commit 85a7b10

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed

src/yandex_cloud_ml_sdk/_auth.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,35 +36,49 @@
3636

3737

3838
class 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

5664
class 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

6777
class 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

91107
class 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

100122
class 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

150179
class 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

181217
class 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

215260
class 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

291346
class 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

Comments
 (0)