iqm-station-control-client 8.1.0__py3-none-any.whl → 9.1.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/station_control/client/__init__.py +1 -1
- iqm/station_control/client/iqm_server/error.py +1 -1
- iqm/station_control/client/iqm_server/grpc_utils.py +5 -3
- iqm/station_control/client/iqm_server/iqm_server_client.py +179 -46
- iqm/station_control/client/list_models.py +18 -12
- iqm/station_control/client/serializers/__init__.py +1 -1
- iqm/station_control/client/serializers/channel_property_serializer.py +12 -6
- iqm/station_control/client/serializers/datetime_serializers.py +1 -1
- iqm/station_control/client/serializers/playlist_serializers.py +1 -1
- iqm/station_control/client/serializers/run_serializers.py +1 -1
- iqm/station_control/client/serializers/setting_node_serializer.py +1 -1
- iqm/station_control/client/serializers/struct_serializer.py +1 -1
- iqm/station_control/client/serializers/sweep_serializers.py +2 -3
- iqm/station_control/client/serializers/task_serializers.py +1 -1
- iqm/station_control/client/station_control.py +245 -487
- iqm/station_control/client/utils.py +44 -17
- iqm/station_control/interface/__init__.py +1 -1
- iqm/station_control/interface/list_with_meta.py +1 -1
- iqm/station_control/interface/models/__init__.py +13 -1
- iqm/station_control/interface/models/dut.py +1 -1
- iqm/station_control/interface/models/dynamic_quantum_architecture.py +98 -0
- iqm/station_control/interface/models/observation.py +1 -1
- iqm/station_control/interface/models/observation_set.py +15 -1
- iqm/station_control/interface/models/run.py +1 -1
- iqm/station_control/interface/models/sequence.py +1 -1
- iqm/station_control/interface/models/static_quantum_architecture.py +40 -0
- iqm/station_control/interface/models/sweep.py +1 -1
- iqm/station_control/interface/models/type_aliases.py +7 -1
- iqm/station_control/interface/pydantic_base.py +1 -1
- iqm/station_control/interface/station_control.py +511 -0
- {iqm_station_control_client-8.1.0.dist-info → iqm_station_control_client-9.1.0.dist-info}/METADATA +2 -2
- {iqm_station_control_client-8.1.0.dist-info → iqm_station_control_client-9.1.0.dist-info}/RECORD +35 -33
- iqm/station_control/client/iqm_server/meta_class.py +0 -38
- {iqm_station_control_client-8.1.0.dist-info → iqm_station_control_client-9.1.0.dist-info}/LICENSE.txt +0 -0
- {iqm_station_control_client-8.1.0.dist-info → iqm_station_control_client-9.1.0.dist-info}/WHEEL +0 -0
- {iqm_station_control_client-8.1.0.dist-info → iqm_station_control_client-9.1.0.dist-info}/top_level.txt +0 -0
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
from exa.common.errors.
|
|
15
|
+
from exa.common.errors.station_control_errors import StationControlError
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
class IqmServerError(StationControlError):
|
|
@@ -25,6 +25,7 @@ from pydantic import HttpUrl
|
|
|
25
25
|
|
|
26
26
|
from iqm.station_control.client.iqm_server import proto
|
|
27
27
|
from iqm.station_control.client.iqm_server.error import IqmServerError
|
|
28
|
+
from iqm.station_control.interface.models.type_aliases import StrUUID
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
class ClientCallDetails(grpc.ClientCallDetails):
|
|
@@ -43,8 +44,7 @@ class ApiTokenAuth(grpc.UnaryUnaryClientInterceptor, grpc.UnaryStreamClientInter
|
|
|
43
44
|
|
|
44
45
|
def _add_auth_header(self, client_call_details) -> ClientCallDetails:
|
|
45
46
|
details = ClientCallDetails(client_call_details)
|
|
46
|
-
|
|
47
|
-
details.metadata.append(("authorization", f"Bearer {token}"))
|
|
47
|
+
details.metadata.append(("authorization", self.get_token_callback()))
|
|
48
48
|
return details
|
|
49
49
|
|
|
50
50
|
def intercept_unary_stream(self, continuation, client_call_details, request):
|
|
@@ -115,7 +115,9 @@ def create_channel(
|
|
|
115
115
|
return channel
|
|
116
116
|
|
|
117
117
|
|
|
118
|
-
def to_proto_uuid(value:
|
|
118
|
+
def to_proto_uuid(value: StrUUID) -> proto.Uuid:
|
|
119
|
+
if isinstance(value, str):
|
|
120
|
+
value = uuid.UUID(value)
|
|
119
121
|
return proto.Uuid(raw=value.bytes)
|
|
120
122
|
|
|
121
123
|
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
-
"""
|
|
14
|
+
"""Client implementation for IQM Server."""
|
|
15
15
|
|
|
16
|
-
from collections.abc import Callable, Iterable
|
|
16
|
+
from collections.abc import Callable, Iterable, Sequence
|
|
17
17
|
from contextlib import contextmanager
|
|
18
18
|
import dataclasses
|
|
19
19
|
from io import BytesIO
|
|
@@ -22,9 +22,11 @@ import logging
|
|
|
22
22
|
from time import sleep
|
|
23
23
|
from typing import Any, TypeVar, cast
|
|
24
24
|
import uuid
|
|
25
|
+
from uuid import UUID
|
|
25
26
|
|
|
26
27
|
import grpc
|
|
27
28
|
from iqm.models.channel_properties import ChannelProperties
|
|
29
|
+
import requests
|
|
28
30
|
|
|
29
31
|
from exa.common.data.setting_node import SettingNode
|
|
30
32
|
from exa.common.data.value import ObservationValue, validate_value
|
|
@@ -39,42 +41,64 @@ from iqm.station_control.client.iqm_server.grpc_utils import (
|
|
|
39
41
|
to_datetime,
|
|
40
42
|
to_proto_uuid,
|
|
41
43
|
)
|
|
42
|
-
from iqm.station_control.client.iqm_server.meta_class import IqmServerClientMeta
|
|
43
44
|
from iqm.station_control.client.list_models import DutFieldDataList, DutList
|
|
44
45
|
from iqm.station_control.client.serializers import deserialize_sweep_results, serialize_sweep_job_request
|
|
45
46
|
from iqm.station_control.client.serializers.channel_property_serializer import unpack_channel_properties
|
|
46
47
|
from iqm.station_control.client.serializers.setting_node_serializer import deserialize_setting_node
|
|
47
48
|
from iqm.station_control.client.serializers.task_serializers import deserialize_sweep_job_request
|
|
48
|
-
from iqm.station_control.client.station_control import
|
|
49
|
+
from iqm.station_control.client.station_control import _StationControlClientBase
|
|
50
|
+
from iqm.station_control.interface.list_with_meta import ListWithMeta
|
|
49
51
|
from iqm.station_control.interface.models import (
|
|
50
52
|
DutData,
|
|
51
53
|
DutFieldData,
|
|
54
|
+
DynamicQuantumArchitecture,
|
|
55
|
+
JobData,
|
|
52
56
|
JobExecutorStatus,
|
|
57
|
+
JobResult,
|
|
58
|
+
ObservationData,
|
|
59
|
+
ObservationDefinition,
|
|
60
|
+
ObservationLite,
|
|
61
|
+
ObservationSetData,
|
|
62
|
+
ObservationSetDefinition,
|
|
63
|
+
ObservationSetUpdate,
|
|
64
|
+
ObservationUpdate,
|
|
65
|
+
QualityMetrics,
|
|
66
|
+
RunData,
|
|
67
|
+
RunDefinition,
|
|
68
|
+
RunLite,
|
|
69
|
+
SequenceMetadataData,
|
|
70
|
+
SequenceMetadataDefinition,
|
|
71
|
+
SequenceResultData,
|
|
72
|
+
SequenceResultDefinition,
|
|
73
|
+
StaticQuantumArchitecture,
|
|
53
74
|
Statuses,
|
|
54
75
|
SweepData,
|
|
55
76
|
SweepDefinition,
|
|
56
77
|
SweepResults,
|
|
57
78
|
)
|
|
58
|
-
from iqm.station_control.interface.models.jobs import
|
|
79
|
+
from iqm.station_control.interface.models.jobs import JobError
|
|
59
80
|
from iqm.station_control.interface.models.sweep import SweepBase
|
|
81
|
+
from iqm.station_control.interface.models.type_aliases import GetObservationsMode, SoftwareVersionSet, StrUUID
|
|
60
82
|
|
|
61
83
|
logger = logging.getLogger(__name__)
|
|
62
84
|
|
|
63
85
|
T = TypeVar("T")
|
|
64
86
|
|
|
65
87
|
|
|
66
|
-
class IqmServerClient(
|
|
88
|
+
class IqmServerClient(_StationControlClientBase):
|
|
67
89
|
def __init__(
|
|
68
90
|
self,
|
|
69
91
|
root_url: str,
|
|
92
|
+
*,
|
|
70
93
|
get_token_callback: Callable[[], str] | None = None,
|
|
94
|
+
client_signature: str | None = None,
|
|
71
95
|
grpc_channel: grpc.Channel | None = None,
|
|
72
96
|
):
|
|
73
|
-
|
|
97
|
+
super().__init__(root_url, get_token_callback=get_token_callback, client_signature=client_signature)
|
|
74
98
|
self._connection_params = parse_connection_params(root_url)
|
|
75
99
|
self._cached_resources = {}
|
|
76
100
|
self._latest_submitted_sweep = None
|
|
77
|
-
self._channel = grpc_channel or create_channel(self._connection_params,
|
|
101
|
+
self._channel = grpc_channel or create_channel(self._connection_params, self._get_token_callback)
|
|
78
102
|
self._current_qc = resolve_current_qc(self._channel, self._connection_params.quantum_computer)
|
|
79
103
|
|
|
80
104
|
def __del__(self):
|
|
@@ -86,9 +110,18 @@ class IqmServerClient(StationControlClient, metaclass=IqmServerClientMeta):
|
|
|
86
110
|
def get_about(self) -> dict:
|
|
87
111
|
return self._get_resource("about", parse_json)
|
|
88
112
|
|
|
113
|
+
def get_health(self) -> dict:
|
|
114
|
+
raise NotImplementedError
|
|
115
|
+
|
|
89
116
|
def get_configuration(self) -> dict:
|
|
90
117
|
return self._get_resource("configuration", parse_json)
|
|
91
118
|
|
|
119
|
+
def get_exa_configuration(self) -> str:
|
|
120
|
+
raise NotImplementedError
|
|
121
|
+
|
|
122
|
+
def get_or_create_software_version_set(self, software_version_set: SoftwareVersionSet) -> int:
|
|
123
|
+
raise NotImplementedError
|
|
124
|
+
|
|
92
125
|
def get_settings(self) -> SettingNode:
|
|
93
126
|
return self._get_resource("settings", deserialize_setting_node).copy()
|
|
94
127
|
|
|
@@ -98,14 +131,6 @@ class IqmServerClient(StationControlClient, metaclass=IqmServerClientMeta):
|
|
|
98
131
|
def get_channel_properties(self) -> dict[str, ChannelProperties]:
|
|
99
132
|
return self._get_resource("channel-properties", unpack_channel_properties)
|
|
100
133
|
|
|
101
|
-
def get_duts(self) -> list[DutData]:
|
|
102
|
-
return self._get_resource("duts", lambda data: DutList.model_validate(parse_json(data)))
|
|
103
|
-
|
|
104
|
-
def get_dut_fields(self, dut_label: str) -> list[DutFieldData]:
|
|
105
|
-
return self._get_resource(
|
|
106
|
-
f"dut-fields/{dut_label}", lambda data: DutFieldDataList.model_validate(parse_json(data))
|
|
107
|
-
)
|
|
108
|
-
|
|
109
134
|
def sweep(self, sweep_definition: SweepDefinition) -> dict:
|
|
110
135
|
with wrap_error("Job submission failed"):
|
|
111
136
|
jobs = proto.JobsStub(self._channel)
|
|
@@ -126,8 +151,11 @@ class IqmServerClient(StationControlClient, metaclass=IqmServerClientMeta):
|
|
|
126
151
|
"job_id": str(job_id),
|
|
127
152
|
}
|
|
128
153
|
|
|
129
|
-
def get_sweep(self, sweep_id:
|
|
154
|
+
def get_sweep(self, sweep_id: UUID) -> SweepData:
|
|
130
155
|
with wrap_error("Job loading failed"):
|
|
156
|
+
if isinstance(sweep_id, str):
|
|
157
|
+
sweep_id = uuid.UUID(sweep_id)
|
|
158
|
+
|
|
131
159
|
jobs = proto.JobsStub(self._channel)
|
|
132
160
|
job_lookup = proto.JobLookupV1(id=to_proto_uuid(sweep_id))
|
|
133
161
|
job: proto.JobV1 = jobs.GetJobV1(job_lookup)
|
|
@@ -146,18 +174,118 @@ class IqmServerClient(StationControlClient, metaclass=IqmServerClientMeta):
|
|
|
146
174
|
**{f.name: getattr(sweep, f.name) for f in dataclasses.fields(SweepBase)},
|
|
147
175
|
)
|
|
148
176
|
|
|
149
|
-
def
|
|
177
|
+
def delete_sweep(self, sweep_id: UUID) -> None:
|
|
178
|
+
raise NotImplementedError
|
|
179
|
+
|
|
180
|
+
def get_sweep_results(self, sweep_id: UUID) -> SweepResults:
|
|
150
181
|
with wrap_error("Job result loading failed"):
|
|
151
182
|
jobs = proto.JobsStub(self._channel)
|
|
152
183
|
data_chunks = jobs.GetJobResultsV1(proto.JobLookupV1(id=to_proto_uuid(sweep_id)))
|
|
153
184
|
return deserialize_sweep_results(load_all(data_chunks))
|
|
154
185
|
|
|
155
|
-
def
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
186
|
+
def run(
|
|
187
|
+
self,
|
|
188
|
+
run_definition: RunDefinition,
|
|
189
|
+
update_progress_callback: Callable[[Statuses], None] | None = None,
|
|
190
|
+
wait_job_completion: bool = True,
|
|
191
|
+
) -> bool:
|
|
192
|
+
raise NotImplementedError
|
|
193
|
+
|
|
194
|
+
def get_run(self, run_id: UUID) -> RunData:
|
|
195
|
+
raise NotImplementedError
|
|
196
|
+
|
|
197
|
+
def query_runs(self, **kwargs) -> ListWithMeta[RunLite]:
|
|
198
|
+
raise NotImplementedError
|
|
199
|
+
|
|
200
|
+
def create_observations(
|
|
201
|
+
self, observation_definitions: Sequence[ObservationDefinition]
|
|
202
|
+
) -> ListWithMeta[ObservationData]:
|
|
203
|
+
raise NotImplementedError
|
|
204
|
+
|
|
205
|
+
def get_observations(
|
|
206
|
+
self,
|
|
207
|
+
*,
|
|
208
|
+
mode: GetObservationsMode,
|
|
209
|
+
dut_label: str | None = None,
|
|
210
|
+
dut_field: str | None = None,
|
|
211
|
+
tags: list[str] | None = None,
|
|
212
|
+
invalid: bool | None = False,
|
|
213
|
+
run_ids: list[UUID] | None = None,
|
|
214
|
+
sequence_ids: list[UUID] | None = None,
|
|
215
|
+
limit: int | None = None,
|
|
216
|
+
) -> list[ObservationData]:
|
|
217
|
+
raise NotImplementedError
|
|
218
|
+
|
|
219
|
+
def query_observations(self, **kwargs) -> ListWithMeta[ObservationData]:
|
|
220
|
+
raise NotImplementedError
|
|
221
|
+
|
|
222
|
+
def update_observations(self, observation_updates: Sequence[ObservationUpdate]) -> list[ObservationData]:
|
|
223
|
+
raise NotImplementedError
|
|
224
|
+
|
|
225
|
+
def query_observation_sets(self, **kwargs) -> ListWithMeta[ObservationSetData]:
|
|
226
|
+
raise NotImplementedError
|
|
227
|
+
|
|
228
|
+
def create_observation_set(self, observation_set_definition: ObservationSetDefinition) -> ObservationSetData:
|
|
229
|
+
raise NotImplementedError
|
|
230
|
+
|
|
231
|
+
def get_observation_set(self, observation_set_id: UUID) -> ObservationSetData:
|
|
232
|
+
raise NotImplementedError
|
|
233
|
+
|
|
234
|
+
def update_observation_set(self, observation_set_update: ObservationSetUpdate) -> ObservationSetData:
|
|
235
|
+
raise NotImplementedError
|
|
236
|
+
|
|
237
|
+
def finalize_observation_set(self, observation_set_id: UUID) -> None:
|
|
238
|
+
raise NotImplementedError
|
|
239
|
+
|
|
240
|
+
def get_observation_set_observations(self, observation_set_id: UUID) -> list[ObservationLite]:
|
|
241
|
+
raise NotImplementedError
|
|
242
|
+
|
|
243
|
+
def get_default_calibration_set(self) -> ObservationSetData:
|
|
244
|
+
raise NotImplementedError
|
|
245
|
+
|
|
246
|
+
def get_default_calibration_set_observations(self) -> list[ObservationLite]:
|
|
247
|
+
raise NotImplementedError
|
|
248
|
+
|
|
249
|
+
def get_dynamic_quantum_architecture(self, calibration_set_id: UUID) -> DynamicQuantumArchitecture:
|
|
250
|
+
response = self._send_request(requests.get, f"api/v1/calibration/{calibration_set_id}/gates")
|
|
251
|
+
return DynamicQuantumArchitecture.model_validate_json(response.text)
|
|
252
|
+
|
|
253
|
+
def get_default_dynamic_quantum_architecture(self) -> DynamicQuantumArchitecture:
|
|
254
|
+
raise NotImplementedError
|
|
255
|
+
|
|
256
|
+
def get_default_calibration_set_quality_metrics(self) -> QualityMetrics:
|
|
257
|
+
raise NotImplementedError
|
|
258
|
+
|
|
259
|
+
def get_calibration_set_quality_metrics(self, calibration_set_id: UUID) -> QualityMetrics:
|
|
260
|
+
raise NotImplementedError
|
|
261
|
+
|
|
262
|
+
def get_duts(self) -> list[DutData]:
|
|
263
|
+
return self._get_resource("duts", lambda data: DutList.model_validate(parse_json(data)))
|
|
264
|
+
|
|
265
|
+
def get_dut_fields(self, dut_label: str) -> list[DutFieldData]:
|
|
266
|
+
return self._get_resource(
|
|
267
|
+
f"dut-fields/{dut_label}", lambda data: DutFieldDataList.model_validate(parse_json(data))
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
def query_sequence_metadatas(self, **kwargs) -> ListWithMeta[SequenceMetadataData]:
|
|
271
|
+
raise NotImplementedError
|
|
272
|
+
|
|
273
|
+
def create_sequence_metadata(
|
|
274
|
+
self, sequence_metadata_definition: SequenceMetadataDefinition
|
|
275
|
+
) -> SequenceMetadataData:
|
|
276
|
+
raise NotImplementedError
|
|
277
|
+
|
|
278
|
+
def save_sequence_result(self, sequence_result_definition: SequenceResultDefinition) -> SequenceResultData:
|
|
279
|
+
raise NotImplementedError
|
|
280
|
+
|
|
281
|
+
def get_sequence_result(self, sequence_id: UUID) -> SequenceResultData:
|
|
282
|
+
raise NotImplementedError
|
|
159
283
|
|
|
160
|
-
def
|
|
284
|
+
def get_static_quantum_architecture(self, dut_label: str) -> StaticQuantumArchitecture:
|
|
285
|
+
response = self._send_request(requests.get, "api/v1/quantum-architecture")
|
|
286
|
+
return StaticQuantumArchitecture.model_validate_json(response.text)
|
|
287
|
+
|
|
288
|
+
def get_job(self, job_id: StrUUID) -> JobData:
|
|
161
289
|
with wrap_error("Job loading failed"):
|
|
162
290
|
jobs = proto.JobsStub(self._channel)
|
|
163
291
|
job: proto.JobV1 = jobs.GetJobV1(proto.JobLookupV1(id=to_proto_uuid(job_id)))
|
|
@@ -175,6 +303,34 @@ class IqmServerClient(StationControlClient, metaclass=IqmServerClientMeta):
|
|
|
175
303
|
position=job.queue_position if job.HasField("queue_position") else None,
|
|
176
304
|
)
|
|
177
305
|
|
|
306
|
+
def abort_job(self, job_id: StrUUID) -> None:
|
|
307
|
+
with wrap_error("Job cancellation failed"):
|
|
308
|
+
jobs = proto.JobsStub(self._channel)
|
|
309
|
+
jobs.CancelJobV1(proto.JobLookupV1(id=to_proto_uuid(job_id)))
|
|
310
|
+
|
|
311
|
+
def get_calibration_set_values(self, calibration_set_id: StrUUID) -> dict[str, ObservationValue]:
|
|
312
|
+
with wrap_error("Calibration set loading failed"):
|
|
313
|
+
calibrations = proto.CalibrationsStub(self._channel)
|
|
314
|
+
data_chunks = calibrations.GetFullCalibrationDataV1(
|
|
315
|
+
proto.CalibrationLookupV1(
|
|
316
|
+
id=to_proto_uuid(calibration_set_id),
|
|
317
|
+
)
|
|
318
|
+
)
|
|
319
|
+
_, cal_set_values = parse_calibration_set(load_all(data_chunks))
|
|
320
|
+
return cal_set_values
|
|
321
|
+
|
|
322
|
+
def get_latest_calibration_set_id(self, dut_label: str) -> uuid.UUID:
|
|
323
|
+
with wrap_error("Calibration set metadata loading failed"):
|
|
324
|
+
calibrations = proto.CalibrationsStub(self._channel)
|
|
325
|
+
metadata: proto.CalibrationMetadataV1 = calibrations.GetLatestQuantumComputerCalibrationV1(
|
|
326
|
+
proto.LatestQuantumComputerCalibrationLookupV1(
|
|
327
|
+
qc_id=self._current_qc.id,
|
|
328
|
+
)
|
|
329
|
+
)
|
|
330
|
+
if metadata.dut_label != dut_label:
|
|
331
|
+
raise ValueError(f"No calibration set for dut_label = {dut_label}")
|
|
332
|
+
return from_proto_uuid(metadata.id)
|
|
333
|
+
|
|
178
334
|
def _wait_job_completion(
|
|
179
335
|
self,
|
|
180
336
|
task_id: str,
|
|
@@ -202,29 +358,6 @@ class IqmServerClient(StationControlClient, metaclass=IqmServerClientMeta):
|
|
|
202
358
|
except KeyboardInterrupt:
|
|
203
359
|
return True
|
|
204
360
|
|
|
205
|
-
def get_calibration_set_values(self, calibration_set_id: uuid.UUID) -> dict[str, ObservationValue]:
|
|
206
|
-
with wrap_error("Calibration set loading failed"):
|
|
207
|
-
calibrations = proto.CalibrationsStub(self._channel)
|
|
208
|
-
data_chunks = calibrations.GetFullCalibrationDataV1(
|
|
209
|
-
proto.CalibrationLookupV1(
|
|
210
|
-
id=to_proto_uuid(calibration_set_id),
|
|
211
|
-
)
|
|
212
|
-
)
|
|
213
|
-
_, cal_set_values = parse_calibration_set(load_all(data_chunks))
|
|
214
|
-
return cal_set_values
|
|
215
|
-
|
|
216
|
-
def get_latest_calibration_set_id(self, dut_label: str) -> uuid.UUID:
|
|
217
|
-
with wrap_error("Calibration set metadata loading failed"):
|
|
218
|
-
calibrations = proto.CalibrationsStub(self._channel)
|
|
219
|
-
metadata: proto.CalibrationMetadataV1 = calibrations.GetLatestQuantumComputerCalibrationV1(
|
|
220
|
-
proto.LatestQuantumComputerCalibrationLookupV1(
|
|
221
|
-
qc_id=self._current_qc.id,
|
|
222
|
-
)
|
|
223
|
-
)
|
|
224
|
-
if metadata.dut_label != dut_label:
|
|
225
|
-
raise ValueError(f"No calibration set for dut_label = {dut_label}")
|
|
226
|
-
return from_proto_uuid(metadata.id)
|
|
227
|
-
|
|
228
361
|
def _get_cached_sweep(self, sweep_id: uuid.UUID) -> SweepDefinition | None:
|
|
229
362
|
latest_submitted = self._latest_submitted_sweep
|
|
230
363
|
if latest_submitted and latest_submitted.sweep_id == sweep_id:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2025 IQM
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -11,9 +11,12 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
-
"""Station control client
|
|
14
|
+
"""Station control client list types for different models.
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
These are used mainly for easy serialization and deserialization of list of objects.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from typing import Generic, TypeAlias, TypeVar
|
|
17
20
|
|
|
18
21
|
from pydantic import ConfigDict, RootModel
|
|
19
22
|
|
|
@@ -53,17 +56,20 @@ class ListModel(RootModel):
|
|
|
53
56
|
def __len__(self) -> int:
|
|
54
57
|
return len(self.root)
|
|
55
58
|
|
|
59
|
+
def __str__(self) -> str:
|
|
60
|
+
return str(self.root)
|
|
61
|
+
|
|
56
62
|
model_config = ConfigDict(
|
|
57
63
|
ser_json_inf_nan="constants", # Will serialize Infinity and NaN values as Infinity and NaN
|
|
58
64
|
)
|
|
59
65
|
|
|
60
66
|
|
|
61
|
-
DutList = ListModel[list[DutData]]
|
|
62
|
-
DutFieldDataList = ListModel[list[DutFieldData]]
|
|
63
|
-
ObservationDataList = ListModel[list[ObservationData]]
|
|
64
|
-
ObservationDefinitionList = ListModel[list[ObservationDefinition]]
|
|
65
|
-
ObservationLiteList = ListModel[list[ObservationLite]]
|
|
66
|
-
ObservationUpdateList = ListModel[list[ObservationUpdate]]
|
|
67
|
-
ObservationSetDataList = ListModel[list[ObservationSetData]]
|
|
68
|
-
SequenceMetadataDataList = ListModel[list[SequenceMetadataData]]
|
|
69
|
-
RunLiteList = ListModel[list[RunLite]]
|
|
67
|
+
DutList: TypeAlias = ListModel[list[DutData]]
|
|
68
|
+
DutFieldDataList: TypeAlias = ListModel[list[DutFieldData]]
|
|
69
|
+
ObservationDataList: TypeAlias = ListModel[list[ObservationData]]
|
|
70
|
+
ObservationDefinitionList: TypeAlias = ListModel[list[ObservationDefinition]]
|
|
71
|
+
ObservationLiteList: TypeAlias = ListModel[list[ObservationLite]]
|
|
72
|
+
ObservationUpdateList: TypeAlias = ListModel[list[ObservationUpdate]]
|
|
73
|
+
ObservationSetDataList: TypeAlias = ListModel[list[ObservationSetData]]
|
|
74
|
+
SequenceMetadataDataList: TypeAlias = ListModel[list[SequenceMetadataData]]
|
|
75
|
+
RunLiteList: TypeAlias = ListModel[list[RunLite]]
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
#
|
|
2
|
-
# Copyright (c) 2019-2024 IQM Finland Oy.
|
|
3
|
-
# All rights reserved. Confidential and proprietary.
|
|
1
|
+
# Copyright 2025 IQM
|
|
4
2
|
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
8
14
|
"""Serializers and deserializers for :class:`~iqm.models.channel_properties.channel_properties.ChannelProperties`"""
|
|
9
15
|
|
|
10
16
|
from collections.abc import Iterable
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2025 IQM
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -27,8 +27,7 @@ from exa.common.data.setting_node import SettingNode
|
|
|
27
27
|
from exa.common.sweep.database_serialization import decode_and_validate_sweeps, encode_nd_sweeps
|
|
28
28
|
from iqm.station_control.client.serializers.datetime_serializers import deserialize_datetime, serialize_datetime
|
|
29
29
|
from iqm.station_control.client.serializers.playlist_serializers import pack_playlist, unpack_playlist
|
|
30
|
-
from iqm.station_control.interface.models import SweepData, SweepDefinition, SweepResults
|
|
31
|
-
from iqm.station_control.interface.models.jobs import JobExecutorStatus
|
|
30
|
+
from iqm.station_control.interface.models import JobExecutorStatus, SweepData, SweepDefinition, SweepResults
|
|
32
31
|
|
|
33
32
|
|
|
34
33
|
def serialize_sweep_definition(sweep_definition: SweepDefinition) -> SweepDefinitionProto:
|