iqm-client 25.1.0__py3-none-any.whl → 25.3.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.
- iqm/iqm_client/iqm_client.py +57 -81
- {iqm_client-25.1.0.dist-info → iqm_client-25.3.0.dist-info}/METADATA +1 -1
- {iqm_client-25.1.0.dist-info → iqm_client-25.3.0.dist-info}/RECORD +8 -8
- {iqm_client-25.1.0.dist-info → iqm_client-25.3.0.dist-info}/AUTHORS.rst +0 -0
- {iqm_client-25.1.0.dist-info → iqm_client-25.3.0.dist-info}/LICENSE.txt +0 -0
- {iqm_client-25.1.0.dist-info → iqm_client-25.3.0.dist-info}/WHEEL +0 -0
- {iqm_client-25.1.0.dist-info → iqm_client-25.3.0.dist-info}/entry_points.txt +0 -0
- {iqm_client-25.1.0.dist-info → iqm_client-25.3.0.dist-info}/top_level.txt +0 -0
iqm/iqm_client/iqm_client.py
CHANGED
|
@@ -170,6 +170,7 @@ class IQMClient:
|
|
|
170
170
|
*,
|
|
171
171
|
timeout: float,
|
|
172
172
|
retry: bool = False,
|
|
173
|
+
allow_errors: bool = False,
|
|
173
174
|
) -> requests.Response:
|
|
174
175
|
"""Make a HTTP GET request to an IQM server endpoint.
|
|
175
176
|
|
|
@@ -180,6 +181,7 @@ class IQMClient:
|
|
|
180
181
|
endpoint_args: Arguments for the endpoint.
|
|
181
182
|
timeout: HTTP request timeout (in seconds).
|
|
182
183
|
retry: Iff True, keep trying if you get a 502 error.
|
|
184
|
+
allow_errors: Iff true, don't raise exceptions for error responses.
|
|
183
185
|
|
|
184
186
|
Returns:
|
|
185
187
|
HTTP response to the request.
|
|
@@ -199,9 +201,10 @@ class IQMClient:
|
|
|
199
201
|
)
|
|
200
202
|
|
|
201
203
|
response = self._retry_request_on_error(request) if retry else request()
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
204
|
+
if not allow_errors:
|
|
205
|
+
self._check_not_found_error(response)
|
|
206
|
+
self._check_authentication_errors(response)
|
|
207
|
+
response.raise_for_status()
|
|
205
208
|
return response
|
|
206
209
|
|
|
207
210
|
def _deserialize_response(
|
|
@@ -354,7 +357,10 @@ class IQMClient:
|
|
|
354
357
|
ID for the created job. This ID is needed to query the job status and the execution results.
|
|
355
358
|
|
|
356
359
|
"""
|
|
357
|
-
headers = {
|
|
360
|
+
headers = {
|
|
361
|
+
"Expect": "100-Continue",
|
|
362
|
+
**self._default_headers(),
|
|
363
|
+
}
|
|
358
364
|
try:
|
|
359
365
|
# check if someone is trying to profile us with OpenTelemetry
|
|
360
366
|
from opentelemetry import propagate
|
|
@@ -367,11 +373,12 @@ class IQMClient:
|
|
|
367
373
|
if os.environ.get("IQM_CLIENT_DEBUG") == "1":
|
|
368
374
|
print(f"\nIQM CLIENT DEBUGGING ENABLED\nSUBMITTING RUN REQUEST:\n{run_request}\n")
|
|
369
375
|
|
|
376
|
+
# use UTF-8 encoding for the JSON payload
|
|
370
377
|
result = self._retry_request_on_error(
|
|
371
378
|
lambda: requests.post(
|
|
372
379
|
self._api.url(APIEndpoint.SUBMIT_JOB),
|
|
373
|
-
|
|
374
|
-
headers=headers,
|
|
380
|
+
data=run_request.model_dump_json(exclude_none=True).encode("utf-8"),
|
|
381
|
+
headers=headers | {"Content-Type": "application/json; charset=UTF-8"},
|
|
375
382
|
timeout=REQUESTS_TIMEOUT,
|
|
376
383
|
)
|
|
377
384
|
)
|
|
@@ -668,91 +675,60 @@ class IQMClient:
|
|
|
668
675
|
)
|
|
669
676
|
status = status_response.json()
|
|
670
677
|
if Status(status["status"]) not in Status.terminal_statuses():
|
|
671
|
-
return RunResult.from_dict(
|
|
672
|
-
{
|
|
673
|
-
"measurements": [],
|
|
674
|
-
"status": status["status"],
|
|
675
|
-
"message": "",
|
|
676
|
-
"metadata": {
|
|
677
|
-
"calibration_set_id": None,
|
|
678
|
-
"circuits_batch": [],
|
|
679
|
-
"parameters": None,
|
|
680
|
-
"timestamps": {},
|
|
681
|
-
},
|
|
682
|
-
}
|
|
683
|
-
)
|
|
678
|
+
return RunResult.from_dict({"status": status["status"], "metadata": {}})
|
|
684
679
|
|
|
685
|
-
result = self.
|
|
686
|
-
|
|
687
|
-
self._api.url(APIEndpoint.GET_JOB_RESULT, str(job_id)),
|
|
688
|
-
headers=self._default_headers(),
|
|
689
|
-
timeout=timeout_secs,
|
|
690
|
-
)
|
|
691
|
-
)
|
|
692
|
-
if result.status_code != 404:
|
|
693
|
-
result.raise_for_status()
|
|
694
|
-
measurements = [] if result.status_code == 404 else result.json()
|
|
695
|
-
request_parameters = (
|
|
696
|
-
{}
|
|
697
|
-
if result.status_code == 404
|
|
698
|
-
else requests.get(
|
|
699
|
-
self._api.url(APIEndpoint.GET_JOB_REQUEST_PARAMETERS, str(job_id)),
|
|
700
|
-
headers=self._default_headers(),
|
|
701
|
-
timeout=timeout_secs,
|
|
702
|
-
).json()
|
|
703
|
-
)
|
|
704
|
-
calibration_set_id = (
|
|
705
|
-
None
|
|
706
|
-
if result.status_code == 404
|
|
707
|
-
else requests.get(
|
|
708
|
-
self._api.url(APIEndpoint.GET_JOB_CALIBRATION_SET_ID, str(job_id)),
|
|
709
|
-
headers=self._default_headers(),
|
|
710
|
-
timeout=timeout_secs,
|
|
711
|
-
).json()
|
|
712
|
-
)
|
|
713
|
-
circuits_batch = (
|
|
714
|
-
[]
|
|
715
|
-
if result.status_code == 404
|
|
716
|
-
else requests.get(
|
|
717
|
-
self._api.url(APIEndpoint.GET_JOB_CIRCUITS_BATCH, str(job_id)),
|
|
718
|
-
headers=self._default_headers(),
|
|
719
|
-
timeout=timeout_secs,
|
|
720
|
-
).json()
|
|
680
|
+
result = self._get_request(
|
|
681
|
+
APIEndpoint.GET_JOB_RESULT, (str(job_id),), timeout=timeout_secs, retry=True, allow_errors=True
|
|
721
682
|
)
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
else requests.get(
|
|
726
|
-
self._api.url(APIEndpoint.GET_JOB_TIMELINE, str(job_id)),
|
|
727
|
-
headers=self._default_headers(),
|
|
728
|
-
timeout=timeout_secs,
|
|
729
|
-
).json()
|
|
730
|
-
)
|
|
731
|
-
error_message_response = requests.get(
|
|
732
|
-
self._api.url(APIEndpoint.GET_JOB_ERROR_LOG, str(job_id)),
|
|
733
|
-
headers=self._default_headers(),
|
|
734
|
-
timeout=timeout_secs,
|
|
683
|
+
|
|
684
|
+
error_log_response = self._get_request(
|
|
685
|
+
APIEndpoint.GET_JOB_ERROR_LOG, (str(job_id),), timeout=timeout_secs, allow_errors=True
|
|
735
686
|
)
|
|
736
|
-
|
|
687
|
+
if error_log_response.status_code == 200:
|
|
688
|
+
error_log = error_log_response.json()
|
|
689
|
+
if isinstance(error_log, dict) and "user_error_message" in error_log:
|
|
690
|
+
error_message = error_log["user_error_message"]
|
|
691
|
+
else:
|
|
692
|
+
# backwards compatibility for older error_log format
|
|
693
|
+
# TODO: remove when not needed anymore
|
|
694
|
+
error_message = error_log_response.text
|
|
695
|
+
else:
|
|
696
|
+
error_message = None
|
|
697
|
+
|
|
698
|
+
if result.status_code == 404:
|
|
699
|
+
return RunResult.from_dict({"status": status["status"], "message": error_message, "metadata": {}})
|
|
700
|
+
else:
|
|
701
|
+
result.raise_for_status()
|
|
702
|
+
|
|
703
|
+
measurements = result.json()
|
|
704
|
+
request_parameters = self._get_request(
|
|
705
|
+
APIEndpoint.GET_JOB_REQUEST_PARAMETERS, (str(job_id),), timeout=timeout_secs, allow_errors=True
|
|
706
|
+
).json()
|
|
707
|
+
calibration_set_id = self._get_request(
|
|
708
|
+
APIEndpoint.GET_JOB_CALIBRATION_SET_ID, (str(job_id),), timeout=timeout_secs, allow_errors=True
|
|
709
|
+
).json()
|
|
710
|
+
circuits_batch = self._get_request(
|
|
711
|
+
APIEndpoint.GET_JOB_CIRCUITS_BATCH, (str(job_id),), timeout=timeout_secs, allow_errors=True
|
|
712
|
+
).json()
|
|
713
|
+
timeline = self._get_request(
|
|
714
|
+
APIEndpoint.GET_JOB_TIMELINE, (str(job_id),), timeout=timeout_secs, allow_errors=True
|
|
715
|
+
).json()
|
|
716
|
+
|
|
737
717
|
return RunResult.from_dict(
|
|
738
718
|
{
|
|
739
719
|
"measurements": measurements,
|
|
740
720
|
"status": status["status"],
|
|
741
721
|
"message": error_message,
|
|
742
722
|
"metadata": {
|
|
743
|
-
"
|
|
723
|
+
"calibration_set_id": calibration_set_id,
|
|
744
724
|
"circuits_batch": circuits_batch,
|
|
745
|
-
"parameters":
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
"move_validation_mode": request_parameters["move_validation_mode"],
|
|
753
|
-
"move_gate_frame_tracking_mode": request_parameters["move_gate_frame_tracking_mode"],
|
|
754
|
-
}
|
|
755
|
-
),
|
|
725
|
+
"parameters": {
|
|
726
|
+
"shots": request_parameters["shots"],
|
|
727
|
+
"max_circuit_duration_over_t2": request_parameters["max_circuit_duration_over_t2"],
|
|
728
|
+
"heralding_mode": request_parameters["heralding_mode"],
|
|
729
|
+
"move_validation_mode": request_parameters["move_validation_mode"],
|
|
730
|
+
"move_gate_frame_tracking_mode": request_parameters["move_gate_frame_tracking_mode"],
|
|
731
|
+
},
|
|
756
732
|
"timestamps": {datapoint["status"]: datapoint["timestamp"] for datapoint in timeline},
|
|
757
733
|
},
|
|
758
734
|
}
|
|
@@ -21,7 +21,7 @@ iqm/iqm_client/__init__.py,sha256=D-8W54EcQIxk_1JZo_86GYlR1YitHhPIiFwwLJ2IfGE,14
|
|
|
21
21
|
iqm/iqm_client/api.py,sha256=V57vslYSn5g1IgXWtWuxp3hD1DbY18dKUexRdxEuX78,8268
|
|
22
22
|
iqm/iqm_client/authentication.py,sha256=Zbc5DpTwrcwNePKyZ_7KAFxwQFSVyZelQR_CWRCmlME,12187
|
|
23
23
|
iqm/iqm_client/errors.py,sha256=ty2P-sg80zlAoL3_kC3PlprgDUv4PI-KFhmmxaaapS0,1429
|
|
24
|
-
iqm/iqm_client/iqm_client.py,sha256=
|
|
24
|
+
iqm/iqm_client/iqm_client.py,sha256=SFImZk5DrAq51hr2G5sk242mO-8LYz-Mlc6Rc_JIuZE,50019
|
|
25
25
|
iqm/iqm_client/models.py,sha256=YjlerNleeE1kOmzRsux-o02h7XSqv0u0KQEERufdxKk,50302
|
|
26
26
|
iqm/iqm_client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
27
|
iqm/iqm_client/transpile.py,sha256=-iIZaxaTaQLy6pMkRG15VN8X1ZE_iNhX3pjsNjqg6P8,36935
|
|
@@ -56,10 +56,10 @@ iqm/qiskit_iqm/fake_backends/fake_apollo.py,sha256=eT2vd3kQBi1rrvxCpePymBCfFK84d
|
|
|
56
56
|
iqm/qiskit_iqm/fake_backends/fake_deneb.py,sha256=RzQXmLXmBARDiMKVxk5Aw9fVbc6IYlW0A5jibk9iYD0,3156
|
|
57
57
|
iqm/qiskit_iqm/fake_backends/fake_garnet.py,sha256=GI0xafTCj1Um09qVuccO6GPOGBm6ygul_O40Wu220Ys,5555
|
|
58
58
|
iqm/qiskit_iqm/fake_backends/iqm_fake_backend.py,sha256=wJtfsxjPYbDKmzaz5R4AuaXvvPHa21WyPtRgNctL9eY,16785
|
|
59
|
-
iqm_client-25.
|
|
60
|
-
iqm_client-25.
|
|
61
|
-
iqm_client-25.
|
|
62
|
-
iqm_client-25.
|
|
63
|
-
iqm_client-25.
|
|
64
|
-
iqm_client-25.
|
|
65
|
-
iqm_client-25.
|
|
59
|
+
iqm_client-25.3.0.dist-info/AUTHORS.rst,sha256=qsxeK5A3-B_xK3hNbhFHEIkoHNpo7sdzYyRTs7Bdtm8,795
|
|
60
|
+
iqm_client-25.3.0.dist-info/LICENSE.txt,sha256=2DXrmQtVVUV9Fc9RBFJidMiTEaQlG2oAtlC9PMrEwTk,11333
|
|
61
|
+
iqm_client-25.3.0.dist-info/METADATA,sha256=aId3j1veUFCJiceuZYn0veT8kjgr9EQdXR_bAOZVpi8,17079
|
|
62
|
+
iqm_client-25.3.0.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
|
|
63
|
+
iqm_client-25.3.0.dist-info/entry_points.txt,sha256=Kk2qfRwk8vbIJ7qCAvmaUogfRRn6t92_hBFhe6kqAE4,1317
|
|
64
|
+
iqm_client-25.3.0.dist-info/top_level.txt,sha256=NB4XRfyDS6_wG9gMsyX-9LTU7kWnTQxNvkbzIxGv3-c,4
|
|
65
|
+
iqm_client-25.3.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|