iqm-station-control-client 9.5.0__tar.gz → 9.7.0__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 (83) hide show
  1. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/CHANGELOG.rst +16 -0
  2. {iqm_station_control_client-9.5.0/src/iqm_station_control_client.egg-info → iqm_station_control_client-9.7.0}/PKG-INFO +4 -1
  3. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/pyproject.toml +8 -0
  4. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/requirements/base.in +3 -0
  5. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/requirements/base.txt +4 -1
  6. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/grpc_utils.py +1 -1
  7. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/iqm_server_client.py +10 -9
  8. iqm_station_control_client-9.7.0/src/iqm/station_control/client/py.typed +0 -0
  9. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/serializers/run_serializers.py +7 -7
  10. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/serializers/sweep_serializers.py +3 -3
  11. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/station_control.py +34 -34
  12. iqm_station_control_client-9.7.0/src/iqm/station_control/interface/py.typed +0 -0
  13. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/interface/station_control.py +5 -5
  14. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0/src/iqm_station_control_client.egg-info}/PKG-INFO +4 -1
  15. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm_station_control_client.egg-info/SOURCES.txt +2 -0
  16. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm_station_control_client.egg-info/requires.txt +3 -0
  17. iqm_station_control_client-9.7.0/version.txt +1 -0
  18. iqm_station_control_client-9.5.0/version.txt +0 -1
  19. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/LICENSE.txt +0 -0
  20. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/MANIFEST.in +0 -0
  21. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/README.rst +0 -0
  22. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/docs/API.rst +0 -0
  23. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/docs/Makefile +0 -0
  24. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/docs/_static/css/custom.css +0 -0
  25. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/docs/_static/images/favicon.ico +0 -0
  26. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/docs/_static/images/logo.png +0 -0
  27. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/docs/_templates/autosummary-class-template.rst +0 -0
  28. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/docs/_templates/autosummary-module-template.rst +0 -0
  29. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/docs/changelog.rst +0 -0
  30. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/docs/conf.py +0 -0
  31. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/docs/index.rst +0 -0
  32. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/docs/license.rst +0 -0
  33. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/setup.cfg +0 -0
  34. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/setup.py +0 -0
  35. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/__init__.py +0 -0
  36. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/__init__.py +0 -0
  37. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/error.py +0 -0
  38. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/proto/__init__.py +0 -0
  39. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/proto/calibration_pb2.py +0 -0
  40. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/proto/calibration_pb2.pyi +0 -0
  41. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/proto/calibration_pb2_grpc.py +0 -0
  42. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/proto/common_pb2.py +0 -0
  43. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/proto/common_pb2.pyi +0 -0
  44. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/proto/common_pb2_grpc.py +0 -0
  45. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/proto/job_pb2.py +0 -0
  46. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/proto/job_pb2.pyi +0 -0
  47. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/proto/job_pb2_grpc.py +0 -0
  48. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/proto/qc_pb2.py +0 -0
  49. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/proto/qc_pb2.pyi +0 -0
  50. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/proto/qc_pb2_grpc.py +0 -0
  51. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/proto/uuid_pb2.py +0 -0
  52. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/proto/uuid_pb2.pyi +0 -0
  53. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/proto/uuid_pb2_grpc.py +0 -0
  54. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/testing/__init__.py +0 -0
  55. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/iqm_server/testing/iqm_server_mock.py +0 -0
  56. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/list_models.py +0 -0
  57. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/serializers/__init__.py +0 -0
  58. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/serializers/channel_property_serializer.py +0 -0
  59. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/serializers/datetime_serializers.py +0 -0
  60. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/serializers/playlist_serializers.py +0 -0
  61. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/serializers/setting_node_serializer.py +0 -0
  62. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/serializers/struct_serializer.py +0 -0
  63. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/serializers/task_serializers.py +0 -0
  64. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/client/utils.py +0 -0
  65. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/interface/__init__.py +0 -0
  66. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/interface/list_with_meta.py +0 -0
  67. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/interface/models/__init__.py +0 -0
  68. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/interface/models/dut.py +0 -0
  69. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/interface/models/dynamic_quantum_architecture.py +0 -0
  70. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/interface/models/jobs.py +0 -0
  71. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/interface/models/monitor.py +0 -0
  72. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/interface/models/observation.py +0 -0
  73. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/interface/models/observation_set.py +0 -0
  74. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/interface/models/run.py +0 -0
  75. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/interface/models/sequence.py +0 -0
  76. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/interface/models/static_quantum_architecture.py +0 -0
  77. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/interface/models/sweep.py +0 -0
  78. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/interface/models/type_aliases.py +0 -0
  79. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm/station_control/interface/pydantic_base.py +0 -0
  80. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm_station_control_client.egg-info/dependency_links.txt +0 -0
  81. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/src/iqm_station_control_client.egg-info/top_level.txt +0 -0
  82. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/tests/.pylintrc +0 -0
  83. {iqm_station_control_client-9.5.0 → iqm_station_control_client-9.7.0}/tests/__init__.py +0 -0
@@ -2,6 +2,22 @@
2
2
  Changelog
3
3
  =========
4
4
 
5
+ Version 9.7.0 (2025-07-10)
6
+ ==========================
7
+
8
+ Bug fix
9
+ -------
10
+
11
+ - Better error handling when using IQM Server.
12
+
13
+ Version 9.6.0 (2025-07-09)
14
+ ==========================
15
+
16
+ Features
17
+ --------
18
+
19
+ - Enable mypy type checking in CI and add temporary type ignores to the source code. :issue:`SW-1615`
20
+
5
21
  Version 9.5.0 (2025-07-07)
6
22
  ==========================
7
23
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: iqm-station-control-client
3
- Version: 9.5.0
3
+ Version: 9.7.0
4
4
  Summary: Python client for communicating with Station Control Service
5
5
  Author-email: IQM Finland Oy <info@meetiqm.com>
6
6
  License: Apache License
@@ -217,11 +217,14 @@ Requires-Dist: iqm-exa-common<27,>=26
217
217
  Requires-Dist: iqm-data-definitions<3.0,>=2.13
218
218
  Requires-Dist: opentelemetry-exporter-otlp==1.25.0
219
219
  Requires-Dist: protobuf<5.0,>=4.25.3
220
+ Requires-Dist: types-protobuf
220
221
  Requires-Dist: grpcio<2.0,>=1.65.4
221
222
  Requires-Dist: pydantic<3.0,>=2.10.4
222
223
  Requires-Dist: PyYAML==6.0
223
224
  Requires-Dist: requests==2.32.3
225
+ Requires-Dist: types-requests
224
226
  Requires-Dist: tqdm>=4.59.0
227
+ Requires-Dist: types-tqdm
225
228
 
226
229
  Station control client library
227
230
  ==============================
@@ -21,6 +21,14 @@ file = "LICENSE.txt"
21
21
  Documentation = "https://iqm-finland.github.io/docs/iqm-station-control-client/"
22
22
  Homepage = "https://pypi.org/project/iqm-station-control-client/"
23
23
 
24
+ [tool.mypy]
25
+ explicit_package_bases = true
26
+ mypy_path = "$MYPY_CONFIG_FILE_DIR/src"
27
+ namespace_packages = true
28
+ [[tool.mypy.overrides]]
29
+ module = [ "iqm.data_definitions.*", "iqm.models.*", "daemon.*", "quimb.*", "qiskit.*", "qiskit_aer.*", "grpc.*", "lmfit.*", "emukit.*", "mockito.*", "sklearn.*", "dill.*", "uncertainties.*", "GPy.*", "pythonjsonlogger.*",]
30
+ ignore_missing_imports = true
31
+
24
32
  [tool.ruff]
25
33
  exclude = [ "*.ipynb", "*.rst",]
26
34
  extend-exclude = [ "src/iqm/station_control/client/iqm_server/proto",]
@@ -1,8 +1,11 @@
1
1
  iqm-data-definitions >= 2.13, < 3.0
2
2
  opentelemetry-exporter-otlp == 1.25.0
3
3
  protobuf >= 4.25.3, < 5.0
4
+ types-protobuf
4
5
  grpcio >= 1.65.4, < 2.0
5
6
  pydantic >= 2.10.4, <3.0
6
7
  PyYAML == 6.0
7
8
  requests == 2.32.3
9
+ types-requests
8
10
  tqdm >= 4.59.0
11
+ types-tqdm
@@ -2,8 +2,11 @@ iqm-exa-common>=26,<27
2
2
  iqm-data-definitions >= 2.13, < 3.0
3
3
  opentelemetry-exporter-otlp == 1.25.0
4
4
  protobuf >= 4.25.3, < 5.0
5
+ types-protobuf
5
6
  grpcio >= 1.65.4, < 2.0
6
7
  pydantic >= 2.10.4, <3.0
7
8
  PyYAML == 6.0
8
9
  requests == 2.32.3
9
- tqdm >= 4.59.0
10
+ types-requests
11
+ tqdm >= 4.59.0
12
+ types-tqdm
@@ -152,5 +152,5 @@ def extract_error(error: grpc.RpcError, title: str | None = None) -> IqmServerEr
152
152
  message=f"{title}: {message}" if title else message,
153
153
  status_code=status_code,
154
154
  error_code=error_code,
155
- details=details,
155
+ details=details, # type: ignore[arg-type]
156
156
  )
@@ -146,7 +146,7 @@ class IqmServerClient(_StationControlClientBase):
146
146
  # right after submitting it so we can cache reference to the submitted sweep here
147
147
  # to avoid extra request to the server
148
148
  job_id = from_proto_uuid(job.id)
149
- self._latest_submitted_sweep = dataclasses.replace(sweep_definition, sweep_id=job_id)
149
+ self._latest_submitted_sweep = dataclasses.replace(sweep_definition, sweep_id=job_id) # type: ignore[assignment]
150
150
  return {
151
151
  "job_id": str(job_id),
152
152
  }
@@ -194,12 +194,12 @@ class IqmServerClient(_StationControlClientBase):
194
194
  def get_run(self, run_id: UUID) -> RunData:
195
195
  raise NotImplementedError
196
196
 
197
- def query_runs(self, **kwargs) -> ListWithMeta[RunLite]:
197
+ def query_runs(self, **kwargs) -> ListWithMeta[RunLite]: # type: ignore[type-arg]
198
198
  raise NotImplementedError
199
199
 
200
200
  def create_observations(
201
201
  self, observation_definitions: Sequence[ObservationDefinition]
202
- ) -> ListWithMeta[ObservationData]:
202
+ ) -> ListWithMeta[ObservationData]: # type: ignore[type-arg]
203
203
  raise NotImplementedError
204
204
 
205
205
  def get_observations(
@@ -216,13 +216,13 @@ class IqmServerClient(_StationControlClientBase):
216
216
  ) -> list[ObservationData]:
217
217
  raise NotImplementedError
218
218
 
219
- def query_observations(self, **kwargs) -> ListWithMeta[ObservationData]:
219
+ def query_observations(self, **kwargs) -> ListWithMeta[ObservationData]: # type: ignore[type-arg]
220
220
  raise NotImplementedError
221
221
 
222
222
  def update_observations(self, observation_updates: Sequence[ObservationUpdate]) -> list[ObservationData]:
223
223
  raise NotImplementedError
224
224
 
225
- def query_observation_sets(self, **kwargs) -> ListWithMeta[ObservationSetData]:
225
+ def query_observation_sets(self, **kwargs) -> ListWithMeta[ObservationSetData]: # type: ignore[type-arg]
226
226
  raise NotImplementedError
227
227
 
228
228
  def create_observation_set(self, observation_set_definition: ObservationSetDefinition) -> ObservationSetData:
@@ -260,14 +260,15 @@ class IqmServerClient(_StationControlClientBase):
260
260
  raise NotImplementedError
261
261
 
262
262
  def get_duts(self) -> list[DutData]:
263
- return self._get_resource("duts", lambda data: DutList.model_validate(parse_json(data)))
263
+ return self._get_resource("duts", lambda data: DutList.model_validate(parse_json(data))) # type: ignore[arg-type,return-value]
264
264
 
265
265
  def get_dut_fields(self, dut_label: str) -> list[DutFieldData]:
266
266
  return self._get_resource(
267
- f"dut-fields/{dut_label}", lambda data: DutFieldDataList.model_validate(parse_json(data))
267
+ f"dut-fields/{dut_label}",
268
+ lambda data: DutFieldDataList.model_validate(parse_json(data)), # type: ignore[arg-type,return-value]
268
269
  )
269
270
 
270
- def query_sequence_metadatas(self, **kwargs) -> ListWithMeta[SequenceMetadataData]:
271
+ def query_sequence_metadatas(self, **kwargs) -> ListWithMeta[SequenceMetadataData]: # type: ignore[type-arg]
271
272
  raise NotImplementedError
272
273
 
273
274
  def create_sequence_metadata(
@@ -291,7 +292,7 @@ class IqmServerClient(_StationControlClientBase):
291
292
  job: proto.JobV1 = jobs.GetJobV1(proto.JobLookupV1(id=to_proto_uuid(job_id)))
292
293
  return JobData(
293
294
  job_id=from_proto_uuid(job.id),
294
- job_status=job.status,
295
+ job_status=job.status, # type: ignore[arg-type]
295
296
  job_result=JobResult(
296
297
  job_id=from_proto_uuid(job.id),
297
298
  parallel_sweep_progress=[],
@@ -40,8 +40,8 @@ def serialize_run_definition(run_definition: RunDefinition) -> RunDefinitionProt
40
40
  username=run_definition.username,
41
41
  experiment_name=run_definition.experiment_name,
42
42
  experiment_label=run_definition.experiment_label,
43
- options=serialize_struct(run_definition.options),
44
- additional_run_properties=serialize_struct(run_definition.additional_run_properties),
43
+ options=serialize_struct(run_definition.options), # type: ignore[arg-type]
44
+ additional_run_properties=serialize_struct(run_definition.additional_run_properties), # type: ignore[arg-type]
45
45
  software_version_set_id=run_definition.software_version_set_id,
46
46
  components=run_definition.components,
47
47
  default_data_parameters=run_definition.default_data_parameters,
@@ -50,7 +50,7 @@ def serialize_run_definition(run_definition: RunDefinition) -> RunDefinitionProt
50
50
  run_definition_proto.sweep_definition_payload.Pack(
51
51
  serialize_sweep_definition(run_definition.sweep_definition), type_url_prefix="iqm-data-definitions"
52
52
  )
53
- for key, sweep in run_definition.hard_sweeps.items():
53
+ for key, sweep in run_definition.hard_sweeps.items(): # type: ignore[union-attr]
54
54
  run_definition_proto.hard_sweeps[key].CopyFrom(proto_serialization.nd_sweep.pack(sweep, minimal=False))
55
55
  return run_definition_proto
56
56
 
@@ -94,7 +94,7 @@ def serialize_run_data(run_data: RunData) -> dict:
94
94
  "options": run_data.options,
95
95
  "additional_run_properties": run_data.additional_run_properties,
96
96
  "software_version_set_id": run_data.software_version_set_id,
97
- "hard_sweeps": {key: encode_nd_sweeps(value) for key, value in run_data.hard_sweeps.items()},
97
+ "hard_sweeps": {key: encode_nd_sweeps(value) for key, value in run_data.hard_sweeps.items()}, # type: ignore[union-attr]
98
98
  "components": run_data.components,
99
99
  "default_data_parameters": run_data.default_data_parameters,
100
100
  "default_sweep_parameters": run_data.default_sweep_parameters,
@@ -124,8 +124,8 @@ def deserialize_run_data(data: dict) -> RunData:
124
124
  default_data_parameters=data["default_data_parameters"],
125
125
  default_sweep_parameters=data["default_sweep_parameters"],
126
126
  sweep_data=deserialize_sweep_data(data["sweep_data"]),
127
- created_timestamp=deserialize_datetime(data["created_timestamp"]),
128
- modified_timestamp=deserialize_datetime(data["modified_timestamp"]),
129
- begin_timestamp=deserialize_datetime(data["begin_timestamp"]),
127
+ created_timestamp=deserialize_datetime(data["created_timestamp"]), # type: ignore[arg-type]
128
+ modified_timestamp=deserialize_datetime(data["modified_timestamp"]), # type: ignore[arg-type]
129
+ begin_timestamp=deserialize_datetime(data["begin_timestamp"]), # type: ignore[arg-type]
130
130
  end_timestamp=deserialize_datetime(data["end_timestamp"]),
131
131
  )
@@ -84,10 +84,10 @@ def deserialize_sweep_data(data: dict) -> SweepData:
84
84
  sweep_id=uuid.UUID(data["sweep_id"]),
85
85
  dut_label=data["dut_label"],
86
86
  settings=SettingNode(**json.loads(data["settings"])),
87
- sweeps=decode_and_validate_sweeps(data["sweeps"]),
87
+ sweeps=decode_and_validate_sweeps(data["sweeps"]), # type: ignore[arg-type]
88
88
  return_parameters=data["return_parameters"],
89
- created_timestamp=deserialize_datetime(data["created_timestamp"]),
90
- modified_timestamp=deserialize_datetime(data["modified_timestamp"]),
89
+ created_timestamp=deserialize_datetime(data["created_timestamp"]), # type: ignore[arg-type]
90
+ modified_timestamp=deserialize_datetime(data["modified_timestamp"]), # type: ignore[arg-type]
91
91
  begin_timestamp=deserialize_datetime(data["begin_timestamp"]),
92
92
  end_timestamp=deserialize_datetime(data["end_timestamp"]),
93
93
  job_status=JobExecutorStatus(data["job_status"]),
@@ -181,12 +181,12 @@ class _StationControlClientBase(StationControlInterface):
181
181
  if not response.ok:
182
182
  try:
183
183
  response_json = response.json()
184
- error_message = response_json["detail"]
185
- except json.JSONDecodeError:
184
+ error_message = response_json.get("message") or response_json["detail"]
185
+ except (json.JSONDecodeError, KeyError):
186
186
  error_message = response.text
187
187
 
188
188
  try:
189
- error_class = map_from_status_code_to_error(response.status_code)
189
+ error_class = map_from_status_code_to_error(response.status_code) # type: ignore[arg-type]
190
190
  except KeyError:
191
191
  raise RuntimeError(f"Unexpected response status code {response.status_code}: {error_message}")
192
192
 
@@ -350,14 +350,14 @@ class StationControlClient(_StationControlClientBase):
350
350
  response = self._send_request(requests.get, f"runs/{run_id}")
351
351
  return deserialize_run_data(response.json())
352
352
 
353
- def query_runs(self, **kwargs) -> ListWithMeta[RunLite]:
353
+ def query_runs(self, **kwargs) -> ListWithMeta[RunLite]: # type: ignore[type-arg]
354
354
  params = self._clean_query_parameters(RunData, **kwargs)
355
355
  response = self._send_request(requests.get, "runs", params=params)
356
356
  return self._deserialize_response(response, RunLiteList, list_with_meta=True)
357
357
 
358
358
  def create_observations(
359
359
  self, observation_definitions: Sequence[ObservationDefinition]
360
- ) -> ListWithMeta[ObservationData]:
360
+ ) -> ListWithMeta[ObservationData]: # type: ignore[type-arg]
361
361
  json_str = self._serialize_model(ObservationDefinitionList(observation_definitions))
362
362
  response = self._send_request(requests.post, "observations", json_str=json_str)
363
363
  return self._deserialize_response(response, ObservationDataList, list_with_meta=True)
@@ -370,8 +370,8 @@ class StationControlClient(_StationControlClientBase):
370
370
  dut_field: str | None = None,
371
371
  tags: list[str] | None = None,
372
372
  invalid: bool | None = False,
373
- run_ids: list[StrUUID] | None = None,
374
- sequence_ids: list[StrUUID] | None = None,
373
+ run_ids: list[StrUUID] | None = None, # type: ignore[override]
374
+ sequence_ids: list[StrUUID] | None = None, # type: ignore[override]
375
375
  limit: int | None = None,
376
376
  ) -> list[ObservationData]:
377
377
  kwargs = {
@@ -388,7 +388,7 @@ class StationControlClient(_StationControlClientBase):
388
388
  response = self._send_request(requests.get, "observations", params=params)
389
389
  return self._deserialize_response(response, ObservationDataList)
390
390
 
391
- def query_observations(self, **kwargs) -> ListWithMeta[ObservationData]:
391
+ def query_observations(self, **kwargs) -> ListWithMeta[ObservationData]: # type: ignore[type-arg]
392
392
  params = self._clean_query_parameters(ObservationData, **kwargs)
393
393
  response = self._send_request(requests.get, "observations", params=params)
394
394
  return self._deserialize_response(response, ObservationDataList, list_with_meta=True)
@@ -398,7 +398,7 @@ class StationControlClient(_StationControlClientBase):
398
398
  response = self._send_request(requests.patch, "observations", json_str=json_str)
399
399
  return self._deserialize_response(response, ObservationDataList)
400
400
 
401
- def query_observation_sets(self, **kwargs) -> ListWithMeta[ObservationSetData]:
401
+ def query_observation_sets(self, **kwargs) -> ListWithMeta[ObservationSetData]: # type: ignore[type-arg]
402
402
  params = self._clean_query_parameters(ObservationSetData, **kwargs)
403
403
  response = self._send_request(requests.get, "observation-sets", params=params)
404
404
  return self._deserialize_response(response, ObservationSetDataList, list_with_meta=True)
@@ -406,16 +406,16 @@ class StationControlClient(_StationControlClientBase):
406
406
  def create_observation_set(self, observation_set_definition: ObservationSetDefinition) -> ObservationSetData:
407
407
  json_str = self._serialize_model(observation_set_definition)
408
408
  response = self._send_request(requests.post, "observation-sets", json_str=json_str)
409
- return self._deserialize_response(response, ObservationSetData)
409
+ return self._deserialize_response(response, ObservationSetData) # type: ignore[return-value]
410
410
 
411
411
  def get_observation_set(self, observation_set_id: StrUUID) -> ObservationSetData:
412
412
  response = self._send_request(requests.get, f"observation-sets/{observation_set_id}")
413
- return self._deserialize_response(response, ObservationSetData)
413
+ return self._deserialize_response(response, ObservationSetData) # type: ignore[return-value]
414
414
 
415
415
  def update_observation_set(self, observation_set_update: ObservationSetUpdate) -> ObservationSetData:
416
416
  json_str = self._serialize_model(observation_set_update)
417
417
  response = self._send_request(requests.patch, "observation-sets", json_str=json_str)
418
- return self._deserialize_response(response, ObservationSetData)
418
+ return self._deserialize_response(response, ObservationSetData) # type: ignore[return-value]
419
419
 
420
420
  def finalize_observation_set(self, observation_set_id: StrUUID) -> None:
421
421
  self._send_request(requests.post, f"observation-sets/{observation_set_id}/finalize")
@@ -426,7 +426,7 @@ class StationControlClient(_StationControlClientBase):
426
426
 
427
427
  def get_default_calibration_set(self) -> ObservationSetData:
428
428
  response = self._send_request(requests.get, "calibration-sets/default")
429
- return self._deserialize_response(response, ObservationSetData)
429
+ return self._deserialize_response(response, ObservationSetData) # type: ignore[return-value]
430
430
 
431
431
  def get_default_calibration_set_observations(self) -> list[ObservationLite]:
432
432
  response = self._send_request(requests.get, "calibration-sets/default/observations")
@@ -434,22 +434,22 @@ class StationControlClient(_StationControlClientBase):
434
434
 
435
435
  def get_default_dynamic_quantum_architecture(self) -> DynamicQuantumArchitecture:
436
436
  response = self._send_request(requests.get, "calibration-sets/default/dynamic-quantum-architecture")
437
- return self._deserialize_response(response, DynamicQuantumArchitecture)
437
+ return self._deserialize_response(response, DynamicQuantumArchitecture) # type: ignore[return-value]
438
438
 
439
439
  @cache
440
440
  def get_dynamic_quantum_architecture(self, calibration_set_id: StrUUID) -> DynamicQuantumArchitecture:
441
441
  response = self._send_request(
442
442
  requests.get, f"calibration-sets/{calibration_set_id}/dynamic-quantum-architecture"
443
443
  )
444
- return self._deserialize_response(response, DynamicQuantumArchitecture)
444
+ return self._deserialize_response(response, DynamicQuantumArchitecture) # type: ignore[return-value]
445
445
 
446
446
  def get_default_calibration_set_quality_metrics(self) -> QualityMetrics:
447
447
  response = self._send_request(requests.get, "calibration-sets/default/metrics")
448
- return self._deserialize_response(response, QualityMetrics)
448
+ return self._deserialize_response(response, QualityMetrics) # type: ignore[return-value]
449
449
 
450
450
  def get_calibration_set_quality_metrics(self, calibration_set_id: StrUUID) -> QualityMetrics:
451
451
  response = self._send_request(requests.get, f"calibration-sets/{calibration_set_id}/metrics")
452
- return self._deserialize_response(response, QualityMetrics)
452
+ return self._deserialize_response(response, QualityMetrics) # type: ignore[return-value]
453
453
 
454
454
  def get_duts(self) -> list[DutData]:
455
455
  response = self._send_request(requests.get, "duts")
@@ -460,7 +460,7 @@ class StationControlClient(_StationControlClientBase):
460
460
  response = self._send_request(requests.get, "dut-fields", params=params)
461
461
  return self._deserialize_response(response, DutFieldDataList)
462
462
 
463
- def query_sequence_metadatas(self, **kwargs) -> ListWithMeta[SequenceMetadataData]:
463
+ def query_sequence_metadatas(self, **kwargs) -> ListWithMeta[SequenceMetadataData]: # type: ignore[type-arg]
464
464
  params = self._clean_query_parameters(SequenceMetadataData, **kwargs)
465
465
  response = self._send_request(requests.get, "sequence-metadatas", params=params)
466
466
  return self._deserialize_response(response, SequenceMetadataDataList, list_with_meta=True)
@@ -470,7 +470,7 @@ class StationControlClient(_StationControlClientBase):
470
470
  ) -> SequenceMetadataData:
471
471
  json_str = self._serialize_model(sequence_metadata_definition)
472
472
  response = self._send_request(requests.post, "sequence-metadatas", json_str=json_str)
473
- return self._deserialize_response(response, SequenceMetadataData)
473
+ return self._deserialize_response(response, SequenceMetadataData) # type: ignore[return-value]
474
474
 
475
475
  def save_sequence_result(self, sequence_result_definition: SequenceResultDefinition) -> SequenceResultData:
476
476
  # FIXME: We don't have information if the object was created or updated. Thus, server always responds 200 (OK).
@@ -478,20 +478,20 @@ class StationControlClient(_StationControlClientBase):
478
478
  response = self._send_request(
479
479
  requests.put, f"sequence-results/{sequence_result_definition.sequence_id}", json_str=json_str
480
480
  )
481
- return self._deserialize_response(response, SequenceResultData)
481
+ return self._deserialize_response(response, SequenceResultData) # type: ignore[return-value]
482
482
 
483
483
  def get_sequence_result(self, sequence_id: StrUUID) -> SequenceResultData:
484
484
  response = self._send_request(requests.get, f"sequence-results/{sequence_id}")
485
- return self._deserialize_response(response, SequenceResultData)
485
+ return self._deserialize_response(response, SequenceResultData) # type: ignore[return-value]
486
486
 
487
487
  @cache
488
488
  def get_static_quantum_architecture(self, dut_label: str) -> StaticQuantumArchitecture:
489
489
  response = self._send_request(requests.get, f"static-quantum-architectures/{dut_label}")
490
- return self._deserialize_response(response, StaticQuantumArchitecture)
490
+ return self._deserialize_response(response, StaticQuantumArchitecture) # type: ignore[return-value]
491
491
 
492
492
  def get_job(self, job_id: StrUUID) -> JobData:
493
493
  response = self._send_request(requests.get, f"jobs/{job_id}")
494
- return self._deserialize_response(response, JobData)
494
+ return self._deserialize_response(response, JobData) # type: ignore[return-value]
495
495
 
496
496
  def abort_job(self, job_id: StrUUID) -> None:
497
497
  self._send_request(requests.post, f"jobs/{job_id}/abort")
@@ -516,7 +516,7 @@ class StationControlClient(_StationControlClientBase):
516
516
  max_seen_position = 0
517
517
  while True:
518
518
  job = self._poll_job(job_id)
519
- if job.job_status >= JobExecutorStatus.EXECUTION_STARTED:
519
+ if job.job_status >= JobExecutorStatus.EXECUTION_STARTED: # type: ignore[operator]
520
520
  if max_seen_position:
521
521
  update_progress_callback([("Progress in queue", max_seen_position, max_seen_position)])
522
522
  return job.job_status
@@ -525,8 +525,8 @@ class StationControlClient(_StationControlClientBase):
525
525
  if position == 0:
526
526
  sleep(1)
527
527
  continue
528
- max_seen_position = max(max_seen_position, position)
529
- update_progress_callback([("Progress in queue", max_seen_position - position, max_seen_position)])
528
+ max_seen_position = max(max_seen_position, position) # type: ignore[type-var,assignment]
529
+ update_progress_callback([("Progress in queue", max_seen_position - position, max_seen_position)]) # type: ignore[operator]
530
530
  sleep(1)
531
531
 
532
532
  def _poll_job_status_until_terminal(
@@ -545,9 +545,9 @@ class StationControlClient(_StationControlClientBase):
545
545
  def _poll_job(self, job_id: str) -> JobData:
546
546
  response = self._send_request(requests.get, f"jobs/{job_id}")
547
547
  job = self._deserialize_response(response, JobData)
548
- if job.job_status == JobExecutorStatus.FAILED:
549
- raise InternalServerError(f"Job: {job.job_id}\n{job.job_error}")
550
- return job
548
+ if job.job_status == JobExecutorStatus.FAILED: # type: ignore[union-attr]
549
+ raise InternalServerError(f"Job: {job.job_id}\n{job.job_error}") # type: ignore[union-attr] # type: ignore[union-attr]
550
+ return job # type: ignore[return-value]
551
551
 
552
552
  @staticmethod
553
553
  def _serialize_model(model: BaseModel) -> str:
@@ -612,22 +612,22 @@ class StationControlClient(_StationControlClientBase):
612
612
  @staticmethod
613
613
  def _deserialize_response(
614
614
  response: requests.Response,
615
- model_class: type[TypePydanticBase | ListModel[list[TypePydanticBase]]],
615
+ model_class: type[TypePydanticBase | ListModel[list[TypePydanticBase]]], # type: ignore[type-arg]
616
616
  *,
617
617
  list_with_meta: bool = False,
618
- ) -> TypePydanticBase | ListWithMeta[TypePydanticBase]:
618
+ ) -> TypePydanticBase | ListWithMeta[TypePydanticBase]: # type: ignore[type-arg]
619
619
  # Use "model_validate_json(response.text)" instead of "model_validate(response.json())".
620
620
  # This validates the provided data as a JSON string or bytes object.
621
621
  # If your incoming data is a JSON payload, this is generally considered faster.
622
622
  if list_with_meta:
623
- response_with_meta = ResponseWithMeta.model_validate_json(response.text)
623
+ response_with_meta = ResponseWithMeta.model_validate_json(response.text) # type: ignore[var-annotated]
624
624
  if response_with_meta.meta and response_with_meta.meta.errors:
625
625
  logger.warning(
626
626
  "Errors in station control response:\n - %s", "\n - ".join(response_with_meta.meta.errors)
627
627
  )
628
- return ListWithMeta(model_class.model_validate(response_with_meta.items), meta=response_with_meta.meta)
628
+ return ListWithMeta(model_class.model_validate(response_with_meta.items), meta=response_with_meta.meta) # type: ignore[arg-type]
629
629
  model = model_class.model_validate_json(response.text)
630
- return model
630
+ return model # type: ignore[return-value]
631
631
 
632
632
 
633
633
  def _remove_empty_values(kwargs: dict[str, Any]) -> dict[str, Any]:
@@ -194,7 +194,7 @@ class StationControlInterface(ABC):
194
194
  """Get run data from the database."""
195
195
 
196
196
  @abstractmethod
197
- def query_runs(self, **kwargs) -> ListWithMeta[RunLite]:
197
+ def query_runs(self, **kwargs) -> ListWithMeta[RunLite]: # type: ignore[type-arg]
198
198
  """Query runs from the database.
199
199
 
200
200
  Runs are queried by the given query parameters. Currently supported query parameters:
@@ -228,7 +228,7 @@ class StationControlInterface(ABC):
228
228
  @abstractmethod
229
229
  def create_observations(
230
230
  self, observation_definitions: Sequence[ObservationDefinition]
231
- ) -> ListWithMeta[ObservationData]:
231
+ ) -> ListWithMeta[ObservationData]: # type: ignore[type-arg]
232
232
  """Create observations in the database.
233
233
 
234
234
  Args:
@@ -285,7 +285,7 @@ class StationControlInterface(ABC):
285
285
  """
286
286
 
287
287
  @abstractmethod
288
- def query_observations(self, **kwargs) -> ListWithMeta[ObservationData]:
288
+ def query_observations(self, **kwargs) -> ListWithMeta[ObservationData]: # type: ignore[type-arg]
289
289
  """Query observations from the database.
290
290
 
291
291
  Observations are queried by the given query parameters. Currently supported query parameters:
@@ -324,7 +324,7 @@ class StationControlInterface(ABC):
324
324
  """
325
325
 
326
326
  @abstractmethod
327
- def query_observation_sets(self, **kwargs) -> ListWithMeta[ObservationSetData]:
327
+ def query_observation_sets(self, **kwargs) -> ListWithMeta[ObservationSetData]: # type: ignore[type-arg]
328
328
  """Query observation sets from the database.
329
329
 
330
330
  Observation sets are queried by the given query parameters. Currently supported query parameters:
@@ -455,7 +455,7 @@ class StationControlInterface(ABC):
455
455
  """Get DUT fields for the specified DUT label from the database."""
456
456
 
457
457
  @abstractmethod
458
- def query_sequence_metadatas(self, **kwargs) -> ListWithMeta[SequenceMetadataData]:
458
+ def query_sequence_metadatas(self, **kwargs) -> ListWithMeta[SequenceMetadataData]: # type: ignore[type-arg]
459
459
  """Query sequence metadatas from the database.
460
460
 
461
461
  Sequence metadatas are queried by the given query parameters. Currently supported query parameters:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: iqm-station-control-client
3
- Version: 9.5.0
3
+ Version: 9.7.0
4
4
  Summary: Python client for communicating with Station Control Service
5
5
  Author-email: IQM Finland Oy <info@meetiqm.com>
6
6
  License: Apache License
@@ -217,11 +217,14 @@ Requires-Dist: iqm-exa-common<27,>=26
217
217
  Requires-Dist: iqm-data-definitions<3.0,>=2.13
218
218
  Requires-Dist: opentelemetry-exporter-otlp==1.25.0
219
219
  Requires-Dist: protobuf<5.0,>=4.25.3
220
+ Requires-Dist: types-protobuf
220
221
  Requires-Dist: grpcio<2.0,>=1.65.4
221
222
  Requires-Dist: pydantic<3.0,>=2.10.4
222
223
  Requires-Dist: PyYAML==6.0
223
224
  Requires-Dist: requests==2.32.3
225
+ Requires-Dist: types-requests
224
226
  Requires-Dist: tqdm>=4.59.0
227
+ Requires-Dist: types-tqdm
225
228
 
226
229
  Station control client library
227
230
  ==============================
@@ -20,6 +20,7 @@ requirements/base.in
20
20
  requirements/base.txt
21
21
  src/iqm/station_control/client/__init__.py
22
22
  src/iqm/station_control/client/list_models.py
23
+ src/iqm/station_control/client/py.typed
23
24
  src/iqm/station_control/client/station_control.py
24
25
  src/iqm/station_control/client/utils.py
25
26
  src/iqm/station_control/client/iqm_server/__init__.py
@@ -55,6 +56,7 @@ src/iqm/station_control/client/serializers/sweep_serializers.py
55
56
  src/iqm/station_control/client/serializers/task_serializers.py
56
57
  src/iqm/station_control/interface/__init__.py
57
58
  src/iqm/station_control/interface/list_with_meta.py
59
+ src/iqm/station_control/interface/py.typed
58
60
  src/iqm/station_control/interface/pydantic_base.py
59
61
  src/iqm/station_control/interface/station_control.py
60
62
  src/iqm/station_control/interface/models/__init__.py
@@ -2,8 +2,11 @@ iqm-exa-common<27,>=26
2
2
  iqm-data-definitions<3.0,>=2.13
3
3
  opentelemetry-exporter-otlp==1.25.0
4
4
  protobuf<5.0,>=4.25.3
5
+ types-protobuf
5
6
  grpcio<2.0,>=1.65.4
6
7
  pydantic<3.0,>=2.10.4
7
8
  PyYAML==6.0
8
9
  requests==2.32.3
10
+ types-requests
9
11
  tqdm>=4.59.0
12
+ types-tqdm
@@ -0,0 +1 @@
1
+ 9.7.0
@@ -1 +0,0 @@
1
- 9.5.0