azure-quantum 0.29.2__py3-none-any.whl → 1.0.0__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.
- azure/quantum/_client/_version.py +1 -1
- azure/quantum/cirq/service.py +7 -0
- azure/quantum/cirq/targets/quantinuum.py +1 -1
- azure/quantum/job/__init__.py +1 -0
- azure/quantum/job/base_job.py +41 -15
- azure/quantum/job/job.py +35 -1
- azure/quantum/job/job_failed_with_results_error.py +41 -0
- azure/quantum/qiskit/backends/backend.py +130 -35
- azure/quantum/qiskit/backends/ionq.py +65 -5
- azure/quantum/qiskit/backends/qci.py +35 -2
- azure/quantum/qiskit/backends/quantinuum.py +25 -4
- azure/quantum/qiskit/backends/rigetti.py +8 -1
- azure/quantum/qiskit/job.py +7 -16
- azure/quantum/qiskit/provider.py +18 -2
- azure/quantum/storage.py +2 -1
- azure/quantum/target/__init__.py +1 -0
- azure/quantum/target/ionq.py +37 -12
- azure/quantum/target/microsoft/elements/dft/__init__.py +4 -0
- azure/quantum/target/microsoft/elements/dft/job.py +46 -0
- azure/quantum/target/microsoft/elements/dft/target.py +66 -0
- azure/quantum/target/microsoft/target.py +36 -9
- azure/quantum/target/params.py +1 -1
- azure/quantum/target/pasqal/target.py +16 -2
- azure/quantum/target/quantinuum.py +34 -9
- azure/quantum/target/rigetti/target.py +21 -3
- azure/quantum/target/solvers.py +7 -1
- azure/quantum/target/target.py +82 -0
- azure/quantum/target/target_factory.py +0 -2
- azure/quantum/version.py +1 -1
- azure/quantum/workspace.py +11 -8
- {azure_quantum-0.29.2.dist-info → azure_quantum-1.0.0.dist-info}/METADATA +3 -5
- azure_quantum-1.0.0.dist-info/RECORD +86 -0
- azure/quantum/_client/aio/__init__.py +0 -23
- azure/quantum/_client/aio/_client.py +0 -124
- azure/quantum/_client/aio/_configuration.py +0 -89
- azure/quantum/_client/aio/_patch.py +0 -20
- azure/quantum/_client/aio/operations/__init__.py +0 -29
- azure/quantum/_client/aio/operations/_operations.py +0 -1291
- azure/quantum/_client/aio/operations/_patch.py +0 -20
- azure/quantum/aio/__init__.py +0 -14
- azure/quantum/aio/_authentication/__init__.py +0 -9
- azure/quantum/aio/_authentication/_chained.py +0 -94
- azure/quantum/aio/_authentication/_default.py +0 -212
- azure/quantum/aio/_authentication/_token.py +0 -81
- azure/quantum/aio/job/__init__.py +0 -1
- azure/quantum/aio/job/base_job.py +0 -326
- azure/quantum/aio/job/job.py +0 -104
- azure/quantum/aio/optimization/__init__.py +0 -11
- azure/quantum/aio/optimization/online_problem.py +0 -17
- azure/quantum/aio/optimization/problem.py +0 -102
- azure/quantum/aio/optimization/streaming_problem.py +0 -280
- azure/quantum/aio/storage.py +0 -390
- azure/quantum/aio/target/__init__.py +0 -19
- azure/quantum/aio/target/ionq.py +0 -47
- azure/quantum/aio/target/quantinuum.py +0 -47
- azure/quantum/aio/target/solvers.py +0 -96
- azure/quantum/aio/target/target.py +0 -68
- azure/quantum/aio/target/target_factory.py +0 -72
- azure/quantum/aio/target/toshiba.py +0 -6
- azure/quantum/aio/workspace.py +0 -337
- azure_quantum-0.29.2.dist-info/RECORD +0 -110
- {azure_quantum-0.29.2.dist-info → azure_quantum-1.0.0.dist-info}/WHEEL +0 -0
- {azure_quantum-0.29.2.dist-info → azure_quantum-1.0.0.dist-info}/top_level.txt +0 -0
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# ------------------------------------
|
|
2
|
-
# Copyright (c) Microsoft Corporation.
|
|
3
|
-
# Licensed under the MIT License.
|
|
4
|
-
# ------------------------------------
|
|
5
|
-
"""Customize generated code here.
|
|
6
|
-
|
|
7
|
-
Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize
|
|
8
|
-
"""
|
|
9
|
-
from typing import List
|
|
10
|
-
|
|
11
|
-
__all__: List[str] = [] # Add all objects you want publicly available to users at this package level
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def patch_sdk():
|
|
15
|
-
"""Do not remove from this file.
|
|
16
|
-
|
|
17
|
-
`patch_sdk` is a last resort escape hatch that allows you to do customizations
|
|
18
|
-
you can't accomplish using the techniques described in
|
|
19
|
-
https://aka.ms/azsdk/python/dpcodegen/python/customize
|
|
20
|
-
"""
|
azure/quantum/aio/__init__.py
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
##
|
|
2
|
-
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
# Licensed under the MIT License.
|
|
4
|
-
##
|
|
5
|
-
import logging
|
|
6
|
-
from azure.quantum.version import __version__
|
|
7
|
-
|
|
8
|
-
from .job.job import *
|
|
9
|
-
from .workspace import *
|
|
10
|
-
|
|
11
|
-
from azure.quantum._client.models._enums import JobStatus
|
|
12
|
-
|
|
13
|
-
logger = logging.getLogger(__name__)
|
|
14
|
-
logger.info(f"version: {__version__}")
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
# ------------------------------------
|
|
2
|
-
# Copyright (c) Microsoft Corporation.
|
|
3
|
-
# Licensed under the MIT License.
|
|
4
|
-
# ------------------------------------
|
|
5
|
-
import logging
|
|
6
|
-
from azure.core.exceptions import ClientAuthenticationError
|
|
7
|
-
from azure.identity import CredentialUnavailableError
|
|
8
|
-
from azure.identity import InteractiveBrowserCredential, DeviceCodeCredential
|
|
9
|
-
|
|
10
|
-
from azure.quantum._authentication._chained import filter_credential_warnings, _get_error_message
|
|
11
|
-
|
|
12
|
-
try:
|
|
13
|
-
from typing import TYPE_CHECKING
|
|
14
|
-
except ImportError:
|
|
15
|
-
TYPE_CHECKING = False
|
|
16
|
-
|
|
17
|
-
if TYPE_CHECKING:
|
|
18
|
-
# pylint:disable=unused-import,ungrouped-imports
|
|
19
|
-
from typing import Any, Optional
|
|
20
|
-
from azure.core.credentials_async import AccessToken, AsyncTokenCredential
|
|
21
|
-
|
|
22
|
-
_LOGGER = logging.getLogger(__name__)
|
|
23
|
-
|
|
24
|
-
import logging
|
|
25
|
-
import sys
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class _ChainedTokenCredential(object):
|
|
29
|
-
"""
|
|
30
|
-
Based on Azure.Identity.ChainedTokenCredential from:
|
|
31
|
-
https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/identity/azure-identity/azure/identity/_credentials/chained.py
|
|
32
|
-
|
|
33
|
-
The key difference is that we don't stop attempting all credentials
|
|
34
|
-
if some of then failed or raised an exception.
|
|
35
|
-
We also don't log a warning unless all credential attempts have failed.
|
|
36
|
-
"""
|
|
37
|
-
|
|
38
|
-
def __init__(self, *credentials):
|
|
39
|
-
# type: (*AsyncTokenCredential) -> None
|
|
40
|
-
self._successful_credential = None # type: Optional[AsyncTokenCredential]
|
|
41
|
-
self.credentials = credentials
|
|
42
|
-
|
|
43
|
-
async def get_token(self, *scopes, **kwargs): # pylint:disable=unused-argument
|
|
44
|
-
# type: (*str, **Any) -> AccessToken
|
|
45
|
-
"""Request a token from each chained credential, in order, returning the first token received.
|
|
46
|
-
This method is called automatically by Azure SDK clients.
|
|
47
|
-
:param str scopes: desired scopes for the access token. This method requires at least one scope.
|
|
48
|
-
:raises ~azure.core.exceptions.ClientAuthenticationError: no credential in the chain provided a token
|
|
49
|
-
"""
|
|
50
|
-
history = []
|
|
51
|
-
|
|
52
|
-
# Suppress warnings from credentials in Azure.Identity
|
|
53
|
-
azure_identity_logger = logging.getLogger("azure.identity")
|
|
54
|
-
handler = logging.StreamHandler(stream=sys.stdout)
|
|
55
|
-
handler.addFilter(filter_credential_warnings)
|
|
56
|
-
azure_identity_logger.addHandler(handler)
|
|
57
|
-
try:
|
|
58
|
-
for credential in self.credentials:
|
|
59
|
-
try:
|
|
60
|
-
if isinstance(credential, (InteractiveBrowserCredential, DeviceCodeCredential)):
|
|
61
|
-
# InteractiveCredentials aren't async.
|
|
62
|
-
token = credential.get_token(*scopes, **kwargs)
|
|
63
|
-
else:
|
|
64
|
-
token = await credential.get_token(*scopes, **kwargs)
|
|
65
|
-
_LOGGER.info("%s acquired a token from %s", self.__class__.__name__, credential.__class__.__name__)
|
|
66
|
-
self._successful_credential = credential
|
|
67
|
-
return token
|
|
68
|
-
except CredentialUnavailableError as ex:
|
|
69
|
-
# credential didn't attempt authentication because it lacks required data or state -> continue
|
|
70
|
-
history.append((credential, ex.message))
|
|
71
|
-
_LOGGER.info("%s - %s is unavailable", self.__class__.__name__, credential.__class__.__name__)
|
|
72
|
-
except Exception as ex: # pylint: disable=broad-except
|
|
73
|
-
# credential failed to authenticate, or something unexpectedly raised -> break
|
|
74
|
-
history.append((credential, str(ex)))
|
|
75
|
-
# instead of logging a warning, we just want to log an info
|
|
76
|
-
# since other credentials might succeed
|
|
77
|
-
_LOGGER.info(
|
|
78
|
-
'%s.get_token failed: %s raised unexpected error "%s"',
|
|
79
|
-
self.__class__.__name__,
|
|
80
|
-
credential.__class__.__name__,
|
|
81
|
-
ex,
|
|
82
|
-
exc_info=_LOGGER.isEnabledFor(logging.DEBUG),
|
|
83
|
-
)
|
|
84
|
-
# here we do NOT want break and will continue to try other credentials
|
|
85
|
-
|
|
86
|
-
finally:
|
|
87
|
-
# Re-enable warnings from credentials in Azure.Identity
|
|
88
|
-
azure_identity_logger.removeHandler(handler)
|
|
89
|
-
|
|
90
|
-
# if all attempts failed, only then we log a warning and raise an error
|
|
91
|
-
attempts = _get_error_message(history)
|
|
92
|
-
message = self.__class__.__name__ + " failed to retrieve a token from the included credentials." + attempts
|
|
93
|
-
_LOGGER.warning(message)
|
|
94
|
-
raise ClientAuthenticationError(message=message)
|
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
# ------------------------------------
|
|
2
|
-
# Copyright (c) Microsoft Corporation.
|
|
3
|
-
# Licensed under the MIT License.
|
|
4
|
-
# ------------------------------------
|
|
5
|
-
import logging
|
|
6
|
-
import os
|
|
7
|
-
from azure.identity import InteractiveBrowserCredential, DeviceCodeCredential
|
|
8
|
-
import requests
|
|
9
|
-
import re
|
|
10
|
-
|
|
11
|
-
from azure.identity._constants import EnvironmentVariables
|
|
12
|
-
from azure.identity._internal import get_default_authority, normalize_authority
|
|
13
|
-
from azure.identity.aio import (
|
|
14
|
-
AzurePowerShellCredential,
|
|
15
|
-
EnvironmentCredential,
|
|
16
|
-
ManagedIdentityCredential,
|
|
17
|
-
SharedTokenCacheCredential,
|
|
18
|
-
AzureCliCredential,
|
|
19
|
-
VisualStudioCodeCredential,
|
|
20
|
-
)
|
|
21
|
-
from ._chained import _ChainedTokenCredential
|
|
22
|
-
from ._token import _TokenFileCredential
|
|
23
|
-
|
|
24
|
-
try:
|
|
25
|
-
from typing import TYPE_CHECKING
|
|
26
|
-
except ImportError:
|
|
27
|
-
TYPE_CHECKING = False
|
|
28
|
-
|
|
29
|
-
if TYPE_CHECKING:
|
|
30
|
-
from typing import Any, List
|
|
31
|
-
from azure.core.credentials_async import AccessToken, AsyncTokenCredential
|
|
32
|
-
|
|
33
|
-
_LOGGER = logging.getLogger(__name__)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
class _DefaultAzureCredential(_ChainedTokenCredential):
|
|
37
|
-
"""
|
|
38
|
-
Based on Azure.Identity.DefaultAzureCredential from:
|
|
39
|
-
https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/identity/azure-identity/azure/identity/_credentials/default.py
|
|
40
|
-
|
|
41
|
-
The two key differences are:
|
|
42
|
-
1) Inherit from _ChainedTokenCredential, which has
|
|
43
|
-
more aggressive error handling than ChainedTokenCredential
|
|
44
|
-
2) Instantiate the internal credentials the first time the get_token gets called
|
|
45
|
-
such that we can get the tenant_id if it was not passed by the user (but we don't
|
|
46
|
-
want to do that in the constructor).
|
|
47
|
-
We automatically identify the user's tenant_id for a given subscription
|
|
48
|
-
so that users with MSA accounts don't need to pass it.
|
|
49
|
-
This is a mitigation for bug https://github.com/Azure/azure-sdk-for-python/issues/18975
|
|
50
|
-
We need the following parameters to enable auto-detection of tenant_id
|
|
51
|
-
- subscription_id
|
|
52
|
-
- arm_base_url (defaults to the production url "https://management.azure.com/")
|
|
53
|
-
"""
|
|
54
|
-
def __init__(self, **kwargs):
|
|
55
|
-
# type: (**Any) -> None
|
|
56
|
-
self._successfull_tenant_id = None
|
|
57
|
-
|
|
58
|
-
self.authority = kwargs.pop("authority", None)
|
|
59
|
-
self.authority = normalize_authority(self.authority) if self.authority else get_default_authority()
|
|
60
|
-
|
|
61
|
-
self.interactive_browser_tenant_id = kwargs.pop(
|
|
62
|
-
"interactive_browser_tenant_id", os.environ.get(EnvironmentVariables.AZURE_TENANT_ID)
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
self.subscription_id = kwargs.pop(
|
|
66
|
-
"subscription_id", os.environ.get("SUBSCRIPTION_ID")
|
|
67
|
-
)
|
|
68
|
-
self.arm_base_url = kwargs.pop(
|
|
69
|
-
"arm_base_url", "https://management.azure.com/"
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
self.managed_identity_client_id = kwargs.pop(
|
|
73
|
-
"managed_identity_client_id", os.environ.get(EnvironmentVariables.AZURE_CLIENT_ID)
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
self.shared_cache_username = kwargs.pop("shared_cache_username", os.environ.get(EnvironmentVariables.AZURE_USERNAME))
|
|
77
|
-
self.shared_cache_tenant_id = kwargs.pop(
|
|
78
|
-
"shared_cache_tenant_id", os.environ.get(EnvironmentVariables.AZURE_TENANT_ID)
|
|
79
|
-
)
|
|
80
|
-
|
|
81
|
-
self.vscode_tenant_id = kwargs.pop(
|
|
82
|
-
"visual_studio_code_tenant_id", os.environ.get(EnvironmentVariables.AZURE_TENANT_ID)
|
|
83
|
-
)
|
|
84
|
-
|
|
85
|
-
self.exclude_token_file_credential = kwargs.pop("exclude_token_file_credential", False)
|
|
86
|
-
self.exclude_environment_credential = kwargs.pop("exclude_environment_credential", False)
|
|
87
|
-
self.exclude_managed_identity_credential = kwargs.pop("exclude_managed_identity_credential", False)
|
|
88
|
-
self.exclude_shared_token_cache_credential = kwargs.pop("exclude_shared_token_cache_credential", False)
|
|
89
|
-
self.exclude_visual_studio_code_credential = kwargs.pop("exclude_visual_studio_code_credential", False)
|
|
90
|
-
self.exclude_cli_credential = kwargs.pop("exclude_cli_credential", False)
|
|
91
|
-
self.exclude_interactive_browser_credential = kwargs.pop("exclude_interactive_browser_credential", True)
|
|
92
|
-
self.exclude_device_code_credential = kwargs.pop("exclude_device_code_credential", False)
|
|
93
|
-
self.exclude_powershell_credential = kwargs.pop("exclude_powershell_credential", False)
|
|
94
|
-
|
|
95
|
-
# credentials will be created lazy on the first call to get_token
|
|
96
|
-
super(_DefaultAzureCredential, self).__init__()
|
|
97
|
-
|
|
98
|
-
def _initialize_credentials(self):
|
|
99
|
-
if self.subscription_id is not None \
|
|
100
|
-
and self.arm_base_url is not None:
|
|
101
|
-
if self.vscode_tenant_id is None:
|
|
102
|
-
self.vscode_tenant_id = self._get_tenant_id(arm_base_url=self.arm_base_url, subscription_id=self.subscription_id)
|
|
103
|
-
if self.shared_cache_tenant_id is None:
|
|
104
|
-
self.shared_cache_tenant_id = self._get_tenant_id(arm_base_url=self.arm_base_url, subscription_id=self.subscription_id)
|
|
105
|
-
if self.interactive_browser_tenant_id is None:
|
|
106
|
-
self.interactive_browser_tenant_id = self._get_tenant_id(arm_base_url=self.arm_base_url, subscription_id=self.subscription_id)
|
|
107
|
-
|
|
108
|
-
credentials = [] # type: List[AsyncTokenCredential]
|
|
109
|
-
if not self.exclude_token_file_credential:
|
|
110
|
-
credentials.append(_TokenFileCredential())
|
|
111
|
-
if not self.exclude_environment_credential:
|
|
112
|
-
credentials.append(EnvironmentCredential(authority=self.authority))
|
|
113
|
-
if not self.exclude_managed_identity_credential:
|
|
114
|
-
credentials.append(ManagedIdentityCredential(client_id=self.managed_identity_client_id))
|
|
115
|
-
if not self.exclude_shared_token_cache_credential and SharedTokenCacheCredential.supported():
|
|
116
|
-
try:
|
|
117
|
-
# username and/or tenant_id are only required when the cache contains tokens for multiple identities
|
|
118
|
-
shared_cache = SharedTokenCacheCredential(
|
|
119
|
-
username=self.shared_cache_username, tenant_id=self.shared_cache_tenant_id, authority=self.authority
|
|
120
|
-
)
|
|
121
|
-
credentials.append(shared_cache)
|
|
122
|
-
except Exception as ex: # pylint:disable=broad-except
|
|
123
|
-
_LOGGER.info("Shared token cache is unavailable: '%s'", ex)
|
|
124
|
-
if not self.exclude_visual_studio_code_credential:
|
|
125
|
-
credentials.append(VisualStudioCodeCredential(tenant_id=self.vscode_tenant_id))
|
|
126
|
-
if not self.exclude_cli_credential:
|
|
127
|
-
credentials.append(AzureCliCredential())
|
|
128
|
-
if not self.exclude_powershell_credential:
|
|
129
|
-
credentials.append(AzurePowerShellCredential())
|
|
130
|
-
if not self.exclude_interactive_browser_credential:
|
|
131
|
-
credentials.append(InteractiveBrowserCredential(tenant_id=self.interactive_browser_tenant_id))
|
|
132
|
-
if not self.exclude_device_code_credential:
|
|
133
|
-
credentials.append(DeviceCodeCredential(tenant_id=self.interactive_browser_tenant_id))
|
|
134
|
-
|
|
135
|
-
self.credentials = credentials
|
|
136
|
-
|
|
137
|
-
async def get_token(self, *scopes, **kwargs):
|
|
138
|
-
# type: (*str, **Any) -> AccessToken
|
|
139
|
-
"""Request an access token for `scopes`.
|
|
140
|
-
This method is called automatically by Azure SDK clients.
|
|
141
|
-
:param str scopes: desired scopes for the access token. This method requires at least one scope.
|
|
142
|
-
:raises ~azure.core.exceptions.ClientAuthenticationError: authentication failed. The exception has a
|
|
143
|
-
`message` attribute listing each authentication attempt and its error message.
|
|
144
|
-
"""
|
|
145
|
-
# add credentials the first time it runs the get_token
|
|
146
|
-
# such that the _get_tenant_id can be called only when needed
|
|
147
|
-
if self.credentials is None \
|
|
148
|
-
or len(self.credentials) == 0:
|
|
149
|
-
self._initialize_credentials()
|
|
150
|
-
|
|
151
|
-
return await super(_DefaultAzureCredential, self).get_token(*scopes, **kwargs)
|
|
152
|
-
|
|
153
|
-
def _get_tenant_id(self, arm_base_url:str, subscription_id:str):
|
|
154
|
-
if arm_base_url is None:
|
|
155
|
-
raise ValueError("arm_base_url is mandatory parameter")
|
|
156
|
-
if subscription_id is None:
|
|
157
|
-
raise ValueError("subscription_id is mandatory parameter")
|
|
158
|
-
|
|
159
|
-
# returns the cached tenant_id if available
|
|
160
|
-
if self._successfull_tenant_id is not None:
|
|
161
|
-
return self._successfull_tenant_id
|
|
162
|
-
|
|
163
|
-
try:
|
|
164
|
-
uri = (
|
|
165
|
-
f"{arm_base_url}/subscriptions/"
|
|
166
|
-
+ f"{subscription_id}?api-version=2018-01-01"
|
|
167
|
-
)
|
|
168
|
-
response = requests.get(uri)
|
|
169
|
-
|
|
170
|
-
# This gnarly piece of code is how we get the guest tenant
|
|
171
|
-
# authority associated with the subscription.
|
|
172
|
-
# We make a unauthenticated request to ARM and extract the tenant
|
|
173
|
-
# authority from the WWW-Authenticate header in the response.
|
|
174
|
-
# The header is of the form:
|
|
175
|
-
# Bearer authorization_uri=
|
|
176
|
-
# https://login.microsoftonline.com/tenantId, key1=value1s
|
|
177
|
-
auth_header = response.headers["WWW-Authenticate"]
|
|
178
|
-
_LOGGER.debug(
|
|
179
|
-
f'{"got the following auth header from"}'
|
|
180
|
-
f"the management endpoint: {auth_header}"
|
|
181
|
-
)
|
|
182
|
-
|
|
183
|
-
trimmed_auth_header = auth_header[
|
|
184
|
-
len("Bearer "):
|
|
185
|
-
] # trim the leading 'Bearer '
|
|
186
|
-
trimmed_auth_header_parts = trimmed_auth_header.split(
|
|
187
|
-
","
|
|
188
|
-
) # get the various k=v parts
|
|
189
|
-
key_value_pairs = dict(
|
|
190
|
-
map(lambda s: tuple(s.split("=")), trimmed_auth_header_parts)
|
|
191
|
-
) # make the parts into a dictionary
|
|
192
|
-
quoted_tenant_uri = key_value_pairs[
|
|
193
|
-
"authorization_uri"
|
|
194
|
-
] # get the value of the 'authorization_uri' key
|
|
195
|
-
tenant_uri = quoted_tenant_uri[
|
|
196
|
-
1:-1
|
|
197
|
-
] # strip it of surrounding quotes
|
|
198
|
-
|
|
199
|
-
_LOGGER.debug(
|
|
200
|
-
f'{"got the following tenant uri from"}'
|
|
201
|
-
+ f"the authentication header: {tenant_uri}"
|
|
202
|
-
)
|
|
203
|
-
|
|
204
|
-
regex = re.compile(pattern=r"([a-f0-9]+[-]){4}[a-f0-9]+", flags=re.IGNORECASE)
|
|
205
|
-
self._successfull_tenant_id = regex.search(tenant_uri).group()
|
|
206
|
-
return self._successfull_tenant_id
|
|
207
|
-
|
|
208
|
-
except Exception as e:
|
|
209
|
-
_LOGGER.debug(
|
|
210
|
-
f"Failed to get tenant authority for subscription: {e}"
|
|
211
|
-
)
|
|
212
|
-
return None
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
##
|
|
2
|
-
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
# Licensed under the MIT License.
|
|
4
|
-
##
|
|
5
|
-
import json
|
|
6
|
-
from json.decoder import JSONDecodeError
|
|
7
|
-
import logging
|
|
8
|
-
import os
|
|
9
|
-
import time
|
|
10
|
-
from aiofile import async_open
|
|
11
|
-
|
|
12
|
-
from azure.identity import CredentialUnavailableError
|
|
13
|
-
from azure.core.credentials import AccessToken
|
|
14
|
-
|
|
15
|
-
try:
|
|
16
|
-
from typing import TYPE_CHECKING
|
|
17
|
-
except ImportError:
|
|
18
|
-
TYPE_CHECKING = False
|
|
19
|
-
|
|
20
|
-
if TYPE_CHECKING:
|
|
21
|
-
# pylint:disable=unused-import,ungrouped-imports
|
|
22
|
-
from typing import Any
|
|
23
|
-
|
|
24
|
-
_LOGGER = logging.getLogger(__name__)
|
|
25
|
-
|
|
26
|
-
_TOKEN_FILE_ENV_VARIABLE = "AZURE_QUANTUM_TOKEN_FILE"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
class _TokenFileCredential(object):
|
|
30
|
-
"""
|
|
31
|
-
Implements a custom TokenCredential to use a local file as the source for an AzureQuantum token.
|
|
32
|
-
|
|
33
|
-
It will only use the local file if the AZURE_QUANTUM_TOKEN_FILE environment variable is set, and references
|
|
34
|
-
an existing json file that contains the access_token and expires_on timestamp in milliseconds.
|
|
35
|
-
|
|
36
|
-
If the environment variable is not set, the file does not exist, or the token is invalid in any way (expired, for example),
|
|
37
|
-
then the credential will throw CredentialUnavailableError, so that _ChainedTokenCredential can fallback to other methods.
|
|
38
|
-
"""
|
|
39
|
-
def __init__(self, **kwargs):
|
|
40
|
-
# type: (**Any) -> None
|
|
41
|
-
self.token_file = os.environ.get(_TOKEN_FILE_ENV_VARIABLE)
|
|
42
|
-
if self.token_file:
|
|
43
|
-
_LOGGER.debug("Using provided token file location: {}".format(self.token_file))
|
|
44
|
-
else:
|
|
45
|
-
_LOGGER.debug("No token file location provided for {} environment variable.".format(_TOKEN_FILE_ENV_VARIABLE))
|
|
46
|
-
|
|
47
|
-
async def get_token(self, *scopes, **kwargs): # pylint:disable=unused-argument
|
|
48
|
-
# type: (*str, **Any) -> AccessToken
|
|
49
|
-
"""Request an access token for `scopes`.
|
|
50
|
-
This method is called automatically by Azure SDK clients.
|
|
51
|
-
:param str scopes: desired scopes for the access token. This method only returns tokens for the https://quantum.microsoft.com/.default scope.
|
|
52
|
-
:raises ~azure.identity.CredentialUnavailableError: when failing to get token. The exception has a
|
|
53
|
-
`message` attribute with the error message.
|
|
54
|
-
"""
|
|
55
|
-
if not self.token_file:
|
|
56
|
-
raise CredentialUnavailableError(message="Token file location not set.")
|
|
57
|
-
|
|
58
|
-
if not os.path.isfile(self.token_file):
|
|
59
|
-
raise CredentialUnavailableError(message="Token file at {} does not exist.".format(self.token_file))
|
|
60
|
-
|
|
61
|
-
try:
|
|
62
|
-
token = await self._parse_token_file(self.token_file)
|
|
63
|
-
except JSONDecodeError:
|
|
64
|
-
raise CredentialUnavailableError(message="Failed to parse token file: Invalid JSON.")
|
|
65
|
-
except KeyError as e:
|
|
66
|
-
raise CredentialUnavailableError(message="Failed to parse token file: Missing expected value: " + str(e))
|
|
67
|
-
except Exception as e:
|
|
68
|
-
raise CredentialUnavailableError(message="Failed to parse token file: " + str(e))
|
|
69
|
-
|
|
70
|
-
if token.expires_on <= time.time():
|
|
71
|
-
raise CredentialUnavailableError(message="Token already expired at {}".format(time.asctime(time.gmtime(token.expires_on))))
|
|
72
|
-
|
|
73
|
-
return token
|
|
74
|
-
|
|
75
|
-
async def _parse_token_file(self, path):
|
|
76
|
-
# type: (*str) -> AccessToken
|
|
77
|
-
async with async_open(path, "r") as file:
|
|
78
|
-
data = json.load(file)
|
|
79
|
-
expires_on = int(data["expires_on"]) / 1000 # Convert ms to seconds, since python time.time only handles epoch time in seconds
|
|
80
|
-
token = AccessToken(data["access_token"], expires_on)
|
|
81
|
-
return token
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from azure.quantum.aio.job.job import Job
|