azure-quantum 3.5.0.dev0__tar.gz → 3.5.1.dev0__tar.gz
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-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/PKG-INFO +4 -5
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/README.md +3 -4
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/_version.py +1 -1
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_constants.py +69 -0
- azure_quantum-3.5.1.dev0/azure/quantum/_mgmt_client.py +239 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_workspace_connection_params.py +128 -27
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/version.py +1 -1
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/workspace.py +63 -5
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure_quantum.egg-info/PKG-INFO +4 -5
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure_quantum.egg-info/SOURCES.txt +1 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/__init__.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/__init__.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/_client.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/_configuration.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/_model_base.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/_patch.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/_serialization.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/models/__init__.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/models/_enums.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/models/_models.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/models/_patch.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/operations/__init__.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/operations/_operations.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/operations/_patch.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/argument_types/__init__.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/argument_types/types.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/cirq/__init__.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/cirq/job.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/cirq/service.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/cirq/targets/__init__.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/cirq/targets/ionq.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/cirq/targets/quantinuum.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/cirq/targets/target.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/job/__init__.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/job/base_job.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/job/filtered_job.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/job/job.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/job/job_failed_with_results_error.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/job/session.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/job/workspace_item.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/job/workspace_item_factory.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/qiskit/__init__.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/qiskit/backends/__init__.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/qiskit/backends/_qiskit_ionq.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/qiskit/backends/backend.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/qiskit/backends/ionq.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/qiskit/backends/qci.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/qiskit/backends/quantinuum.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/qiskit/backends/rigetti.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/qiskit/job.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/qiskit/provider.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/storage.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/target/__init__.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/target/ionq.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/target/params.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/target/pasqal/__init__.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/target/pasqal/result.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/target/pasqal/target.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/target/quantinuum.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/target/rigetti/__init__.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/target/rigetti/result.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/target/rigetti/target.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/target/target.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/target/target_factory.py +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure_quantum.egg-info/dependency_links.txt +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure_quantum.egg-info/requires.txt +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure_quantum.egg-info/top_level.txt +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/requirements-cirq.txt +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/requirements-dev.txt +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/requirements-pulser.txt +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/requirements-qiskit.txt +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/requirements-qsharp.txt +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/requirements-quil.txt +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/requirements.txt +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/setup.cfg +0 -0
- {azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: azure-quantum
|
|
3
|
-
Version: 3.5.
|
|
3
|
+
Version: 3.5.1.dev0
|
|
4
4
|
Summary: Python client for Azure Quantum
|
|
5
5
|
Home-page: https://github.com/microsoft/azure-quantum-python
|
|
6
6
|
Author: Microsoft
|
|
@@ -79,15 +79,14 @@ To get started, visit the following Quickstart guides:
|
|
|
79
79
|
|
|
80
80
|
## General usage ##
|
|
81
81
|
|
|
82
|
-
To connect to your Azure Quantum Workspace, go to the [Azure Portal](https://portal.azure.com), navigate to your Workspace and copy-paste the resource ID
|
|
82
|
+
To connect to your Azure Quantum Workspace, go to the [Azure Portal](https://portal.azure.com), navigate to your Workspace and copy-paste the resource ID into the code snippet below.
|
|
83
83
|
|
|
84
84
|
```python
|
|
85
85
|
from azure.quantum import Workspace
|
|
86
86
|
|
|
87
|
-
# Enter your Workspace
|
|
87
|
+
# Enter your Workspace resource ID below
|
|
88
88
|
workspace = Workspace(
|
|
89
|
-
resource_id=""
|
|
90
|
-
location=""
|
|
89
|
+
resource_id=""
|
|
91
90
|
)
|
|
92
91
|
```
|
|
93
92
|
|
|
@@ -29,15 +29,14 @@ To get started, visit the following Quickstart guides:
|
|
|
29
29
|
|
|
30
30
|
## General usage ##
|
|
31
31
|
|
|
32
|
-
To connect to your Azure Quantum Workspace, go to the [Azure Portal](https://portal.azure.com), navigate to your Workspace and copy-paste the resource ID
|
|
32
|
+
To connect to your Azure Quantum Workspace, go to the [Azure Portal](https://portal.azure.com), navigate to your Workspace and copy-paste the resource ID into the code snippet below.
|
|
33
33
|
|
|
34
34
|
```python
|
|
35
35
|
from azure.quantum import Workspace
|
|
36
36
|
|
|
37
|
-
# Enter your Workspace
|
|
37
|
+
# Enter your Workspace resource ID below
|
|
38
38
|
workspace = Workspace(
|
|
39
|
-
resource_id=""
|
|
40
|
-
location=""
|
|
39
|
+
resource_id=""
|
|
41
40
|
)
|
|
42
41
|
```
|
|
43
42
|
|
|
@@ -55,6 +55,9 @@ class ConnectionConstants:
|
|
|
55
55
|
DATA_PLANE_CREDENTIAL_SCOPE = "https://quantum.microsoft.com/.default"
|
|
56
56
|
ARM_CREDENTIAL_SCOPE = "https://management.azure.com/.default"
|
|
57
57
|
|
|
58
|
+
DEFAULT_ARG_API_VERSION = "2021-03-01"
|
|
59
|
+
DEFAULT_WORKSPACE_API_VERSION = "2025-11-01-preview"
|
|
60
|
+
|
|
58
61
|
MSA_TENANT_ID = "9188040d-6c67-4c5b-b112-36a304b66dad"
|
|
59
62
|
|
|
60
63
|
AUTHORITY = AzureIdentityInternals.get_default_authority()
|
|
@@ -63,10 +66,14 @@ class ConnectionConstants:
|
|
|
63
66
|
# pylint: disable=unnecessary-lambda-assignment
|
|
64
67
|
GET_QUANTUM_PRODUCTION_ENDPOINT = \
|
|
65
68
|
lambda location: f"https://{location}.quantum.azure.com/"
|
|
69
|
+
GET_QUANTUM_PRODUCTION_ENDPOINT_v2 = \
|
|
70
|
+
lambda location: f"https://{location}-v2.quantum.azure.com/"
|
|
66
71
|
GET_QUANTUM_CANARY_ENDPOINT = \
|
|
67
72
|
lambda location: f"https://{location or 'eastus2euap'}.quantum.azure.com/"
|
|
68
73
|
GET_QUANTUM_DOGFOOD_ENDPOINT = \
|
|
69
74
|
lambda location: f"https://{location}.quantum-test.azure.com/"
|
|
75
|
+
GET_QUANTUM_DOGFOOD_ENDPOINT_v2 = \
|
|
76
|
+
lambda location: f"https://{location}-v2.quantum-test.azure.com/"
|
|
70
77
|
|
|
71
78
|
ARM_PRODUCTION_ENDPOINT = "https://management.azure.com/"
|
|
72
79
|
ARM_DOGFOOD_ENDPOINT = "https://api-dogfood.resources.windows-int.net/"
|
|
@@ -93,3 +100,65 @@ class ConnectionConstants:
|
|
|
93
100
|
GUID_REGEX_PATTERN = (
|
|
94
101
|
r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
|
|
95
102
|
)
|
|
103
|
+
|
|
104
|
+
VALID_WORKSPACE_NAME_PATTERN = r"^[a-zA-Z0-9]+(-*[a-zA-Z0-9])*$"
|
|
105
|
+
|
|
106
|
+
VALID_AZURE_REGIONS = {
|
|
107
|
+
"australiacentral",
|
|
108
|
+
"australiacentral2",
|
|
109
|
+
"australiaeast",
|
|
110
|
+
"australiasoutheast",
|
|
111
|
+
"austriaeast",
|
|
112
|
+
"belgiumcentral",
|
|
113
|
+
"brazilsouth",
|
|
114
|
+
"brazilsoutheast",
|
|
115
|
+
"canadacentral",
|
|
116
|
+
"canadaeast",
|
|
117
|
+
"centralindia",
|
|
118
|
+
"centralus",
|
|
119
|
+
"centraluseuap",
|
|
120
|
+
"chilecentral",
|
|
121
|
+
"eastasia",
|
|
122
|
+
"eastus",
|
|
123
|
+
"eastus2",
|
|
124
|
+
"eastus2euap",
|
|
125
|
+
"francecentral",
|
|
126
|
+
"francesouth",
|
|
127
|
+
"germanynorth",
|
|
128
|
+
"germanywestcentral",
|
|
129
|
+
"indonesiacentral",
|
|
130
|
+
"israelcentral",
|
|
131
|
+
"italynorth",
|
|
132
|
+
"japaneast",
|
|
133
|
+
"japanwest",
|
|
134
|
+
"koreacentral",
|
|
135
|
+
"koreasouth",
|
|
136
|
+
"malaysiawest",
|
|
137
|
+
"mexicocentral",
|
|
138
|
+
"newzealandnorth",
|
|
139
|
+
"northcentralus",
|
|
140
|
+
"northeurope",
|
|
141
|
+
"norwayeast",
|
|
142
|
+
"norwaywest",
|
|
143
|
+
"polandcentral",
|
|
144
|
+
"qatarcentral",
|
|
145
|
+
"southafricanorth",
|
|
146
|
+
"southafricawest",
|
|
147
|
+
"southcentralus",
|
|
148
|
+
"southindia",
|
|
149
|
+
"southeastasia",
|
|
150
|
+
"spaincentral",
|
|
151
|
+
"swedencentral",
|
|
152
|
+
"switzerlandnorth",
|
|
153
|
+
"switzerlandwest",
|
|
154
|
+
"uaecentral",
|
|
155
|
+
"uaenorth",
|
|
156
|
+
"uksouth",
|
|
157
|
+
"ukwest",
|
|
158
|
+
"westcentralus",
|
|
159
|
+
"westeurope",
|
|
160
|
+
"westindia",
|
|
161
|
+
"westus",
|
|
162
|
+
"westus2",
|
|
163
|
+
"westus3",
|
|
164
|
+
}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
##
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# Licensed under the MIT License.
|
|
4
|
+
##
|
|
5
|
+
"""
|
|
6
|
+
Module providing the WorkspaceMgmtClient class for managing workspace operations.
|
|
7
|
+
Created to do not add additional azure-mgmt-* dependencies that can conflict with existing ones.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import logging
|
|
11
|
+
from http import HTTPStatus
|
|
12
|
+
from typing import Any, Optional, cast
|
|
13
|
+
from azure.core import PipelineClient
|
|
14
|
+
from azure.core.credentials import TokenProvider
|
|
15
|
+
from azure.core.pipeline import policies
|
|
16
|
+
from azure.core.rest import HttpRequest
|
|
17
|
+
from azure.core.exceptions import HttpResponseError
|
|
18
|
+
from azure.quantum._workspace_connection_params import WorkspaceConnectionParams
|
|
19
|
+
from azure.quantum._constants import ConnectionConstants
|
|
20
|
+
from azure.quantum._client._configuration import VERSION
|
|
21
|
+
|
|
22
|
+
logger = logging.getLogger(__name__)
|
|
23
|
+
|
|
24
|
+
__all__ = ["WorkspaceMgmtClient"]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class WorkspaceMgmtClient():
|
|
28
|
+
"""
|
|
29
|
+
Client for Azure Quantum Workspace related ARM/ARG operations.
|
|
30
|
+
Uses PipelineClient under the hood which is standard for all Azure SDK clients,
|
|
31
|
+
see https://learn.microsoft.com/en-us/azure/developer/python/sdk/fundamentals/http-pipeline-retries.
|
|
32
|
+
|
|
33
|
+
:param credential:
|
|
34
|
+
The credential to use to connect to Azure services.
|
|
35
|
+
|
|
36
|
+
:param base_url:
|
|
37
|
+
The base URL for the ARM endpoint.
|
|
38
|
+
|
|
39
|
+
:param user_agent:
|
|
40
|
+
Add the specified value as a prefix to the HTTP User-Agent header.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
# Constants
|
|
44
|
+
DEFAULT_RETRY_TOTAL = 3
|
|
45
|
+
CONTENT_TYPE_JSON = "application/json"
|
|
46
|
+
CONNECT_DOC_LINK = "https://learn.microsoft.com/en-us/azure/quantum/how-to-connect-workspace"
|
|
47
|
+
CONNECT_DOC_MESSAGE = f"To find details on how to connect to your workspace, please see {CONNECT_DOC_LINK}."
|
|
48
|
+
|
|
49
|
+
def __init__(self, credential: TokenProvider, base_url: str, user_agent: Optional[str] = None) -> None:
|
|
50
|
+
"""
|
|
51
|
+
Initialize the WorkspaceMgmtClient.
|
|
52
|
+
|
|
53
|
+
:param credential:
|
|
54
|
+
The credential to use to connect to Azure services.
|
|
55
|
+
|
|
56
|
+
:param base_url:
|
|
57
|
+
The base URL for the ARM endpoint.
|
|
58
|
+
"""
|
|
59
|
+
self._credential = credential
|
|
60
|
+
self._base_url = base_url
|
|
61
|
+
self._policies = [
|
|
62
|
+
policies.RequestIdPolicy(),
|
|
63
|
+
policies.HeadersPolicy({
|
|
64
|
+
"Content-Type": self.CONTENT_TYPE_JSON,
|
|
65
|
+
"Accept": self.CONTENT_TYPE_JSON,
|
|
66
|
+
}),
|
|
67
|
+
policies.UserAgentPolicy(user_agent=user_agent, sdk_moniker="quantum/{}".format(VERSION)),
|
|
68
|
+
policies.RetryPolicy(retry_total=self.DEFAULT_RETRY_TOTAL),
|
|
69
|
+
policies.BearerTokenCredentialPolicy(self._credential, ConnectionConstants.ARM_CREDENTIAL_SCOPE),
|
|
70
|
+
]
|
|
71
|
+
self._client: PipelineClient = PipelineClient(base_url=cast(str, base_url), policies=self._policies)
|
|
72
|
+
|
|
73
|
+
def close(self) -> None:
|
|
74
|
+
self._client.close()
|
|
75
|
+
|
|
76
|
+
def __enter__(self) -> 'WorkspaceMgmtClient':
|
|
77
|
+
self._client.__enter__()
|
|
78
|
+
return self
|
|
79
|
+
|
|
80
|
+
def __exit__(self, *exc_details: Any) -> None:
|
|
81
|
+
self._client.__exit__(*exc_details)
|
|
82
|
+
|
|
83
|
+
def load_workspace_from_arg(self, connection_params: WorkspaceConnectionParams) -> None:
|
|
84
|
+
"""
|
|
85
|
+
Queries Azure Resource Graph to find a workspace by name and optionally location, resource group, subscription.
|
|
86
|
+
Provided workspace name, location, resource group, and subscription in connection params must be validated beforehand.
|
|
87
|
+
|
|
88
|
+
:param connection_params:
|
|
89
|
+
The workspace connection parameters to use and update.
|
|
90
|
+
"""
|
|
91
|
+
if not connection_params.workspace_name:
|
|
92
|
+
raise ValueError("Workspace name must be specified to try to load workspace details from ARG.")
|
|
93
|
+
|
|
94
|
+
query = f"""
|
|
95
|
+
Resources
|
|
96
|
+
| where type =~ 'microsoft.quantum/workspaces'
|
|
97
|
+
| where name =~ '{connection_params.workspace_name}'
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
if connection_params.resource_group:
|
|
101
|
+
query += f"\n | where resourceGroup =~ '{connection_params.resource_group}'"
|
|
102
|
+
|
|
103
|
+
if connection_params.location:
|
|
104
|
+
query += f"\n | where location =~ '{connection_params.location}'"
|
|
105
|
+
|
|
106
|
+
query += """
|
|
107
|
+
| extend endpointUri = tostring(properties.endpointUri)
|
|
108
|
+
| project name, subscriptionId, resourceGroup, location, endpointUri
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
request_body = {
|
|
112
|
+
"query": query
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if connection_params.subscription_id:
|
|
116
|
+
request_body["subscriptions"] = [connection_params.subscription_id]
|
|
117
|
+
|
|
118
|
+
# Create request to Azure Resource Graph API
|
|
119
|
+
request = HttpRequest(
|
|
120
|
+
method="POST",
|
|
121
|
+
url=self._client.format_url("/providers/Microsoft.ResourceGraph/resources"),
|
|
122
|
+
params={"api-version": ConnectionConstants.DEFAULT_ARG_API_VERSION},
|
|
123
|
+
json=request_body
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
try:
|
|
127
|
+
response = self._client.send_request(request)
|
|
128
|
+
response.raise_for_status()
|
|
129
|
+
result = response.json()
|
|
130
|
+
except Exception as e:
|
|
131
|
+
raise RuntimeError(
|
|
132
|
+
f"Could not load workspace details from Azure Resource Graph: {str(e)}.\n{self.CONNECT_DOC_MESSAGE}"
|
|
133
|
+
) from e
|
|
134
|
+
|
|
135
|
+
data = result.get('data', [])
|
|
136
|
+
|
|
137
|
+
if not data:
|
|
138
|
+
raise ValueError(f"No matching workspace found with name '{connection_params.workspace_name}'. {self.CONNECT_DOC_MESSAGE}")
|
|
139
|
+
|
|
140
|
+
if len(data) > 1:
|
|
141
|
+
raise ValueError(
|
|
142
|
+
f"Multiple Azure Quantum workspaces found with name '{connection_params.workspace_name}'. "
|
|
143
|
+
f"Please specify additional connection parameters. {self.CONNECT_DOC_MESSAGE}"
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
workspace_data = data[0]
|
|
147
|
+
|
|
148
|
+
connection_params.subscription_id = workspace_data.get('subscriptionId')
|
|
149
|
+
connection_params.resource_group = workspace_data.get('resourceGroup')
|
|
150
|
+
connection_params.location = workspace_data.get('location')
|
|
151
|
+
connection_params.quantum_endpoint = workspace_data.get('endpointUri')
|
|
152
|
+
|
|
153
|
+
logger.debug(
|
|
154
|
+
"Found workspace '%s' in subscription '%s', resource group '%s', location '%s', endpoint '%s'",
|
|
155
|
+
connection_params.workspace_name,
|
|
156
|
+
connection_params.subscription_id,
|
|
157
|
+
connection_params.resource_group,
|
|
158
|
+
connection_params.location,
|
|
159
|
+
connection_params.quantum_endpoint
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
# If one of the required parameters is missing, probably workspace in failed provisioning state
|
|
163
|
+
if not connection_params.is_complete():
|
|
164
|
+
raise ValueError(
|
|
165
|
+
f"Failed to retrieve complete workspace details for workspace '{connection_params.workspace_name}'. "
|
|
166
|
+
"Please check that workspace is in valid state."
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
def load_workspace_from_arm(self, connection_params: WorkspaceConnectionParams) -> None:
|
|
170
|
+
"""
|
|
171
|
+
Fetches the workspace resource from ARM and sets location and endpoint URI params.
|
|
172
|
+
Provided workspace name, resource group, and subscription in connection params must be validated beforehand.
|
|
173
|
+
|
|
174
|
+
:param connection_params:
|
|
175
|
+
The workspace connection parameters to use and update.
|
|
176
|
+
"""
|
|
177
|
+
if not all([connection_params.subscription_id, connection_params.resource_group, connection_params.workspace_name]):
|
|
178
|
+
raise ValueError("Missing required connection parameters to load workspace details from ARM.")
|
|
179
|
+
|
|
180
|
+
api_version = connection_params.api_version or ConnectionConstants.DEFAULT_WORKSPACE_API_VERSION
|
|
181
|
+
|
|
182
|
+
url = (
|
|
183
|
+
f"/subscriptions/{connection_params.subscription_id}"
|
|
184
|
+
f"/resourceGroups/{connection_params.resource_group}"
|
|
185
|
+
f"/providers/Microsoft.Quantum/workspaces/{connection_params.workspace_name}"
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
request = HttpRequest(
|
|
189
|
+
method="GET",
|
|
190
|
+
url=self._client.format_url(url),
|
|
191
|
+
params={"api-version": api_version},
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
try:
|
|
195
|
+
response = self._client.send_request(request)
|
|
196
|
+
response.raise_for_status()
|
|
197
|
+
workspace_data = response.json()
|
|
198
|
+
except HttpResponseError as e:
|
|
199
|
+
if e.status_code == HTTPStatus.NOT_FOUND:
|
|
200
|
+
raise ValueError(
|
|
201
|
+
f"Azure Quantum workspace '{connection_params.workspace_name}' "
|
|
202
|
+
f"not found in resource group '{connection_params.resource_group}' "
|
|
203
|
+
f"and subscription '{connection_params.subscription_id}'. "
|
|
204
|
+
f"{self.CONNECT_DOC_MESSAGE}"
|
|
205
|
+
) from e
|
|
206
|
+
# Re-raise for other HTTP errors
|
|
207
|
+
raise
|
|
208
|
+
except Exception as e:
|
|
209
|
+
raise RuntimeError(
|
|
210
|
+
f"Could not load workspace details from ARM: {str(e)}.\n{self.CONNECT_DOC_MESSAGE}"
|
|
211
|
+
) from e
|
|
212
|
+
|
|
213
|
+
# Extract and apply location
|
|
214
|
+
location = workspace_data.get("location")
|
|
215
|
+
if location:
|
|
216
|
+
connection_params.location = location
|
|
217
|
+
logger.debug(
|
|
218
|
+
"Updated workspace location from ARM: %s",
|
|
219
|
+
location
|
|
220
|
+
)
|
|
221
|
+
else:
|
|
222
|
+
raise ValueError(
|
|
223
|
+
f"Failed to retrieve location for workspace '{connection_params.workspace_name}'. "
|
|
224
|
+
f"Please check that workspace is in valid state."
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
# Extract and apply endpoint URI from properties
|
|
228
|
+
properties = workspace_data.get("properties", {})
|
|
229
|
+
endpoint_uri = properties.get("endpointUri")
|
|
230
|
+
if endpoint_uri:
|
|
231
|
+
connection_params.quantum_endpoint = endpoint_uri
|
|
232
|
+
logger.debug(
|
|
233
|
+
"Updated workspace endpoint from ARM: %s", connection_params.quantum_endpoint
|
|
234
|
+
)
|
|
235
|
+
else:
|
|
236
|
+
raise ValueError(
|
|
237
|
+
f"Failed to retrieve endpoint uri for workspace '{connection_params.workspace_name}'. "
|
|
238
|
+
f"Please check that workspace is in valid state."
|
|
239
|
+
)
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_workspace_connection_params.py
RENAMED
|
@@ -20,6 +20,8 @@ from azure.quantum._constants import (
|
|
|
20
20
|
EnvironmentVariables,
|
|
21
21
|
ConnectionConstants,
|
|
22
22
|
GUID_REGEX_PATTERN,
|
|
23
|
+
VALID_WORKSPACE_NAME_PATTERN,
|
|
24
|
+
VALID_AZURE_REGIONS,
|
|
23
25
|
)
|
|
24
26
|
|
|
25
27
|
class WorkspaceConnectionParams:
|
|
@@ -46,9 +48,19 @@ class WorkspaceConnectionParams:
|
|
|
46
48
|
ResourceGroupName=(?P<resource_group>[^\s;]+);
|
|
47
49
|
WorkspaceName=(?P<workspace_name>[^\s;]+);
|
|
48
50
|
ApiKey=(?P<api_key>[^\s;]+);
|
|
49
|
-
QuantumEndpoint=(?P<quantum_endpoint>https://(?P<location>[
|
|
51
|
+
QuantumEndpoint=(?P<quantum_endpoint>https://(?P<location>[a-zA-Z0-9]+)(?:-v2)?.quantum(?:-test)?.azure.com/);
|
|
50
52
|
""",
|
|
51
53
|
re.VERBOSE | re.IGNORECASE)
|
|
54
|
+
|
|
55
|
+
WORKSPACE_NOT_FULLY_SPECIFIED_MSG = """
|
|
56
|
+
Azure Quantum workspace not fully specified.
|
|
57
|
+
Please specify one of the following:
|
|
58
|
+
1) A valid resource ID.
|
|
59
|
+
2) A valid combination of subscription ID,
|
|
60
|
+
resource group name, and workspace name.
|
|
61
|
+
3) A valid connection string (via Workspace.from_connection_string()).
|
|
62
|
+
4) A valid workspace name.
|
|
63
|
+
"""
|
|
52
64
|
|
|
53
65
|
def __init__(
|
|
54
66
|
self,
|
|
@@ -85,6 +97,8 @@ class WorkspaceConnectionParams:
|
|
|
85
97
|
self.client_id = None
|
|
86
98
|
self.tenant_id = None
|
|
87
99
|
self.api_version = None
|
|
100
|
+
# Track if connection string was used
|
|
101
|
+
self._used_connection_string = False
|
|
88
102
|
# callback to create a new client if needed
|
|
89
103
|
# for example, when changing the user agent
|
|
90
104
|
self.on_new_client_request = on_new_client_request
|
|
@@ -108,6 +122,81 @@ class WorkspaceConnectionParams:
|
|
|
108
122
|
workspace_name=workspace_name,
|
|
109
123
|
)
|
|
110
124
|
self.apply_resource_id(resource_id=resource_id)
|
|
125
|
+
# Validate connection parameters if they are set
|
|
126
|
+
self._validate_connection_params()
|
|
127
|
+
|
|
128
|
+
def _validate_connection_params(self):
|
|
129
|
+
self._validate_subscription_id()
|
|
130
|
+
self._validate_resource_group()
|
|
131
|
+
self._validate_workspace_name()
|
|
132
|
+
self._validate_location()
|
|
133
|
+
|
|
134
|
+
def _validate_subscription_id(self):
|
|
135
|
+
# Validate that subscription id is a valid GUID
|
|
136
|
+
if self.subscription_id is not None:
|
|
137
|
+
if not isinstance(self.subscription_id, str):
|
|
138
|
+
raise ValueError("Subscription ID must be a string.")
|
|
139
|
+
if not re.match(f"^{GUID_REGEX_PATTERN}$", self.subscription_id, re.IGNORECASE):
|
|
140
|
+
raise ValueError("Subscription ID must be a valid GUID.")
|
|
141
|
+
|
|
142
|
+
def _validate_resource_group(self):
|
|
143
|
+
# Validate resource group, see https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/resource-name-rules#microsoftresources
|
|
144
|
+
# Length 1-90, valid characters: alphanumeric, underscore, parentheses, hyphen, period (except at end), and Unicode characters:
|
|
145
|
+
# Uppercase Letter - Signified by the Unicode designation "Lu" (letter, uppercase);
|
|
146
|
+
# Lowercase Letter - Signified by the Unicode designation "Ll" (letter, lowercase);
|
|
147
|
+
# Titlecase Letter - Signified by the Unicode designation "Lt" (letter, titlecase);
|
|
148
|
+
# Modifier Letter - Signified by the Unicode designation "Lm" (letter, modifier);
|
|
149
|
+
# Other Letter - Signified by the Unicode designation "Lo" (letter, other);
|
|
150
|
+
# Decimal Digit Number - Signified by the Unicode designation "Nd" (number, decimal digit).
|
|
151
|
+
if self.resource_group is not None:
|
|
152
|
+
if not isinstance(self.resource_group, str):
|
|
153
|
+
raise ValueError("Resource group name must be a string.")
|
|
154
|
+
|
|
155
|
+
if len(self.resource_group) < 1 or len(self.resource_group) > 90:
|
|
156
|
+
raise ValueError(
|
|
157
|
+
"Resource group name must be between 1 and 90 characters long."
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
err_msg = "Resource group name can only include alphanumeric, underscore, parentheses, hyphen, period (except at end), and Unicode characters that match the allowed characters."
|
|
161
|
+
if self.resource_group.endswith('.'):
|
|
162
|
+
raise ValueError(err_msg)
|
|
163
|
+
|
|
164
|
+
import unicodedata
|
|
165
|
+
for i, char in enumerate(self.resource_group):
|
|
166
|
+
category = unicodedata.category(char)
|
|
167
|
+
if not (
|
|
168
|
+
char in ('_', '(', ')', '-', '.') or
|
|
169
|
+
category in ('Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nd')
|
|
170
|
+
):
|
|
171
|
+
raise ValueError(err_msg)
|
|
172
|
+
|
|
173
|
+
def _validate_workspace_name(self):
|
|
174
|
+
# Validate workspace name, see https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/resource-name-rules#microsoftquantum
|
|
175
|
+
# Length 2-54, valid characters: alphanumerics (a-zA-Z0-9) and hyphens, can't start or end with hyphen
|
|
176
|
+
if self.workspace_name is not None:
|
|
177
|
+
if not isinstance(self.workspace_name, str):
|
|
178
|
+
raise ValueError("Workspace name must be a string.")
|
|
179
|
+
|
|
180
|
+
if len(self.workspace_name) < 2 or len(self.workspace_name) > 54:
|
|
181
|
+
raise ValueError(
|
|
182
|
+
"Workspace name must be between 2 and 54 characters long."
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
err_msg = "Workspace name can only include alphanumerics (a-zA-Z0-9) and hyphens, and cannot start or end with hyphen."
|
|
186
|
+
|
|
187
|
+
if self.workspace_name.startswith('-') or self.workspace_name.endswith('-'):
|
|
188
|
+
raise ValueError(err_msg)
|
|
189
|
+
|
|
190
|
+
if not re.match(VALID_WORKSPACE_NAME_PATTERN, self.workspace_name):
|
|
191
|
+
raise ValueError(err_msg)
|
|
192
|
+
|
|
193
|
+
def _validate_location(self):
|
|
194
|
+
# Validate that location is one of the Azure regions https://learn.microsoft.com/en-us/azure/reliability/regions-list
|
|
195
|
+
if self.location is not None:
|
|
196
|
+
if not isinstance(self.location, str):
|
|
197
|
+
raise ValueError("Location must be a string.")
|
|
198
|
+
if self.location not in VALID_AZURE_REGIONS:
|
|
199
|
+
raise ValueError(f"Location must be one of the Azure regions listed in https://learn.microsoft.com/en-us/azure/reliability/regions-list.")
|
|
111
200
|
|
|
112
201
|
@property
|
|
113
202
|
def location(self):
|
|
@@ -142,19 +231,8 @@ class WorkspaceConnectionParams:
|
|
|
142
231
|
def quantum_endpoint(self):
|
|
143
232
|
"""
|
|
144
233
|
The Azure Quantum data plane endpoint.
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if self._quantum_endpoint:
|
|
148
|
-
return self._quantum_endpoint
|
|
149
|
-
if not self.location:
|
|
150
|
-
raise ValueError("Location not specified")
|
|
151
|
-
if self.environment is EnvironmentKind.PRODUCTION:
|
|
152
|
-
return ConnectionConstants.GET_QUANTUM_PRODUCTION_ENDPOINT(self.location)
|
|
153
|
-
if self.environment is EnvironmentKind.CANARY:
|
|
154
|
-
return ConnectionConstants.GET_QUANTUM_CANARY_ENDPOINT(self.location)
|
|
155
|
-
if self.environment is EnvironmentKind.DOGFOOD:
|
|
156
|
-
return ConnectionConstants.GET_QUANTUM_DOGFOOD_ENDPOINT(self.location)
|
|
157
|
-
raise ValueError(f"Unknown environment `{self.environment}`.")
|
|
234
|
+
"""
|
|
235
|
+
return self._quantum_endpoint
|
|
158
236
|
|
|
159
237
|
@quantum_endpoint.setter
|
|
160
238
|
def quantum_endpoint(self, value: str):
|
|
@@ -235,6 +313,7 @@ class WorkspaceConnectionParams:
|
|
|
235
313
|
if not match:
|
|
236
314
|
raise ValueError("Invalid connection string")
|
|
237
315
|
self._merge_re_match(match)
|
|
316
|
+
self._used_connection_string = True
|
|
238
317
|
|
|
239
318
|
def merge(
|
|
240
319
|
self,
|
|
@@ -450,6 +529,32 @@ class WorkspaceConnectionParams:
|
|
|
450
529
|
full_user_agent = (f"{app_id} {full_user_agent}"
|
|
451
530
|
if full_user_agent else app_id)
|
|
452
531
|
return full_user_agent
|
|
532
|
+
|
|
533
|
+
def have_enough_for_discovery(self) -> bool:
|
|
534
|
+
"""
|
|
535
|
+
Returns true if we have enough parameters
|
|
536
|
+
to try to find the Azure Quantum Workspace.
|
|
537
|
+
"""
|
|
538
|
+
return (self.workspace_name
|
|
539
|
+
and self.get_credential_or_default())
|
|
540
|
+
|
|
541
|
+
def assert_have_enough_for_discovery(self):
|
|
542
|
+
"""
|
|
543
|
+
Raises ValueError if we don't have enough parameters
|
|
544
|
+
to try to find the Azure Quantum Workspace.
|
|
545
|
+
"""
|
|
546
|
+
if not self.have_enough_for_discovery():
|
|
547
|
+
raise ValueError(self.WORKSPACE_NOT_FULLY_SPECIFIED_MSG)
|
|
548
|
+
|
|
549
|
+
def can_build_resource_id(self) -> bool:
|
|
550
|
+
"""
|
|
551
|
+
Returns true if we have all necessary parameters
|
|
552
|
+
to identify the Azure Quantum Workspace resource.
|
|
553
|
+
"""
|
|
554
|
+
return (self.subscription_id
|
|
555
|
+
and self.resource_group
|
|
556
|
+
and self.workspace_name
|
|
557
|
+
and self.get_credential_or_default())
|
|
453
558
|
|
|
454
559
|
def is_complete(self) -> bool:
|
|
455
560
|
"""
|
|
@@ -460,6 +565,7 @@ class WorkspaceConnectionParams:
|
|
|
460
565
|
and self.subscription_id
|
|
461
566
|
and self.resource_group
|
|
462
567
|
and self.workspace_name
|
|
568
|
+
and self.quantum_endpoint
|
|
463
569
|
and self.get_credential_or_default())
|
|
464
570
|
|
|
465
571
|
def assert_complete(self):
|
|
@@ -468,15 +574,7 @@ class WorkspaceConnectionParams:
|
|
|
468
574
|
to connect to the Azure Quantum Workspace.
|
|
469
575
|
"""
|
|
470
576
|
if not self.is_complete():
|
|
471
|
-
raise ValueError(
|
|
472
|
-
"""
|
|
473
|
-
Azure Quantum workspace not fully specified.
|
|
474
|
-
Please specify one of the following:
|
|
475
|
-
1) A valid combination of location and resource ID.
|
|
476
|
-
2) A valid combination of location, subscription ID,
|
|
477
|
-
resource group name, and workspace name.
|
|
478
|
-
3) A valid connection string (via Workspace.from_connection_string()).
|
|
479
|
-
""")
|
|
577
|
+
raise ValueError(self.WORKSPACE_NOT_FULLY_SPECIFIED_MSG)
|
|
480
578
|
|
|
481
579
|
def default_from_env_vars(self) -> WorkspaceConnectionParams:
|
|
482
580
|
"""
|
|
@@ -512,10 +610,13 @@ class WorkspaceConnectionParams:
|
|
|
512
610
|
or not self.workspace_name
|
|
513
611
|
or not self.credential
|
|
514
612
|
):
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
613
|
+
env_connection_string = os.environ.get(EnvironmentVariables.CONNECTION_STRING)
|
|
614
|
+
if env_connection_string:
|
|
615
|
+
self._merge_connection_params(
|
|
616
|
+
connection_params=WorkspaceConnectionParams(
|
|
617
|
+
connection_string=env_connection_string),
|
|
618
|
+
merge_default_mode=True)
|
|
619
|
+
self._used_connection_string = True
|
|
519
620
|
return self
|
|
520
621
|
|
|
521
622
|
@classmethod
|
|
@@ -21,6 +21,7 @@ from typing import (
|
|
|
21
21
|
Tuple,
|
|
22
22
|
Union,
|
|
23
23
|
)
|
|
24
|
+
from typing_extensions import Self
|
|
24
25
|
from azure.core.paging import ItemPaged
|
|
25
26
|
from azure.quantum._client import ServicesClient
|
|
26
27
|
from azure.quantum._client.models import JobDetails, ItemDetails, SessionDetails
|
|
@@ -49,6 +50,7 @@ from azure.quantum.storage import (
|
|
|
49
50
|
get_container_uri,
|
|
50
51
|
ContainerClient
|
|
51
52
|
)
|
|
53
|
+
from azure.quantum._mgmt_client import WorkspaceMgmtClient
|
|
52
54
|
if TYPE_CHECKING:
|
|
53
55
|
from azure.quantum.target import Target
|
|
54
56
|
|
|
@@ -62,10 +64,11 @@ class Workspace:
|
|
|
62
64
|
"""
|
|
63
65
|
Represents an Azure Quantum workspace.
|
|
64
66
|
|
|
65
|
-
When creating a Workspace object, callers have
|
|
67
|
+
When creating a Workspace object, callers have several options for
|
|
66
68
|
identifying the Azure Quantum workspace (in order of precedence):
|
|
67
|
-
1. specify a valid
|
|
68
|
-
2. specify a valid
|
|
69
|
+
1. specify a valid resource ID; or
|
|
70
|
+
2. specify a valid subscription ID, resource group, and workspace name; or
|
|
71
|
+
3. specify a valid workspace name.
|
|
69
72
|
|
|
70
73
|
You can also use a connection string to specify the connection parameters
|
|
71
74
|
to an Azure Quantum Workspace by calling
|
|
@@ -110,6 +113,12 @@ class Workspace:
|
|
|
110
113
|
Add the specified value as a prefix to the HTTP User-Agent header
|
|
111
114
|
when communicating to the Azure Quantum service.
|
|
112
115
|
"""
|
|
116
|
+
|
|
117
|
+
# Internal parameter names
|
|
118
|
+
_FROM_CONNECTION_STRING_PARAM = '_from_connection_string'
|
|
119
|
+
_QUANTUM_ENDPOINT_PARAM = '_quantum_endpoint'
|
|
120
|
+
_MGMT_CLIENT_PARAM = '_mgmt_client'
|
|
121
|
+
|
|
113
122
|
def __init__(
|
|
114
123
|
self,
|
|
115
124
|
subscription_id: Optional[str] = None,
|
|
@@ -122,6 +131,14 @@ class Workspace:
|
|
|
122
131
|
user_agent: Optional[str] = None,
|
|
123
132
|
**kwargs: Any,
|
|
124
133
|
) -> None:
|
|
134
|
+
# Extract internal params before passing kwargs to WorkspaceConnectionParams
|
|
135
|
+
# Param to track whether the workspace was created from a connection string
|
|
136
|
+
from_connection_string = kwargs.pop(Workspace._FROM_CONNECTION_STRING_PARAM, False)
|
|
137
|
+
# In case from connection string, quantum_endpoint must be passed
|
|
138
|
+
quantum_endpoint = kwargs.pop(Workspace._QUANTUM_ENDPOINT_PARAM, None)
|
|
139
|
+
# Params to pass a mock in tests
|
|
140
|
+
self._mgmt_client = kwargs.pop(Workspace._MGMT_CLIENT_PARAM, None)
|
|
141
|
+
|
|
125
142
|
connection_params = WorkspaceConnectionParams(
|
|
126
143
|
location=location,
|
|
127
144
|
subscription_id=subscription_id,
|
|
@@ -129,13 +146,14 @@ class Workspace:
|
|
|
129
146
|
workspace_name=name,
|
|
130
147
|
credential=credential,
|
|
131
148
|
resource_id=resource_id,
|
|
149
|
+
quantum_endpoint=quantum_endpoint,
|
|
132
150
|
user_agent=user_agent,
|
|
133
151
|
**kwargs
|
|
134
152
|
).default_from_env_vars()
|
|
135
153
|
|
|
136
154
|
logger.info("Using %s environment.", connection_params.environment)
|
|
137
155
|
|
|
138
|
-
connection_params.
|
|
156
|
+
connection_params.assert_have_enough_for_discovery()
|
|
139
157
|
|
|
140
158
|
connection_params.on_new_client_request = self._on_new_client_request
|
|
141
159
|
|
|
@@ -145,6 +163,32 @@ class Workspace:
|
|
|
145
163
|
self._resource_group = connection_params.resource_group
|
|
146
164
|
self._workspace_name = connection_params.workspace_name
|
|
147
165
|
|
|
166
|
+
if not self._mgmt_client:
|
|
167
|
+
credential = connection_params.get_credential_or_default()
|
|
168
|
+
self._mgmt_client = WorkspaceMgmtClient(
|
|
169
|
+
credential=credential,
|
|
170
|
+
base_url=connection_params.arm_endpoint,
|
|
171
|
+
user_agent=connection_params.get_full_user_agent(),
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
# pylint: disable=protected-access
|
|
175
|
+
using_connection_string = (
|
|
176
|
+
from_connection_string
|
|
177
|
+
or connection_params._used_connection_string
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
# Populate workspace details from ARG if not using connection string and
|
|
181
|
+
# name is provided but missing subscription and/or resource group
|
|
182
|
+
if not using_connection_string \
|
|
183
|
+
and not connection_params.can_build_resource_id():
|
|
184
|
+
self._mgmt_client.load_workspace_from_arg(connection_params)
|
|
185
|
+
|
|
186
|
+
# Populate workspace details from ARM if not using connection string and not loaded from ARG
|
|
187
|
+
if not using_connection_string and not connection_params.is_complete():
|
|
188
|
+
self._mgmt_client.load_workspace_from_arm(connection_params)
|
|
189
|
+
|
|
190
|
+
connection_params.assert_complete()
|
|
191
|
+
|
|
148
192
|
# Create QuantumClient
|
|
149
193
|
self._client = self._create_client()
|
|
150
194
|
|
|
@@ -277,6 +321,8 @@ class Workspace:
|
|
|
277
321
|
:rtype: Workspace
|
|
278
322
|
"""
|
|
279
323
|
connection_params = WorkspaceConnectionParams(connection_string=connection_string)
|
|
324
|
+
kwargs[cls._FROM_CONNECTION_STRING_PARAM] = True
|
|
325
|
+
kwargs[cls._QUANTUM_ENDPOINT_PARAM] = connection_params.quantum_endpoint
|
|
280
326
|
return cls(
|
|
281
327
|
subscription_id=connection_params.subscription_id,
|
|
282
328
|
resource_group=connection_params.resource_group,
|
|
@@ -1023,4 +1069,16 @@ class Workspace:
|
|
|
1023
1069
|
return orderby
|
|
1024
1070
|
else:
|
|
1025
1071
|
return None
|
|
1026
|
-
|
|
1072
|
+
|
|
1073
|
+
def close(self) -> None:
|
|
1074
|
+
self._mgmt_client.close()
|
|
1075
|
+
self._client.close()
|
|
1076
|
+
|
|
1077
|
+
def __enter__(self) -> Self:
|
|
1078
|
+
self._client.__enter__()
|
|
1079
|
+
self._mgmt_client.__enter__()
|
|
1080
|
+
return self
|
|
1081
|
+
|
|
1082
|
+
def __exit__(self, *exc_details: Any) -> None:
|
|
1083
|
+
self._mgmt_client.__exit__(*exc_details)
|
|
1084
|
+
self._client.__exit__(*exc_details)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: azure-quantum
|
|
3
|
-
Version: 3.5.
|
|
3
|
+
Version: 3.5.1.dev0
|
|
4
4
|
Summary: Python client for Azure Quantum
|
|
5
5
|
Home-page: https://github.com/microsoft/azure-quantum-python
|
|
6
6
|
Author: Microsoft
|
|
@@ -79,15 +79,14 @@ To get started, visit the following Quickstart guides:
|
|
|
79
79
|
|
|
80
80
|
## General usage ##
|
|
81
81
|
|
|
82
|
-
To connect to your Azure Quantum Workspace, go to the [Azure Portal](https://portal.azure.com), navigate to your Workspace and copy-paste the resource ID
|
|
82
|
+
To connect to your Azure Quantum Workspace, go to the [Azure Portal](https://portal.azure.com), navigate to your Workspace and copy-paste the resource ID into the code snippet below.
|
|
83
83
|
|
|
84
84
|
```python
|
|
85
85
|
from azure.quantum import Workspace
|
|
86
86
|
|
|
87
|
-
# Enter your Workspace
|
|
87
|
+
# Enter your Workspace resource ID below
|
|
88
88
|
workspace = Workspace(
|
|
89
|
-
resource_id=""
|
|
90
|
-
location=""
|
|
89
|
+
resource_id=""
|
|
91
90
|
)
|
|
92
91
|
```
|
|
93
92
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/_configuration.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/_serialization.py
RENAMED
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/models/__init__.py
RENAMED
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/models/_enums.py
RENAMED
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/models/_models.py
RENAMED
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/models/_patch.py
RENAMED
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/operations/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/_client/operations/_patch.py
RENAMED
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/argument_types/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/cirq/targets/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/cirq/targets/quantinuum.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/job/workspace_item_factory.py
RENAMED
|
File without changes
|
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/qiskit/backends/__init__.py
RENAMED
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/qiskit/backends/_qiskit_ionq.py
RENAMED
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/qiskit/backends/backend.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/qiskit/backends/quantinuum.py
RENAMED
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/qiskit/backends/rigetti.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/target/pasqal/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/target/rigetti/__init__.py
RENAMED
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/target/rigetti/result.py
RENAMED
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/target/rigetti/target.py
RENAMED
|
File without changes
|
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure/quantum/target/target_factory.py
RENAMED
|
File without changes
|
{azure_quantum-3.5.0.dev0 → azure_quantum-3.5.1.dev0}/azure_quantum.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|