azure-quantum 1.1.1__py3-none-any.whl → 1.1.2.dev0__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.
@@ -2,17 +2,19 @@
2
2
  # Copyright (c) Microsoft Corporation. All rights reserved.
3
3
  # Licensed under the MIT License.
4
4
  ##
5
+
6
+ from __future__ import annotations
5
7
  from datetime import datetime
6
8
  import logging
7
- import os
8
- import re
9
-
10
- from typing import Any, Dict, Iterable, List, Optional, TYPE_CHECKING, Tuple, Union
11
-
12
- # Temporarily replacing the DefaultAzureCredential with
13
- # a custom _DefaultAzureCredential
14
- # from azure.identity import DefaultAzureCredential
15
- from azure.quantum._authentication import _DefaultAzureCredential
9
+ from typing import (
10
+ Any,
11
+ Dict,
12
+ Iterable,
13
+ List,
14
+ Optional,
15
+ TYPE_CHECKING,
16
+ Tuple,
17
+ Union)
16
18
 
17
19
  from azure.quantum._client import QuantumClient
18
20
  from azure.quantum._client.operations import (
@@ -23,10 +25,18 @@ from azure.quantum._client.operations import (
23
25
  TopLevelItemsOperations
24
26
  )
25
27
  from azure.quantum._client.models import BlobDetails, JobStatus
26
- from azure.quantum import Job, Session
27
- from azure.quantum.storage import create_container_using_client, get_container_uri, ContainerClient
28
-
29
- from .version import __version__
28
+ from azure.quantum import Job, Session
29
+ from azure.quantum._workspace_connection_params import (
30
+ WorkspaceConnectionParams
31
+ )
32
+ from azure.quantum._constants import (
33
+ ConnectionConstants,
34
+ )
35
+ from azure.quantum.storage import (
36
+ create_container_using_client,
37
+ get_container_uri,
38
+ ContainerClient
39
+ )
30
40
 
31
41
  if TYPE_CHECKING:
32
42
  from azure.quantum._client.models import TargetStatus
@@ -36,65 +46,36 @@ logger = logging.getLogger(__name__)
36
46
 
37
47
  __all__ = ["Workspace"]
38
48
 
39
- DEFAULT_CONTAINER_NAME_FORMAT = "job-{job_id}"
40
- USER_AGENT_APPID_ENV_VAR_NAME = "AZURE_QUANTUM_PYTHON_APPID"
41
-
42
-
43
- def sdk_environment(name):
44
- return (
45
- "AZURE_QUANTUM_ENV" in os.environ
46
- and os.environ["AZURE_QUANTUM_ENV"] == name
47
- )
48
-
49
-
50
- # Settings based on environment variables:
51
- BASE_URL_FROM_ENV = (
52
- os.environ["AZURE_QUANTUM_BASEURL"]
53
- if "AZURE_QUANTUM_BASEURL" in os.environ
54
- else None
55
- )
56
- if sdk_environment("dogfood"):
57
- logger.info("Using DOGFOOD configuration.")
58
- BASE_URL = (
59
- lambda location: BASE_URL_FROM_ENV
60
- or f"https://{location}.quantum-test.azure.com/"
61
- )
62
- ARM_BASE_URL = "https://api-dogfood.resources.windows-int.net/"
63
- else:
64
- if sdk_environment("canary"):
65
- logger.info("Using CANARY configuration.")
66
- BASE_URL = (
67
- lambda location: BASE_URL_FROM_ENV
68
- or f'{"https://eastus2euap.quantum.azure.com/"}'
69
- )
70
- else:
71
- logger.debug("Using production configuration.")
72
- BASE_URL = (
73
- lambda location: BASE_URL_FROM_ENV
74
- or f"https://{location}.quantum.azure.com/"
75
- )
76
- ARM_BASE_URL = "https://management.azure.com/"
77
-
78
49
 
79
50
  class Workspace:
51
+ DEFAULT_CONTAINER_NAME_FORMAT = "job-{job_id}"
52
+
80
53
  """Represents an Azure Quantum workspace.
81
54
 
82
- When creating a Workspace object, callers have two options for identifying
83
- the Azure Quantum workspace:
84
- 1. specify a valid resource ID, or
85
- 2. specify a valid subscription ID, resource group, and workspace name.
55
+ When creating a Workspace object, callers have two options for
56
+ identifying the Azure Quantum workspace (in order of precedence):
57
+ 1. specify a valid location and resource ID; or
58
+ 2. specify a valid location, subscription ID,
59
+ resource group, and workspace name.
60
+
61
+ You can also use a connection string to specify the connection parameters
62
+ to a Azure Quantum Workspace by calling:
63
+ Workspace.from_connection_string()
86
64
 
87
65
  If the Azure Quantum workspace does not have linked storage, the caller
88
66
  must also pass a valid Azure storage account connection string.
89
67
 
90
68
  :param subscription_id:
91
- The Azure subscription ID. Ignored if resource_id is specified.
69
+ The Azure subscription ID.
70
+ Ignored if resource_id is specified.
92
71
 
93
72
  :param resource_group:
94
- The Azure resource group name. Ignored if resource_id is specified.
73
+ The Azure resource group name.
74
+ Ignored if resource_id is specified.
95
75
 
96
76
  :param name:
97
- The Azure Quantum workspace name. Ignored if resource_id is specified.
77
+ The Azure Quantum workspace name.
78
+ Ignored if resource_id is specified.
98
79
 
99
80
  :param storage:
100
81
  The Azure storage account connection string.
@@ -113,15 +94,12 @@ class Workspace:
113
94
  The credential to use to connect to Azure services.
114
95
  Normally one of the credential types from Azure.Identity (https://learn.microsoft.com/python/api/overview/azure/identity-readme?view=azure-python#credential-classes).
115
96
 
116
- Defaults to \"DefaultAzureCredential\", which will attempt multiple
97
+ Defaults to \"DefaultAzureCredential\", which will attempt multiple
117
98
  forms of authentication.
118
99
 
119
100
  :param user_agent:
120
101
  Add the specified value as a prefix to the HTTP User-Agent header when communicating to the Azure Quantum service.
121
102
  """
122
-
123
- credentials = None
124
-
125
103
  def __init__(
126
104
  self,
127
105
  subscription_id: Optional[str] = None,
@@ -132,110 +110,107 @@ class Workspace:
132
110
  location: Optional[str] = None,
133
111
  credential: Optional[object] = None,
134
112
  user_agent: Optional[str] = None,
113
+ **kwargs: Any,
135
114
  ):
136
- if resource_id is not None:
137
- # A valid resource ID looks like:
138
- # /subscriptions/f846b2bd-d0e2-4a1d-8141-4c6944a9d387/resourceGroups/
139
- # RESOURCE_GROUP_NAME/providers/Microsoft.Quantum/Workspaces/WORKSPACE_NAME
140
- regex = r"^/subscriptions/([a-fA-F0-9-]*)/resourceGroups/([^\s/]*)/providers/Microsoft\.Quantum/Workspaces/([^\s/]*)$"
141
- match = re.search(regex, resource_id, re.IGNORECASE)
142
- if match:
143
- # match should contain four groups:
144
- # -> match.group(0):
145
- # The full resource ID for the Azure Quantum workspace
146
- # -> match.group(1): The Azure subscription ID
147
- # -> match.group(2): The Azure resource group name
148
- # -> match.group(3): The Azure Quantum workspace name
149
- subscription_id = match.group(1)
150
- resource_group = match.group(2)
151
- name = match.group(3)
152
-
153
- if not subscription_id or not resource_group or not name:
154
- raise ValueError(
155
- "Azure Quantum workspace not fully specified."
156
- + "Please specify either a valid resource ID "
157
- + "or a valid combination of subscription ID,"
158
- + "resource group name, and workspace name."
159
- )
115
+ connection_params = WorkspaceConnectionParams(
116
+ location=location,
117
+ subscription_id=subscription_id,
118
+ resource_group=resource_group,
119
+ workspace_name=name,
120
+ credential=credential,
121
+ resource_id=resource_id,
122
+ user_agent=user_agent,
123
+ **kwargs
124
+ ).default_from_env_vars()
125
+
126
+ logger.info("Using %s environment.", connection_params.environment)
127
+
128
+ connection_params.assert_complete()
160
129
 
161
- if not location:
162
- raise ValueError(
163
- "Azure Quantum workspace does not have an associated location. " +
164
- "Please specify the location associated with your workspace.")
165
-
166
- # Temporarily using a custom _DefaultAzureCredential
167
- # instead of Azure.Identity.DefaultAzureCredential
168
- # See _DefaultAzureCredential documentation for more info.
169
- if credential is None:
170
- credential = _DefaultAzureCredential(exclude_interactive_browser_credential=False,
171
- exclude_shared_token_cache_credential=True,
172
- subscription_id=subscription_id,
173
- arm_base_url=ARM_BASE_URL)
174
-
175
- self.credentials = credential
176
- self.name = name
177
- self.resource_group = resource_group
178
- self.subscription_id = subscription_id
179
- self.storage = storage
180
- self._user_agent = user_agent
181
-
182
- # Convert user-provided location into names
183
- # recognized by Azure resource manager.
184
- # For example, a customer-provided value of
185
- # "West US" should be converted to "westus".
186
- self.location = "".join(location.split()).lower()
130
+ connection_params.on_new_client_request = self.on_new_client_request
131
+
132
+ self._connection_params = connection_params
133
+ self._storage = storage
187
134
 
188
135
  # Create QuantumClient
189
136
  self._client = self._create_client()
190
137
 
191
- def _create_client(self) -> QuantumClient:
192
- endpoint = BASE_URL(self.location)
193
- logger.debug(
194
- f"Creating client for: subs:{self.subscription_id},"
195
- + f"rg={self.resource_group}, ws={self.name}, frontdoor={endpoint}"
196
- )
138
+ def on_new_client_request(self):
139
+ self._client = self._create_client()
140
+
141
+ @property
142
+ def location(self):
143
+ return self._connection_params.location
197
144
 
145
+ @property
146
+ def subscription_id(self):
147
+ return self._connection_params.subscription_id
148
+
149
+ @property
150
+ def resource_group(self):
151
+ return self._connection_params.resource_group
152
+
153
+ @property
154
+ def name(self):
155
+ return self._connection_params.workspace_name
156
+
157
+ @property
158
+ def credential(self):
159
+ return self._connection_params.credential
160
+
161
+ @property
162
+ def storage(self):
163
+ return self._storage
164
+
165
+ def _create_client(self) -> QuantumClient:
166
+ connection_params = self._connection_params
167
+ kwargs = {}
168
+ if connection_params.api_version:
169
+ kwargs["api_version"] = connection_params.api_version
198
170
  client = QuantumClient(
199
- credential=self.credentials,
200
- subscription_id=self.subscription_id,
201
- resource_group_name=self.resource_group,
202
- workspace_name=self.name,
203
- endpoint=endpoint,
204
- user_agent=self.user_agent
171
+ credential=connection_params.get_credential_or_default(),
172
+ subscription_id=connection_params.subscription_id,
173
+ resource_group_name=connection_params.resource_group,
174
+ workspace_name=connection_params.workspace_name,
175
+ azure_region=connection_params.location,
176
+ user_agent=connection_params.get_full_user_agent(),
177
+ credential_scopes = [ConnectionConstants.DATA_PLANE_CREDENTIAL_SCOPE],
178
+ endpoint=connection_params.quantum_endpoint,
179
+ authentication_policy=connection_params.get_auth_policy(),
180
+ **kwargs
205
181
  )
206
182
  return client
207
183
 
208
184
  @property
209
185
  def user_agent(self):
210
186
  """
211
- Get the Workspace's UserAgent that is sent to the service via the header.
212
- Uses the value specified during initialization and appends the environment
213
- variable AZURE_QUANTUM_PYTHON_APPID if specified.
187
+ Get the Workspace's UserAgent that is sent to
188
+ the service via the header.
214
189
  """
215
- full_user_agent = self._user_agent
216
- env_app_id = os.environ.get(USER_AGENT_APPID_ENV_VAR_NAME)
217
- if env_app_id:
218
- full_user_agent = f"{full_user_agent}-{env_app_id}" if full_user_agent else env_app_id
219
- return full_user_agent
190
+ return self._connection_params.get_full_user_agent()
220
191
 
221
- def append_user_agent(self, value: Union[str, None]):
192
+ def append_user_agent(self, value: str):
222
193
  """
223
194
  Append a new value to the Workspace's UserAgent and re-initialize the
224
195
  QuantumClient. The values are appended using a dash.
225
196
 
226
197
  :param value: UserAgent value to add, e.g. "azure-quantum-<plugin>"
227
198
  """
228
- new_user_agent = None
229
-
230
- if value is not None and value not in (self._user_agent or ""):
231
- new_user_agent = f"{self._user_agent}-{value}" if self._user_agent else value
199
+ self._connection_params.append_user_agent(value=value)
232
200
 
233
- if new_user_agent != self._user_agent:
234
- self._user_agent = new_user_agent
235
- # We need to recreate the client for it to
236
- # pick the new UserAgent
237
- if self._client is not None:
238
- self._client = self._create_client()
201
+ @classmethod
202
+ def from_connection_string(cls, connection_string: str, **kwargs) -> Workspace:
203
+ """
204
+ Creates a new Azure Quantum Workspace client from a connection string.
205
+ """
206
+ connection_params = WorkspaceConnectionParams(connection_string=connection_string)
207
+ return cls(
208
+ subscription_id=connection_params.subscription_id,
209
+ resource_group=connection_params.resource_group,
210
+ name=connection_params.workspace_name,
211
+ location=connection_params.location,
212
+ credential=connection_params.get_credential_or_default(),
213
+ **kwargs)
239
214
 
240
215
  def _get_top_level_items_client(self) -> TopLevelItemsOperations:
241
216
  return self._client.top_level_items
@@ -252,9 +227,6 @@ class Workspace:
252
227
  def _get_quotas_client(self) -> QuotasOperations:
253
228
  return self._client.quotas
254
229
 
255
- def _custom_headers(self):
256
- return {"x-ms-azurequantum-sdk-version": __version__}
257
-
258
230
  def _get_linked_storage_sas_uri(
259
231
  self, container_name: str, blob_name: str = None
260
232
  ) -> str:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: azure-quantum
3
- Version: 1.1.1
3
+ Version: 1.1.2.dev0
4
4
  Summary: Python client for Azure Quantum
5
5
  Home-page: https://github.com/microsoft/azure-quantum-python
6
6
  Author: Microsoft
@@ -1,24 +1,26 @@
1
1
  azure/quantum/__init__.py,sha256=Za8xZY4lzFkW8m4ero-bqrfN437D2NRukM77ukb4GPM,508
2
+ azure/quantum/_constants.py,sha256=6FCBpjUK2GHeycKejgGYTvxtlSsfWdbG2iOXGQg8NaM,3219
3
+ azure/quantum/_workspace_connection_params.py,sha256=fGha3ALz1YRnKo07xHCbDzDcmUS7rsaakGvx_pvVINo,21632
2
4
  azure/quantum/storage.py,sha256=_4bMniDk9LrB_K5CQwuCivJFZXdmhRvU2b6Z3xxXw9I,12556
3
- azure/quantum/version.py,sha256=_ggGKCYTcHkMXXBdnBqCf8DkjOIdLBgQe0iSM5GGXhA,235
4
- azure/quantum/workspace.py,sha256=a-KjVbDbnPNBzsCzDmQOv90Dh6WGVuZn3UiuL7jNDPk,19757
5
+ azure/quantum/version.py,sha256=-vAeAqsgIjIU8KmFftm1j4jiGOI7BOHvbIG4ovYqcv4,240
6
+ azure/quantum/workspace.py,sha256=QXnIHOOYEGixajbZ8oeEWu-fAUI_Fms4zkA_amurm3g,17607
5
7
  azure/quantum/_authentication/__init__.py,sha256=bniNZlS0hMIjO_y7DevGBAS6MixyA5pbPHcdGipUWM4,236
6
- azure/quantum/_authentication/_chained.py,sha256=bs4w7auiCoRaNB0f86yAQU04Jgmd8VcKfy1wWmUxt6Q,5047
7
- azure/quantum/_authentication/_default.py,sha256=efU7o2yqsm7TJ88H6LEP2IZYL0Wj7cqcEmXv_rvELKo,10502
8
- azure/quantum/_authentication/_token.py,sha256=1rEmuu5XY3MApx_rCo7lnsi0qhch-y3goK5zXriXS7A,3570
8
+ azure/quantum/_authentication/_chained.py,sha256=0rdohB_fVGFHUhlly9sGxqQTBTZGpGxtlBqNHDFbAqE,4848
9
+ azure/quantum/_authentication/_default.py,sha256=RzhK5UNQb6TK95VQI4o8Gm2nxtOaz64yA0J9Tw9zpW4,6625
10
+ azure/quantum/_authentication/_token.py,sha256=mOrvibDiOgkDnqU1OBIw9PyIv-np6DkdxMNC4UtuGkc,3616
9
11
  azure/quantum/_client/__init__.py,sha256=kzaVxPfnju-Y_EGMfOVYVB7pHjPvc-IWrkFI2eNk68s,896
10
- azure/quantum/_client/_client.py,sha256=Ze9RgPOC2ByOei_sZ-t-HrIjr9gk9TisJQigp_zkHgs,5854
11
- azure/quantum/_client/_configuration.py,sha256=bPbYqPE6tVIH1ApQ0X5GybMykYQs-hu2i5d05BRFx8E,4444
12
+ azure/quantum/_client/_client.py,sha256=ZG-zalnITLyBk3BSMjLt4PtnNv8Nky5-kcmnIrk1IkQ,7143
13
+ azure/quantum/_client/_configuration.py,sha256=5uktKtZxoVVAoSyeL0VNGS9AfPERp-9rU5Vn30dgY7o,4440
12
14
  azure/quantum/_client/_patch.py,sha256=YTV6yZ9bRfBBaw2z7v4MdzR-zeHkdtKkGb4SU8C25mE,694
13
- azure/quantum/_client/_serialization.py,sha256=CMxjYOWCILsk7kozMUGRsyeKUw-tkxI_k0EvYkqQZKU,80832
15
+ azure/quantum/_client/_serialization.py,sha256=KJSS6KWgnKcz-cENQCmWZ9Ziv303lnBbLwFIpYZeKFU,81097
14
16
  azure/quantum/_client/_vendor.py,sha256=h8ByiyZ4cCQyFxqnuhTQdv1Rms3dVjKsrgZDzwMcSJ0,996
15
- azure/quantum/_client/_version.py,sha256=yBnfwkwYY2laMqv1FZa-C3phZufP-IQzzwdy5sE7BLY,495
17
+ azure/quantum/_client/_version.py,sha256=1BvMPpsGTc8vSsVvDoi2TMiSVPtozGm87WOCYKmau7Q,500
16
18
  azure/quantum/_client/models/__init__.py,sha256=c1PRpzNsQTcDk4GkrFMMIlwNQQa2c0p5N0Lzd-23YBA,2100
17
19
  azure/quantum/_client/models/_enums.py,sha256=omj_B8_E8ONzTHg5hLgDlFYibRRbdr9sEN298im_otA,2977
18
- azure/quantum/_client/models/_models.py,sha256=LxIEord6GsqPbFqS4TWWqxVL9w7-TbsbVhsaUGwyP9M,41802
20
+ azure/quantum/_client/models/_models.py,sha256=wktCM5oBVfwQetNoHobL1wNsC3knXV-HmqBq_Q77Kw4,41810
19
21
  azure/quantum/_client/models/_patch.py,sha256=YTV6yZ9bRfBBaw2z7v4MdzR-zeHkdtKkGb4SU8C25mE,694
20
22
  azure/quantum/_client/operations/__init__.py,sha256=1mIl1WjHa-yFdX45TZayC1JfYeEPj5v7E2i7vck69qM,1154
21
- azure/quantum/_client/operations/_operations.py,sha256=qEsFFyPozfw384AV8EkDQJKiKG2Q8NRb4GoDYqKRpqQ,75919
23
+ azure/quantum/_client/operations/_operations.py,sha256=N_96-hfw6dYL3xfOI1mrYiXWAbWhNBNsV8EFpHtjW4U,81928
22
24
  azure/quantum/_client/operations/_patch.py,sha256=YTV6yZ9bRfBBaw2z7v4MdzR-zeHkdtKkGb4SU8C25mE,694
23
25
  azure/quantum/argument_types/__init__.py,sha256=S3-qpSHPz2d27xrgYbWvnv76OzULIONTp9mSGXu2ATM,271
24
26
  azure/quantum/argument_types/types.py,sha256=2mM8s37DKgNfSsjzwmg4dnmj9roSeHY1ZT5vKnpjAYM,1041
@@ -70,7 +72,7 @@ azure/quantum/target/pasqal/target.py,sha256=j9xK9chbmo-FL4Y9HBVqtL14Rr6lxQK6UN-
70
72
  azure/quantum/target/rigetti/__init__.py,sha256=I1vyzZBYGI540pauTqJd0RSSyTShGqkEL7Yjo25_RNY,378
71
73
  azure/quantum/target/rigetti/result.py,sha256=yDtT1y-JZFU7_mCaN1V_E6LPjJVD2vn4jvHOPT0IP9k,2278
72
74
  azure/quantum/target/rigetti/target.py,sha256=hGZm1wkBb1CBtDBWXEFS2Nje6gRXBTjOYgFkjOJ7TZ8,6458
73
- azure_quantum-1.1.1.dist-info/METADATA,sha256=xE8CjqqeGlNfvT77hOhtsmod66bCJpd3n8vK8ERQKUM,7304
74
- azure_quantum-1.1.1.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
75
- azure_quantum-1.1.1.dist-info/top_level.txt,sha256=S7DhWV9m80TBzAhOFjxDUiNbKszzoThbnrSz5MpbHSQ,6
76
- azure_quantum-1.1.1.dist-info/RECORD,,
75
+ azure_quantum-1.1.2.dev0.dist-info/METADATA,sha256=Zorh_0O9e8Wlm5o9DWOxLThwb2Evn68rVPmzrct02MU,7309
76
+ azure_quantum-1.1.2.dev0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
77
+ azure_quantum-1.1.2.dev0.dist-info/top_level.txt,sha256=S7DhWV9m80TBzAhOFjxDUiNbKszzoThbnrSz5MpbHSQ,6
78
+ azure_quantum-1.1.2.dev0.dist-info/RECORD,,