openquantum-sdk 0.3.3__tar.gz → 0.3.7__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.
Files changed (32) hide show
  1. {openquantum_sdk-0.3.3/openquantum_sdk.egg-info → openquantum_sdk-0.3.7}/PKG-INFO +24 -8
  2. openquantum_sdk-0.3.3/PKG-INFO → openquantum_sdk-0.3.7/README.md +19 -18
  3. {openquantum_sdk-0.3.3 → openquantum_sdk-0.3.7}/openquantum_sdk/__init__.py +1 -1
  4. {openquantum_sdk-0.3.3 → openquantum_sdk-0.3.7}/openquantum_sdk/__main__.py +3 -1
  5. {openquantum_sdk-0.3.3 → openquantum_sdk-0.3.7}/openquantum_sdk/auth.py +58 -5
  6. openquantum_sdk-0.3.7/openquantum_sdk/backends.py +688 -0
  7. {openquantum_sdk-0.3.3 → openquantum_sdk-0.3.7}/openquantum_sdk/clients.py +337 -26
  8. openquantum_sdk-0.3.7/openquantum_sdk/enums.py +40 -0
  9. openquantum_sdk-0.3.7/openquantum_sdk/models.py +469 -0
  10. {openquantum_sdk-0.3.3 → openquantum_sdk-0.3.7}/openquantum_sdk/qiskit/__init__.py +3 -7
  11. openquantum_sdk-0.3.7/openquantum_sdk/utils.py +71 -0
  12. openquantum_sdk-0.3.3/README.md → openquantum_sdk-0.3.7/openquantum_sdk.egg-info/PKG-INFO +34 -7
  13. {openquantum_sdk-0.3.3 → openquantum_sdk-0.3.7}/openquantum_sdk.egg-info/SOURCES.txt +3 -1
  14. openquantum_sdk-0.3.7/openquantum_sdk.egg-info/requires.txt +7 -0
  15. {openquantum_sdk-0.3.3 → openquantum_sdk-0.3.7}/pyproject.toml +5 -1
  16. openquantum_sdk-0.3.7/tests/test_backends.py +240 -0
  17. {openquantum_sdk-0.3.3 → openquantum_sdk-0.3.7}/tests/test_clients.py +14 -4
  18. openquantum_sdk-0.3.7/tests/test_clients_plan_priority.py +162 -0
  19. openquantum_sdk-0.3.3/openquantum_sdk/enums.py +0 -16
  20. openquantum_sdk-0.3.3/openquantum_sdk/models.py +0 -223
  21. openquantum_sdk-0.3.3/openquantum_sdk/utils.py +0 -24
  22. openquantum_sdk-0.3.3/openquantum_sdk.egg-info/requires.txt +0 -1
  23. openquantum_sdk-0.3.3/tests/conftest.py +0 -40
  24. {openquantum_sdk-0.3.3 → openquantum_sdk-0.3.7}/MANIFEST.in +0 -0
  25. {openquantum_sdk-0.3.3 → openquantum_sdk-0.3.7}/openquantum_sdk.egg-info/dependency_links.txt +0 -0
  26. {openquantum_sdk-0.3.3 → openquantum_sdk-0.3.7}/openquantum_sdk.egg-info/entry_points.txt +0 -0
  27. {openquantum_sdk-0.3.3 → openquantum_sdk-0.3.7}/openquantum_sdk.egg-info/top_level.txt +0 -0
  28. {openquantum_sdk-0.3.3 → openquantum_sdk-0.3.7}/requirements-dev.txt +0 -0
  29. {openquantum_sdk-0.3.3 → openquantum_sdk-0.3.7}/requirements.txt +0 -0
  30. {openquantum_sdk-0.3.3 → openquantum_sdk-0.3.7}/setup.cfg +0 -0
  31. {openquantum_sdk-0.3.3 → openquantum_sdk-0.3.7}/tests/__init__.py +0 -0
  32. {openquantum_sdk-0.3.3 → openquantum_sdk-0.3.7}/tests/test_qiskit_wrappers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openquantum-sdk
3
- Version: 0.3.3
3
+ Version: 0.3.7
4
4
  Summary: Python SDK for Open Quantum
5
5
  Classifier: Programming Language :: Python :: 3
6
6
  Classifier: License :: OSI Approved :: Apache Software License
@@ -8,6 +8,10 @@ Classifier: Operating System :: OS Independent
8
8
  Requires-Python: >=3.8
9
9
  Description-Content-Type: text/markdown
10
10
  Requires-Dist: requests>=2.25.0
11
+ Provides-Extra: qiskit
12
+ Requires-Dist: openquantum-sdk-qiskit>=0.2.4; extra == "qiskit"
13
+ Provides-Extra: pennylane
14
+ Requires-Dist: openquantum-sdk-pennylane>=0.1.0; extra == "pennylane"
11
15
 
12
16
  # Open Quantum Python SDK
13
17
 
@@ -58,6 +62,13 @@ auth = ClientCredentialsAuth(
58
62
  )
59
63
  ```
60
64
 
65
+ ### Option 3: Environment Variables
66
+
67
+ ```bash
68
+ export OPENQUANTUM_CLIENT_ID=s_...
69
+ export OPENQUANTUM_CLIENT_SECRET=e460c8...
70
+ ```
71
+
61
72
  ## Quickstart: One-Call Submission (Recommended)
62
73
 
63
74
  ```python
@@ -93,7 +104,7 @@ try:
93
104
  # 3. Define config
94
105
  config = JobSubmissionConfig(
95
106
  organization_id=org_id,
96
- backend_class_id="rigetti:ankaa-3",
107
+ backend_class_id="iqm:emerald",
97
108
  name="Bell State SDK Quickstart",
98
109
  job_subcategory_id="fin:port", # Finance Portfolio Optimization
99
110
  shots=100,
@@ -155,7 +166,7 @@ try:
155
166
  print(f" - {bc.name} [{bc.type}] — {bc.short_code or bc.id}")
156
167
 
157
168
  # 2. Choose IDs
158
- MY_BACKEND = "rigetti:ankaa-3"
169
+ MY_BACKEND = "iqm:emerald"
159
170
  MY_SUBCATEGORY = "fin:port"
160
171
 
161
172
  # 3. Upload
@@ -290,6 +301,7 @@ finally:
290
301
  | `list_user_organizations(limit=20, cursor=...)` | `PaginatedOrganizations` | Your orgs |
291
302
  | `list_providers(limit=20, cursor=...)` | `PaginatedProviders` | All backend providers |
292
303
  | `list_backend_classes(provider_id=None, limit=20, cursor=...)` | `PaginatedBackendClasses` | Available backends |
304
+ | `get_credit_balance(organization_id: str)` | `CreditBalanceRead` | Get current credit balance |
293
305
 
294
306
  ## Data Models
295
307
 
@@ -345,7 +357,7 @@ from openquantum_sdk.enums import ExecutionPlanType, QueuePriorityType
345
357
  ```bash
346
358
  python -m openquantum_sdk --sdk-key ./key.json \
347
359
  --input bell.qasm \
348
- --backend "ionq:aria-1" \
360
+ --backend "iqm:emerald" \
349
361
  --name "CLI Circuit" \
350
362
  --subcategory "mathematics:linear-systems" \
351
363
  --shots 100 \
@@ -359,11 +371,12 @@ Automatically **downloads and pretty-prints JSON output**.
359
371
  ### Backends
360
372
  | Provider | Backend | Short Code |
361
373
  | ------ | ------ | ------ |
362
- | IonQ | Aria-1 | `ionq:aria-1` |
374
+ | AQT | Ibex-Q1 | `aqt:ibex-q1` |
375
+ | IonQ | Forte Enterprise | `ionq:forte-ent` |
363
376
  | IonQ | Forte-1 | `ionq:forte-1` |
364
377
  | IQM | Emerald | `iqm:emerald` |
365
378
  | IQM | Garnet | `iqm:garnet` |
366
- | Rigetti | Ankaa-3 | `rigetti:ankaa-3` |
379
+ | Rigetti | Cepheus-1-108Q | `rigetti:cepheus-108q`|
367
380
 
368
381
  *Note: This list may be modified as backends are added or removed from the platform. For the most up-to-date list, run the following code:*
369
382
 
@@ -431,5 +444,8 @@ for cat in cats:
431
444
  **Q: How do I get results as JSON?**
432
445
  **A:** Use `scheduler.download_job_output(job)` — returns parsed object.
433
446
 
434
- **Q: Why does auto mode fail on some QPUs?**
435
- **A:** `auto` only allows `PUBLIC` + `STANDARD`. Use explicit enums for private/instant access.
447
+ **Q: Why does auto mode fail on some QPUs?**
448
+ **A:** `"auto"` selects the cheapest plan and priority (`PUBLIC` + `STANDARD`). If a backend only offers private execution, pass `execution_plan="private"` explicitly. Similarly, use `queue_priority="priority"` or `"instant"` for higher-priority queue access.
449
+
450
+ **Q: Can I hide the public plan citation notice?**
451
+ **A:** Setting `OPENQUANTUM_HIDE_CITATION_NOTICE=true` will omit the citation notice from output.
@@ -1,14 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: openquantum-sdk
3
- Version: 0.3.3
4
- Summary: Python SDK for Open Quantum
5
- Classifier: Programming Language :: Python :: 3
6
- Classifier: License :: OSI Approved :: Apache Software License
7
- Classifier: Operating System :: OS Independent
8
- Requires-Python: >=3.8
9
- Description-Content-Type: text/markdown
10
- Requires-Dist: requests>=2.25.0
11
-
12
1
  # Open Quantum Python SDK
13
2
 
14
3
  A lightweight, modern Python SDK for the **Open Quantum Platform**.
@@ -58,6 +47,13 @@ auth = ClientCredentialsAuth(
58
47
  )
59
48
  ```
60
49
 
50
+ ### Option 3: Environment Variables
51
+
52
+ ```bash
53
+ export OPENQUANTUM_CLIENT_ID=s_...
54
+ export OPENQUANTUM_CLIENT_SECRET=e460c8...
55
+ ```
56
+
61
57
  ## Quickstart: One-Call Submission (Recommended)
62
58
 
63
59
  ```python
@@ -93,7 +89,7 @@ try:
93
89
  # 3. Define config
94
90
  config = JobSubmissionConfig(
95
91
  organization_id=org_id,
96
- backend_class_id="rigetti:ankaa-3",
92
+ backend_class_id="iqm:emerald",
97
93
  name="Bell State SDK Quickstart",
98
94
  job_subcategory_id="fin:port", # Finance Portfolio Optimization
99
95
  shots=100,
@@ -155,7 +151,7 @@ try:
155
151
  print(f" - {bc.name} [{bc.type}] — {bc.short_code or bc.id}")
156
152
 
157
153
  # 2. Choose IDs
158
- MY_BACKEND = "rigetti:ankaa-3"
154
+ MY_BACKEND = "iqm:emerald"
159
155
  MY_SUBCATEGORY = "fin:port"
160
156
 
161
157
  # 3. Upload
@@ -290,6 +286,7 @@ finally:
290
286
  | `list_user_organizations(limit=20, cursor=...)` | `PaginatedOrganizations` | Your orgs |
291
287
  | `list_providers(limit=20, cursor=...)` | `PaginatedProviders` | All backend providers |
292
288
  | `list_backend_classes(provider_id=None, limit=20, cursor=...)` | `PaginatedBackendClasses` | Available backends |
289
+ | `get_credit_balance(organization_id: str)` | `CreditBalanceRead` | Get current credit balance |
293
290
 
294
291
  ## Data Models
295
292
 
@@ -345,7 +342,7 @@ from openquantum_sdk.enums import ExecutionPlanType, QueuePriorityType
345
342
  ```bash
346
343
  python -m openquantum_sdk --sdk-key ./key.json \
347
344
  --input bell.qasm \
348
- --backend "ionq:aria-1" \
345
+ --backend "iqm:emerald" \
349
346
  --name "CLI Circuit" \
350
347
  --subcategory "mathematics:linear-systems" \
351
348
  --shots 100 \
@@ -359,11 +356,12 @@ Automatically **downloads and pretty-prints JSON output**.
359
356
  ### Backends
360
357
  | Provider | Backend | Short Code |
361
358
  | ------ | ------ | ------ |
362
- | IonQ | Aria-1 | `ionq:aria-1` |
359
+ | AQT | Ibex-Q1 | `aqt:ibex-q1` |
360
+ | IonQ | Forte Enterprise | `ionq:forte-ent` |
363
361
  | IonQ | Forte-1 | `ionq:forte-1` |
364
362
  | IQM | Emerald | `iqm:emerald` |
365
363
  | IQM | Garnet | `iqm:garnet` |
366
- | Rigetti | Ankaa-3 | `rigetti:ankaa-3` |
364
+ | Rigetti | Cepheus-1-108Q | `rigetti:cepheus-108q`|
367
365
 
368
366
  *Note: This list may be modified as backends are added or removed from the platform. For the most up-to-date list, run the following code:*
369
367
 
@@ -431,5 +429,8 @@ for cat in cats:
431
429
  **Q: How do I get results as JSON?**
432
430
  **A:** Use `scheduler.download_job_output(job)` — returns parsed object.
433
431
 
434
- **Q: Why does auto mode fail on some QPUs?**
435
- **A:** `auto` only allows `PUBLIC` + `STANDARD`. Use explicit enums for private/instant access.
432
+ **Q: Why does auto mode fail on some QPUs?**
433
+ **A:** `"auto"` selects the cheapest plan and priority (`PUBLIC` + `STANDARD`). If a backend only offers private execution, pass `execution_plan="private"` explicitly. Similarly, use `queue_priority="priority"` or `"instant"` for higher-priority queue access.
434
+
435
+ **Q: Can I hide the public plan citation notice?**
436
+ **A:** Setting `OPENQUANTUM_HIDE_CITATION_NOTICE=true` will omit the citation notice from output.
@@ -1,5 +1,5 @@
1
1
  from .clients import SchedulerClient, ManagementClient
2
2
  from .utils import poll_for_status
3
3
 
4
- __version__ = "0.3.3"
4
+ __version__ = "0.3.7"
5
5
  __all__ = ["SchedulerClient", "ManagementClient", "poll_for_status"]
@@ -121,8 +121,10 @@ def main():
121
121
  creds=creds
122
122
  )
123
123
 
124
- scheduler = SchedulerClient(base_url=args.scheduler_base, auth=auth)
125
124
  management = ManagementClient(base_url=args.management_base, auth=auth)
125
+ scheduler = SchedulerClient(
126
+ base_url=args.scheduler_base, auth=auth, management_client=management
127
+ )
126
128
 
127
129
  try:
128
130
  print("--- Open Quantum Job Submission CLI ---")
@@ -9,17 +9,28 @@ from urllib.parse import urljoin
9
9
 
10
10
  @dataclass
11
11
  class ClientCredentials:
12
+ """SDK key credentials for machine-to-machine authentication.
13
+
14
+ Attributes:
15
+ client_id: The OAuth2 client ID (SDK key ID).
16
+ client_secret: The OAuth2 client secret (SDK key secret).
17
+ """
18
+
12
19
  client_id: str
13
20
  client_secret: str
14
21
 
15
22
 
16
23
  class ClientCredentialsAuth:
24
+ """Keycloak client-credentials OAuth2 helper with thread-safe token caching.
25
+
26
+ Manages the full token lifecycle: initial fetch, automatic refresh when
27
+ the token is within ``leeway_seconds`` of expiry, and forced refresh on
28
+ 401 retries. All token operations are thread-safe.
29
+
30
+ The token endpoint is constructed as:
31
+ ``{keycloak_base}/realms/{realm}/protocol/openid-connect/token``
17
32
  """
18
- Keycloak client-credentials OAuth2 helper with local, thread-safe token cache.
19
- - Fetches token from: {keycloak_base}/realms/{realm}/protocol/openid-connect/token
20
- - Auto refreshes when within leeway of expiry
21
- - Retries once on 401
22
- """
33
+
23
34
  def __init__(
24
35
  self,
25
36
  creds: ClientCredentials,
@@ -29,6 +40,19 @@ class ClientCredentialsAuth:
29
40
  leeway_seconds: int = 30,
30
41
  session: Optional[requests.Session] = None,
31
42
  ):
43
+ """Initialize the auth helper.
44
+
45
+ Args:
46
+ creds: Client credentials containing the client ID and secret.
47
+ keycloak_base: Base URL of the Keycloak server.
48
+ Defaults to ``"https://id.openquantum.com"``.
49
+ realm: Keycloak realm name. Defaults to ``"platform"``.
50
+ scope: Optional OAuth2 scope to request.
51
+ leeway_seconds: Seconds before token expiry to trigger a
52
+ proactive refresh. Defaults to 30.
53
+ session: Optional ``requests.Session`` to use for token requests.
54
+ A new session is created if not provided.
55
+ """
32
56
  self.keycloak_base = keycloak_base.rstrip("/")
33
57
  self.realm = realm
34
58
  self.creds = creds
@@ -41,6 +65,7 @@ class ClientCredentialsAuth:
41
65
 
42
66
  @property
43
67
  def token_endpoint(self) -> str:
68
+ """The full Keycloak token endpoint URL for this realm."""
44
69
  return urljoin(
45
70
  self.keycloak_base + "/",
46
71
  f"realms/{self.realm}/protocol/openid-connect/token",
@@ -72,6 +97,22 @@ class ClientCredentialsAuth:
72
97
  self._expires_at = time.time() + int(expires_in)
73
98
 
74
99
  def get_access_token(self, force: bool = False) -> str:
100
+ """Return a valid access token, refreshing if needed.
101
+
102
+ Uses double-checked locking to ensure only one thread fetches a
103
+ new token at a time.
104
+
105
+ Args:
106
+ force: If ``True``, forces a token refresh regardless of
107
+ expiry status. Defaults to ``False``.
108
+
109
+ Returns:
110
+ A valid OAuth2 access token string.
111
+
112
+ Raises:
113
+ RuntimeError: If the Keycloak response is missing an access token.
114
+ requests.HTTPError: If the token request fails.
115
+ """
75
116
  if force or self._needs_refresh():
76
117
  with self._lock:
77
118
  if force or self._needs_refresh():
@@ -79,6 +120,18 @@ class ClientCredentialsAuth:
79
120
  return self._access_token # type: ignore[str-bytes-safe]
80
121
 
81
122
  def apply_auth_header(self, headers: Dict[str, str]) -> Dict[str, str]:
123
+ """Add a Bearer authorization header using the current access token.
124
+
125
+ Does not mutate the input dict; returns a new dict with the
126
+ ``Authorization`` header added.
127
+
128
+ Args:
129
+ headers: Existing headers to augment.
130
+
131
+ Returns:
132
+ A new headers dict containing all entries from ``headers`` plus
133
+ the ``Authorization: Bearer <token>`` header.
134
+ """
82
135
  token = self.get_access_token()
83
136
  # don't mutate caller's header dict
84
137
  return {**headers, "Authorization": f"Bearer {token}"}