py2docfx 0.1.19rc2173760__py3-none-any.whl → 0.1.20__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. py2docfx/__main__.py +2 -2
  2. py2docfx/convert_prepare/arg_parser.py +1 -1
  3. py2docfx/convert_prepare/get_source.py +40 -8
  4. py2docfx/convert_prepare/git.py +1 -1
  5. py2docfx/docfx_yaml/logger.py +23 -19
  6. py2docfx/venv/basevenv/Lib/site-packages/certifi/__init__.py +1 -1
  7. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/authorization_code.py +1 -1
  8. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/broker.py +79 -0
  9. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/chained.py +8 -2
  10. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/default.py +145 -54
  11. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/imds.py +25 -1
  12. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/vscode.py +163 -144
  13. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/workload_identity.py +23 -12
  14. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/__init__.py +2 -0
  15. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/pipeline.py +4 -2
  16. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/utils.py +85 -0
  17. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_version.py +1 -1
  18. py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_credentials/authorization_code.py +1 -1
  19. py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_credentials/default.py +112 -56
  20. py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_credentials/imds.py +27 -1
  21. py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_credentials/on_behalf_of.py +1 -1
  22. py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_credentials/vscode.py +15 -67
  23. py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_credentials/workload_identity.py +17 -13
  24. py2docfx/venv/venv1/Lib/site-packages/certifi/__init__.py +1 -1
  25. py2docfx/venv/venv1/Lib/site-packages/cryptography/__about__.py +1 -1
  26. py2docfx/venv/venv1/Lib/site-packages/msal/__main__.py +2 -0
  27. py2docfx/venv/venv1/Lib/site-packages/msal/application.py +63 -21
  28. py2docfx/venv/venv1/Lib/site-packages/msal/broker.py +5 -2
  29. py2docfx/venv/venv1/Lib/site-packages/msal/exceptions.py +19 -5
  30. py2docfx/venv/venv1/Lib/site-packages/msal/managed_identity.py +50 -10
  31. py2docfx/venv/venv1/Lib/site-packages/msal/sku.py +1 -1
  32. py2docfx/venv/venv1/Lib/site-packages/msal/throttled_http_client.py +4 -1
  33. {py2docfx-0.1.19rc2173760.dist-info → py2docfx-0.1.20.dist-info}/METADATA +1 -1
  34. {py2docfx-0.1.19rc2173760.dist-info → py2docfx-0.1.20.dist-info}/RECORD +36 -38
  35. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/linux_vscode_adapter.py +0 -100
  36. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/macos_vscode_adapter.py +0 -34
  37. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/win_vscode_adapter.py +0 -77
  38. {py2docfx-0.1.19rc2173760.dist-info → py2docfx-0.1.20.dist-info}/WHEEL +0 -0
  39. {py2docfx-0.1.19rc2173760.dist-info → py2docfx-0.1.20.dist-info}/top_level.txt +0 -0
@@ -8,8 +8,9 @@ from typing import List, Optional, Any, cast
8
8
 
9
9
  from azure.core.credentials import AccessToken, AccessTokenInfo, TokenRequestOptions
10
10
  from azure.core.credentials_async import AsyncTokenCredential, AsyncSupportsTokenInfo
11
+ from ... import CredentialUnavailableError
11
12
  from ..._constants import EnvironmentVariables
12
- from ..._internal import get_default_authority, normalize_authority, within_dac
13
+ from ..._internal import get_default_authority, normalize_authority, within_dac, process_credential_exclusions
13
14
  from .azure_cli import AzureCliCredential
14
15
  from .azd_cli import AzureDeveloperCliCredential
15
16
  from .azure_powershell import AzurePowerShellCredential
@@ -24,6 +25,34 @@ from .workload_identity import WorkloadIdentityCredential
24
25
  _LOGGER = logging.getLogger(__name__)
25
26
 
26
27
 
28
+ class AsyncFailedDACCredential:
29
+ """Async version of FailedDACCredential for use in async credential chains.
30
+
31
+ This acts as a substitute for an async credential that has failed to initialize in the DAC chain.
32
+ """
33
+
34
+ def __init__(self, credential_name: str, error: str) -> None:
35
+ self._error = error
36
+ self._credential_name = credential_name
37
+
38
+ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken:
39
+ raise CredentialUnavailableError(self._error)
40
+
41
+ async def get_token_info(
42
+ self, *scopes, options: Optional[TokenRequestOptions] = None, **kwargs: Any
43
+ ) -> AccessTokenInfo:
44
+ raise CredentialUnavailableError(self._error)
45
+
46
+ async def __aexit__(self, *args: Any, **kwargs: Any) -> None:
47
+ pass
48
+
49
+ async def __aenter__(self) -> "AsyncFailedDACCredential":
50
+ return self
51
+
52
+ async def close(self) -> None:
53
+ pass
54
+
55
+
27
56
  class DefaultAzureCredential(ChainedTokenCredential):
28
57
  """A credential capable of handling most Azure SDK authentication scenarios. See
29
58
  https://aka.ms/azsdk/python/identity/credential-chains#usage-guidance-for-defaultazurecredential.
@@ -73,9 +102,8 @@ class DefaultAzureCredential(ChainedTokenCredential):
73
102
  :keyword str shared_cache_tenant_id: Preferred tenant for :class:`~azure.identity.aio.SharedTokenCacheCredential`.
74
103
  Defaults to the value of environment variable AZURE_TENANT_ID, if any.
75
104
  :keyword str visual_studio_code_tenant_id: Tenant ID to use when authenticating with
76
- :class:`~azure.identity.aio.VisualStudioCodeCredential`. Defaults to the "Azure: Tenant" setting in VS Code's
77
- user settings or, when that setting has no value, the "organizations" tenant, which supports only Azure Active
78
- Directory work or school accounts.
105
+ :class:`~azure.identity.VisualStudioCodeCredential`. Defaults to the tenant specified in the authentication
106
+ record file used by the Azure Resources extension.
79
107
  :keyword int process_timeout: The timeout in seconds to use for developer credentials that run
80
108
  subprocesses (e.g. AzureCliCredential, AzurePowerShellCredential). Defaults to **10** seconds.
81
109
 
@@ -89,23 +117,15 @@ class DefaultAzureCredential(ChainedTokenCredential):
89
117
  :caption: Create a DefaultAzureCredential.
90
118
  """
91
119
 
92
- def __init__(self, **kwargs: Any) -> None: # pylint: disable=too-many-statements
120
+ def __init__(self, **kwargs: Any) -> None: # pylint: disable=too-many-statements, too-many-locals
93
121
  if "tenant_id" in kwargs:
94
122
  raise TypeError("'tenant_id' is not supported in DefaultAzureCredential.")
95
123
 
96
124
  authority = kwargs.pop("authority", None)
97
-
98
- vscode_tenant_id = kwargs.pop(
99
- "visual_studio_code_tenant_id", os.environ.get(EnvironmentVariables.AZURE_TENANT_ID)
100
- )
101
- vscode_args = dict(kwargs)
102
- if authority:
103
- vscode_args["authority"] = authority
104
- if vscode_tenant_id:
105
- vscode_args["tenant_id"] = vscode_tenant_id
106
-
107
125
  authority = normalize_authority(authority) if authority else get_default_authority()
108
126
 
127
+ vscode_tenant_id = kwargs.pop("visual_studio_code_tenant_id", None)
128
+
109
129
  shared_cache_username = kwargs.pop("shared_cache_username", os.environ.get(EnvironmentVariables.AZURE_USERNAME))
110
130
  shared_cache_tenant_id = kwargs.pop(
111
131
  "shared_cache_tenant_id", os.environ.get(EnvironmentVariables.AZURE_TENANT_ID)
@@ -119,56 +139,88 @@ class DefaultAzureCredential(ChainedTokenCredential):
119
139
  "workload_identity_tenant_id", os.environ.get(EnvironmentVariables.AZURE_TENANT_ID)
120
140
  )
121
141
 
122
- vscode_tenant_id = kwargs.pop(
123
- "visual_studio_code_tenant_id", os.environ.get(EnvironmentVariables.AZURE_TENANT_ID)
124
- )
125
-
126
142
  process_timeout = kwargs.pop("process_timeout", 10)
127
143
 
128
- token_credentials_env = os.environ.get(EnvironmentVariables.AZURE_TOKEN_CREDENTIALS, "").strip().lower()
129
- exclude_workload_identity_credential = kwargs.pop("exclude_workload_identity_credential", False)
130
- exclude_visual_studio_code_credential = kwargs.pop("exclude_visual_studio_code_credential", True)
131
- exclude_developer_cli_credential = kwargs.pop("exclude_developer_cli_credential", False)
132
- exclude_cli_credential = kwargs.pop("exclude_cli_credential", False)
133
- exclude_environment_credential = kwargs.pop("exclude_environment_credential", False)
134
- exclude_managed_identity_credential = kwargs.pop("exclude_managed_identity_credential", False)
135
- exclude_shared_token_cache_credential = kwargs.pop("exclude_shared_token_cache_credential", False)
136
- exclude_powershell_credential = kwargs.pop("exclude_powershell_credential", False)
137
-
138
- if token_credentials_env == "dev":
139
- # In dev mode, use only developer credentials
140
- exclude_environment_credential = True
141
- exclude_managed_identity_credential = True
142
- exclude_workload_identity_credential = True
143
- elif token_credentials_env == "prod":
144
- # In prod mode, use only production credentials
145
- exclude_shared_token_cache_credential = True
146
- exclude_visual_studio_code_credential = True
147
- exclude_cli_credential = True
148
- exclude_developer_cli_credential = True
149
- exclude_powershell_credential = True
150
- elif token_credentials_env != "":
151
- # If the environment variable is set to something other than dev or prod, raise an error
152
- raise ValueError(
153
- f"Invalid value for {EnvironmentVariables.AZURE_TOKEN_CREDENTIALS}: {token_credentials_env}. "
154
- "Valid values are 'dev' or 'prod'."
155
- )
144
+ # Define credential configuration mapping (async version)
145
+ credential_config = {
146
+ "environment": {
147
+ "exclude_param": "exclude_environment_credential",
148
+ "env_name": "environmentcredential",
149
+ "default_exclude": False,
150
+ },
151
+ "workload_identity": {
152
+ "exclude_param": "exclude_workload_identity_credential",
153
+ "env_name": "workloadidentitycredential",
154
+ "default_exclude": False,
155
+ },
156
+ "managed_identity": {
157
+ "exclude_param": "exclude_managed_identity_credential",
158
+ "env_name": "managedidentitycredential",
159
+ "default_exclude": False,
160
+ },
161
+ "shared_token_cache": {
162
+ "exclude_param": "exclude_shared_token_cache_credential",
163
+ "default_exclude": False,
164
+ },
165
+ "visual_studio_code": {
166
+ "exclude_param": "exclude_visual_studio_code_credential",
167
+ "env_name": "visualstudiocodecredential",
168
+ "default_exclude": False,
169
+ },
170
+ "cli": {
171
+ "exclude_param": "exclude_cli_credential",
172
+ "env_name": "azureclicredential",
173
+ "default_exclude": False,
174
+ },
175
+ "developer_cli": {
176
+ "exclude_param": "exclude_developer_cli_credential",
177
+ "env_name": "azuredeveloperclicredential",
178
+ "default_exclude": False,
179
+ },
180
+ "powershell": {
181
+ "exclude_param": "exclude_powershell_credential",
182
+ "env_name": "azurepowershellcredential",
183
+ "default_exclude": False,
184
+ },
185
+ }
186
+
187
+ # Extract user-provided exclude flags and set defaults
188
+ exclude_flags = {}
189
+ user_excludes = {}
190
+ for cred_key, config in credential_config.items():
191
+ param_name = cast(str, config["exclude_param"])
192
+ user_excludes[cred_key] = kwargs.pop(param_name, None)
193
+ exclude_flags[cred_key] = config["default_exclude"]
194
+
195
+ # Process AZURE_TOKEN_CREDENTIALS environment variable and apply user overrides
196
+ exclude_flags = process_credential_exclusions(credential_config, exclude_flags, user_excludes)
197
+
198
+ # Extract individual exclude flags for backward compatibility
199
+ exclude_environment_credential = exclude_flags["environment"]
200
+ exclude_workload_identity_credential = exclude_flags["workload_identity"]
201
+ exclude_managed_identity_credential = exclude_flags["managed_identity"]
202
+ exclude_shared_token_cache_credential = exclude_flags["shared_token_cache"]
203
+ exclude_visual_studio_code_credential = exclude_flags["visual_studio_code"]
204
+ exclude_cli_credential = exclude_flags["cli"]
205
+ exclude_developer_cli_credential = exclude_flags["developer_cli"]
206
+ exclude_powershell_credential = exclude_flags["powershell"]
156
207
 
157
208
  credentials: List[AsyncSupportsTokenInfo] = []
158
209
  within_dac.set(True)
159
210
  if not exclude_environment_credential:
160
211
  credentials.append(EnvironmentCredential(authority=authority, _within_dac=True, **kwargs))
161
212
  if not exclude_workload_identity_credential:
162
- if all(os.environ.get(var) for var in EnvironmentVariables.WORKLOAD_IDENTITY_VARS):
163
- client_id = workload_identity_client_id
213
+ try:
164
214
  credentials.append(
165
215
  WorkloadIdentityCredential(
166
- client_id=cast(str, client_id),
216
+ client_id=cast(str, workload_identity_client_id),
167
217
  tenant_id=workload_identity_tenant_id,
168
- token_file_path=os.environ[EnvironmentVariables.AZURE_FEDERATED_TOKEN_FILE],
218
+ token_file_path=os.environ.get(EnvironmentVariables.AZURE_FEDERATED_TOKEN_FILE),
169
219
  **kwargs,
170
220
  )
171
221
  )
222
+ except ValueError as ex:
223
+ credentials.append(AsyncFailedDACCredential("WorkloadIdentityCredential", error=str(ex)))
172
224
  if not exclude_managed_identity_credential:
173
225
  credentials.append(
174
226
  ManagedIdentityCredential(
@@ -187,7 +239,7 @@ class DefaultAzureCredential(ChainedTokenCredential):
187
239
  except Exception as ex: # pylint:disable=broad-except
188
240
  _LOGGER.info("Shared token cache is unavailable: '%s'", ex)
189
241
  if not exclude_visual_studio_code_credential:
190
- credentials.append(VisualStudioCodeCredential(**vscode_args))
242
+ credentials.append(VisualStudioCodeCredential(tenant_id=vscode_tenant_id))
191
243
  if not exclude_cli_credential:
192
244
  credentials.append(AzureCliCredential(process_timeout=process_timeout))
193
245
  if not exclude_powershell_credential:
@@ -226,8 +278,10 @@ class DefaultAzureCredential(ChainedTokenCredential):
226
278
  return token
227
279
 
228
280
  within_dac.set(True)
229
- token = await super().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs)
230
- within_dac.set(False)
281
+ try:
282
+ token = await super().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs)
283
+ finally:
284
+ within_dac.set(False)
231
285
  return token
232
286
 
233
287
  async def get_token_info(self, *scopes: str, options: Optional[TokenRequestOptions] = None) -> AccessTokenInfo:
@@ -257,6 +311,8 @@ class DefaultAzureCredential(ChainedTokenCredential):
257
311
  return token_info
258
312
 
259
313
  within_dac.set(True)
260
- token_info = await cast(AsyncSupportsTokenInfo, super()).get_token_info(*scopes, options=options)
261
- within_dac.set(False)
314
+ try:
315
+ token_info = await cast(AsyncSupportsTokenInfo, super()).get_token_info(*scopes, options=options)
316
+ finally:
317
+ within_dac.set(False)
262
318
  return token_info
@@ -3,10 +3,13 @@
3
3
  # Licensed under the MIT License.
4
4
  # ------------------------------------
5
5
  import os
6
- from typing import Optional, Any
6
+ from typing import Optional, Any, Dict
7
7
 
8
8
  from azure.core.exceptions import ClientAuthenticationError, HttpResponseError
9
9
  from azure.core.credentials import AccessTokenInfo
10
+ from azure.core.pipeline.policies import AsyncRetryPolicy
11
+ from azure.core.pipeline import PipelineResponse
12
+
10
13
  from ... import CredentialUnavailableError
11
14
  from ..._constants import EnvironmentVariables
12
15
  from .._internal import AsyncContextManager
@@ -16,10 +19,33 @@ from ..._internal import within_credential_chain
16
19
  from ..._credentials.imds import _get_request, _check_forbidden_response, PIPELINE_SETTINGS
17
20
 
18
21
 
22
+ class AsyncImdsRetryPolicy(AsyncRetryPolicy):
23
+ """Async custom retry policy for IMDS credential with extended retry duration for 410 responses.
24
+
25
+ This policy ensures that specifically for 410 status codes, the total exponential backoff duration
26
+ is at least 70 seconds to handle temporary IMDS endpoint unavailability.
27
+ For other status codes, it uses the standard retry behavior.
28
+ """
29
+
30
+ def __init__(self, **kwargs: Any) -> None:
31
+ # Increased backoff factor to ensure at least 70 seconds retry duration for 410 responses.
32
+ # Five retries, with each retry sleeping for [0.0s, 5.0s, 10.0s, 20.0s, 40.0s] between attempts (75s total)
33
+ self.backoff_factor_for_410 = 2.5
34
+ super().__init__(**kwargs)
35
+
36
+ def is_retry(self, settings: Dict[str, Any], response: PipelineResponse[Any, Any]) -> bool:
37
+ if response.http_response.status_code == 410:
38
+ settings["backoff"] = self.backoff_factor_for_410
39
+ else:
40
+ settings["backoff"] = self.backoff_factor
41
+ return super().is_retry(settings, response)
42
+
43
+
19
44
  class ImdsCredential(AsyncContextManager, GetTokenMixin):
20
45
  def __init__(self, **kwargs: Any) -> None:
21
46
  super().__init__()
22
47
 
48
+ kwargs["retry_policy_class"] = AsyncImdsRetryPolicy
23
49
  self._client = AsyncManagedIdentityClient(_get_request, **dict(PIPELINE_SETTINGS, **kwargs))
24
50
  if EnvironmentVariables.AZURE_POD_IDENTITY_AUTHORITY_HOST in os.environ:
25
51
  self._endpoint_available: Optional[bool] = True
@@ -119,7 +119,7 @@ class OnBehalfOfCredential(AsyncContextManager, GetTokenMixin):
119
119
  # Note we assume the cache has tokens for one user only. That's okay because each instance of this class is
120
120
  # locked to a single user (assertion). This assumption will become unsafe if this class allows applications
121
121
  # to change an instance's assertion.
122
- refresh_tokens = self._client.get_cached_refresh_tokens(scopes)
122
+ refresh_tokens = self._client.get_cached_refresh_tokens(scopes, **kwargs)
123
123
  if len(refresh_tokens) == 1: # there should be only one
124
124
  try:
125
125
  refresh_token = refresh_tokens[0]["secret"]
@@ -2,49 +2,37 @@
2
2
  # Copyright (c) Microsoft Corporation.
3
3
  # Licensed under the MIT License.
4
4
  # ------------------------------------
5
- from typing import cast, Optional, Any
5
+ from typing import Optional, Any
6
6
 
7
7
  from azure.core.credentials import AccessToken, AccessTokenInfo, TokenRequestOptions
8
- from azure.core.exceptions import ClientAuthenticationError
9
- from ..._exceptions import CredentialUnavailableError
10
8
  from .._internal import AsyncContextManager
11
- from .._internal.aad_client import AadClient
12
- from .._internal.get_token_mixin import GetTokenMixin
13
9
  from .._internal.decorators import log_get_token_async
14
- from ..._credentials.vscode import _VSCodeCredentialBase
15
- from ..._internal import within_dac
10
+ from ..._credentials.vscode import VisualStudioCodeCredential as SyncVSCodeCredential
16
11
 
17
12
 
18
- class VisualStudioCodeCredential(_VSCodeCredentialBase, AsyncContextManager, GetTokenMixin):
19
- """Authenticates as the Azure user signed in to Visual Studio Code via the 'Azure Account' extension.
13
+ class VisualStudioCodeCredential(AsyncContextManager):
14
+ """Authenticates as the Azure user signed in to Visual Studio Code via the 'Azure Resources' extension.
20
15
 
21
- **Deprecated**: This credential is deprecated because the Azure Account extension for Visual Studio Code, which
22
- this credential relies on, has been deprecated. See the Azure Account extension deprecation notice here:
23
- https://github.com/microsoft/vscode-azure-account/issues/964. Consider using other developer credentials such as
24
- AzureCliCredential, AzureDeveloperCliCredential, or AzurePowerShellCredential.
16
+ This currently only works in Windows/WSL environments and requires the 'azure-identity-broker'
17
+ package to be installed.
25
18
 
26
- :keyword str authority: Authority of a Microsoft Entra endpoint, for example "login.microsoftonline.com".
27
- This argument is required for a custom cloud and usually unnecessary otherwise. Defaults to the authority
28
- matching the "Azure: Cloud" setting in VS Code's user settings or, when that setting has no value, the
29
- authority for Azure Public Cloud.
30
- :keyword str tenant_id: ID of the tenant the credential should authenticate in. Defaults to the "Azure: Tenant"
31
- setting in VS Code's user settings or, when that setting has no value, the "organizations" tenant, which
32
- supports only Microsoft Entra work or school accounts.
19
+ :keyword str tenant_id: A Microsoft Entra tenant ID. Defaults to the tenant specified in the authentication
20
+ record file used by the Azure Resources extension.
33
21
  :keyword List[str] additionally_allowed_tenants: Specifies tenants in addition to the specified "tenant_id"
34
22
  for which the credential may acquire tokens. Add the wildcard value "*" to allow the credential to
35
23
  acquire tokens for any tenant the application can access.
36
24
  """
37
25
 
26
+ def __init__(self, **kwargs: Any) -> None:
27
+ self._sync_credential = SyncVSCodeCredential(**kwargs)
28
+
38
29
  async def __aenter__(self) -> "VisualStudioCodeCredential":
39
- if self._client:
40
- await self._client.__aenter__()
30
+ self._sync_credential.__enter__()
41
31
  return self
42
32
 
43
33
  async def close(self) -> None:
44
34
  """Close the credential's transport session."""
45
-
46
- if self._client:
47
- await self._client.__aexit__()
35
+ self._sync_credential.close()
48
36
 
49
37
  @log_get_token_async
50
38
  async def get_token(
@@ -66,22 +54,7 @@ class VisualStudioCodeCredential(_VSCodeCredentialBase, AsyncContextManager, Get
66
54
  :raises ~azure.identity.CredentialUnavailableError: the credential cannot retrieve user details from Visual
67
55
  Studio Code
68
56
  """
69
- if self._unavailable_reason:
70
- error_message = (
71
- self._unavailable_reason + "\n"
72
- "Visit https://aka.ms/azsdk/python/identity/vscodecredential/troubleshoot"
73
- " to troubleshoot this issue."
74
- )
75
- raise CredentialUnavailableError(message=error_message)
76
- if not self._client:
77
- raise CredentialUnavailableError("Initialization failed")
78
- if within_dac.get():
79
- try:
80
- token = await super().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs)
81
- return token
82
- except ClientAuthenticationError as ex:
83
- raise CredentialUnavailableError(message=ex.message) from ex
84
- return await super().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs)
57
+ return self._sync_credential.get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs)
85
58
 
86
59
  async def get_token_info(self, *scopes: str, options: Optional[TokenRequestOptions] = None) -> AccessTokenInfo:
87
60
  """Request an access token for `scopes` as the user currently signed in to Visual Studio Code.
@@ -99,29 +72,4 @@ class VisualStudioCodeCredential(_VSCodeCredentialBase, AsyncContextManager, Get
99
72
  :raises ~azure.identity.CredentialUnavailableError: the credential cannot retrieve user details from Visual
100
73
  Studio Code.
101
74
  """
102
- if self._unavailable_reason:
103
- error_message = (
104
- self._unavailable_reason + "\n"
105
- "Visit https://aka.ms/azsdk/python/identity/vscodecredential/troubleshoot"
106
- " to troubleshoot this issue."
107
- )
108
- raise CredentialUnavailableError(message=error_message)
109
- if within_dac.get():
110
- try:
111
- token = await super().get_token_info(*scopes, options=options)
112
- return token
113
- except ClientAuthenticationError as ex:
114
- raise CredentialUnavailableError(message=ex.message) from ex
115
- return await super().get_token_info(*scopes, options=options)
116
-
117
- async def _acquire_token_silently(self, *scopes: str, **kwargs: Any) -> Optional[AccessTokenInfo]:
118
- self._client = cast(AadClient, self._client)
119
- return self._client.get_cached_access_token(scopes, **kwargs)
120
-
121
- async def _request_token(self, *scopes: str, **kwargs: Any) -> AccessTokenInfo:
122
- refresh_token = self._get_refresh_token()
123
- self._client = cast(AadClient, self._client)
124
- return await self._client.obtain_token_by_refresh_token(scopes, refresh_token, **kwargs)
125
-
126
- def _get_client(self, **kwargs: Any) -> AadClient:
127
- return AadClient(**kwargs)
75
+ return self._sync_credential.get_token_info(*scopes, options=options)
@@ -5,7 +5,7 @@
5
5
  import os
6
6
  from typing import Any, Optional
7
7
  from .client_assertion import ClientAssertionCredential
8
- from ..._credentials.workload_identity import TokenFileMixin
8
+ from ..._credentials.workload_identity import TokenFileMixin, WORKLOAD_CONFIG_ERROR
9
9
  from ..._constants import EnvironmentVariables
10
10
 
11
11
 
@@ -52,21 +52,25 @@ class WorkloadIdentityCredential(ClientAssertionCredential, TokenFileMixin):
52
52
  tenant_id = tenant_id or os.environ.get(EnvironmentVariables.AZURE_TENANT_ID)
53
53
  client_id = client_id or os.environ.get(EnvironmentVariables.AZURE_CLIENT_ID)
54
54
  token_file_path = token_file_path or os.environ.get(EnvironmentVariables.AZURE_FEDERATED_TOKEN_FILE)
55
+
56
+ missing_args = []
55
57
  if not tenant_id:
56
- raise ValueError(
57
- "'tenant_id' is required. Please pass it in or set the "
58
- f"{EnvironmentVariables.AZURE_TENANT_ID} environment variable"
59
- )
58
+ missing_args.append("'tenant_id'")
60
59
  if not client_id:
61
- raise ValueError(
62
- "'client_id' is required. Please pass it in or set the "
63
- f"{EnvironmentVariables.AZURE_CLIENT_ID} environment variable"
64
- )
60
+ missing_args.append("'client_id'")
65
61
  if not token_file_path:
66
- raise ValueError(
67
- "'token_file_path' is required. Please pass it in or set the "
68
- f"{EnvironmentVariables.AZURE_FEDERATED_TOKEN_FILE} environment variable"
69
- )
62
+ missing_args.append("'token_file_path'")
63
+
64
+ if missing_args:
65
+ missing_args_str = ", ".join(missing_args)
66
+ error_message = f"{WORKLOAD_CONFIG_ERROR}. Missing required arguments: {missing_args_str}."
67
+ raise ValueError(error_message)
68
+
69
+ # Type assertions since we've validated these are not None
70
+ assert tenant_id is not None
71
+ assert client_id is not None
72
+ assert token_file_path is not None
73
+
70
74
  self._token_file_path = token_file_path
71
75
  super().__init__(
72
76
  tenant_id=tenant_id,
@@ -1,4 +1,4 @@
1
1
  from .core import contents, where
2
2
 
3
3
  __all__ = ["contents", "where"]
4
- __version__ = "2025.07.14"
4
+ __version__ = "2025.08.03"
@@ -10,7 +10,7 @@ __all__ = [
10
10
  "__version__",
11
11
  ]
12
12
 
13
- __version__ = "45.0.5"
13
+ __version__ = "45.0.6"
14
14
 
15
15
 
16
16
  __author__ = "The Python Cryptographic Authority and individual contributors"
@@ -300,6 +300,8 @@ def _main():
300
300
  instance_discovery=instance_discovery,
301
301
  enable_broker_on_windows=enable_broker,
302
302
  enable_broker_on_mac=enable_broker,
303
+ enable_broker_on_linux=enable_broker,
304
+ enable_broker_on_wsl=enable_broker,
303
305
  enable_pii_log=enable_pii_log,
304
306
  token_cache=global_cache,
305
307
  ) if not is_cca else msal.ConfidentialClientApplication(