iqm-exa-common 27.3.1__py3-none-any.whl → 27.4.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.
@@ -20,8 +20,7 @@ from iqm.data_definitions.common.v1.sweep_pb2 import SingleParameterSweep as spb
20
20
 
21
21
  from exa.common.api.proto_serialization import sequence
22
22
  import exa.common.api.proto_serialization._parameter as param_proto
23
- from exa.common.control.sweep.sweep import Sweep
24
- from exa.common.data.parameter import DataType, Parameter
23
+ from exa.common.data.parameter import DataType, Parameter, Sweep
25
24
  from exa.common.sweep.util import NdSweep
26
25
 
27
26
 
@@ -12,43 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- """Base immutable class for sweeps specifications."""
15
+ """Deprecated import path for :class:`.Sweep`."""
16
16
 
17
- from typing import Any
18
-
19
- from exa.common.control.sweep.option import CenterSpanOptions, StartStopOptions
20
- from exa.common.control.sweep.sweep_values import SweepValues
21
- from exa.common.data.base_model import BaseModel
22
- from exa.common.data.parameter import Parameter
23
-
24
-
25
- class Sweep(BaseModel):
26
- """Base immutable class for sweeps."""
27
-
28
- parameter: Parameter
29
- """The Sweep represents changing the values of this Parameter."""
30
-
31
- data: SweepValues
32
- """List of values for :attr:`parameter`"""
33
-
34
- def model_post_init(self, __context: Any) -> None:
35
- if not all(self.parameter.validate(value) for value in self.data):
36
- raise ValueError(f"Invalid range data {self.data} for parameter type {self.parameter.data_type}.")
37
-
38
- @classmethod
39
- def __from_center_span(cls, parameter: Parameter, options: CenterSpanOptions) -> SweepValues:
40
- cls._validate_value(parameter, options.center, "center")
41
- cls._validate_value(parameter, options.span, "span")
42
- return options.data
43
-
44
- @classmethod
45
- def __from_start_stop(cls, parameter: Parameter, options: StartStopOptions) -> SweepValues:
46
- cls._validate_value(parameter, options.start, "start")
47
- cls._validate_value(parameter, options.stop, "stop")
48
- cls._validate_value(parameter, options.step, "step") # type: ignore[arg-type]
49
- return options.data
50
-
51
- @staticmethod
52
- def _validate_value(parameter: Parameter, value: complex | str | bool, value_label: str) -> None:
53
- if not parameter.validate(value):
54
- raise ValueError(f"Invalid {value_label} value {value} for parameter type {parameter.data_type}.")
17
+ from ...data.parameter import Sweep # noqa: F401 # Reimport for backwards compatibility
@@ -600,3 +600,29 @@ class Setting(BaseModel):
600
600
  def with_path_name(self) -> Setting:
601
601
  """Copy of self with the parameter name replaced by the path name."""
602
602
  return self.model_copy(update={"parameter": self.parameter.model_copy(update={"name": self.path})})
603
+
604
+ def sweep(self, values: SweepValues) -> Sweep:
605
+ """Create a Sweep object that represents a 1d scan of this setting over the given values.
606
+
607
+ Args:
608
+ values: Sweep values.
609
+
610
+ Returns:
611
+ The Sweep object.
612
+
613
+ """
614
+ return Sweep(parameter=self.parameter, data=values)
615
+
616
+
617
+ class Sweep(BaseModel):
618
+ """Base immutable class for sweeps."""
619
+
620
+ parameter: Parameter
621
+ """The Sweep represents changing the values of this Parameter."""
622
+
623
+ data: SweepValues
624
+ """List of values for :attr:`parameter`"""
625
+
626
+ def model_post_init(self, __context: Any) -> None:
627
+ if not all(self.parameter.validate(value) for value in self.data):
628
+ raise ValueError(f"Invalid range data {self.data} for parameter type {self.parameter.data_type}.")
@@ -64,10 +64,18 @@ class ConflictError(StationControlError):
64
64
  """
65
65
 
66
66
 
67
+ class PayloadTooLargeError(StationControlError):
68
+ """This error happens when the request payload is too large."""
69
+
70
+
67
71
  class ValidationError(StationControlError):
68
72
  """Error raised when something is unprocessable in general, for example if the input value is not acceptable."""
69
73
 
70
74
 
75
+ class TooManyRequestsError(StationControlError):
76
+ """Error raised when the user has sent too many requests in a given amount of time ("rate limiting")."""
77
+
78
+
71
79
  class InternalServerError(StationControlError):
72
80
  """Error raised when an unexpected error happened on the server side.
73
81
 
@@ -94,7 +102,9 @@ _ERROR_TO_STATUS_CODE_MAPPING = {
94
102
  ForbiddenError: HTTPStatus.FORBIDDEN, # 403
95
103
  NotFoundError: HTTPStatus.NOT_FOUND, # 404
96
104
  ConflictError: HTTPStatus.CONFLICT, # 409
105
+ PayloadTooLargeError: HTTPStatus.REQUEST_ENTITY_TOO_LARGE, # 413
97
106
  ValidationError: HTTPStatus.UNPROCESSABLE_ENTITY, # 422
107
+ TooManyRequestsError: HTTPStatus.TOO_MANY_REQUESTS, # 429
98
108
  InternalServerError: HTTPStatus.INTERNAL_SERVER_ERROR, # 500
99
109
  BadGatewayError: HTTPStatus.BAD_GATEWAY, # 502
100
110
  ServiceUnavailableError: HTTPStatus.SERVICE_UNAVAILABLE, # 503
@@ -115,6 +125,8 @@ def map_from_error_to_status_code(error: StationControlError) -> HTTPStatus:
115
125
  return HTTPStatus.INTERNAL_SERVER_ERROR
116
126
 
117
127
 
118
- def map_from_status_code_to_error(status_code: HTTPStatus) -> type[StationControlError]:
128
+ def map_from_status_code_to_error(status_code: HTTPStatus | int) -> type[StationControlError]:
119
129
  """Map an HTTPStatus code to a StationControlError."""
130
+ if isinstance(status_code, int):
131
+ status_code = HTTPStatus(status_code)
120
132
  return _STATUS_CODE_TO_ERROR_MAPPING.get(status_code, InternalServerError)
@@ -24,7 +24,7 @@ import xarray as xr
24
24
  def add_data_array(ds: xr.Dataset, da: xr.DataArray, name: Hashable | None = None) -> xr.Dataset:
25
25
  """Add data array `da` to dataset `ds`.
26
26
 
27
- Unlike the default xarray command, preserves metadata of the dataset.
27
+ Unlike the default xarray command, preserves metadata of the coordinates.
28
28
 
29
29
  Args:
30
30
  ds: Dataset to add to.
@@ -44,16 +44,11 @@ def add_data_array(ds: xr.Dataset, da: xr.DataArray, name: Hashable | None = Non
44
44
  # Attributes of Dataset coordinates are dropped/replaced when adding a DataArray
45
45
  # https://github.com/pydata/xarray/issues/2245
46
46
  # So we need to temporarily store all coord attrs, and then add them back
47
- attributes = {}
48
- for key in ds.coords:
49
- attributes[key] = ds.coords[key].attrs
50
- for key in ds.data_vars:
51
- attributes[key] = ds.data_vars[key].attrs
47
+ attributes = {key: value.attrs for key, value in ds.coords.items()}
48
+
52
49
  ds[name] = da
53
50
  for key in ds.coords:
54
51
  if attributes.get(key):
55
52
  ds.coords[key].attrs = attributes.get(key) # type:ignore[assignment]
56
- for key in ds.data_vars:
57
- if attributes.get(key):
58
- ds.data_vars[key].attrs = attributes[key]
53
+
59
54
  return ds
@@ -11,7 +11,7 @@ def _assert_iso_8601_format(since: str) -> None:
11
11
  raise ValueError("Invalid date format. Use 'YYYY-MM-DD'.")
12
12
 
13
13
 
14
- def format_deprecated(old: str, new: str | None, since: str) -> LiteralString:
14
+ def format_deprecated(old: str, new: str | None, since: str) -> LiteralString: # noqa: D103
15
15
  _assert_iso_8601_format(since)
16
16
  message: str = (
17
17
  f"{old} is deprecated since {since}, it can be be removed from the codebase in the next major release."
@@ -28,7 +28,7 @@ def _natural_sort_key(name: str) -> tuple[int | str | Any, ...]:
28
28
  return tuple(int(item) if item.isdigit() else item.lower() for item in re.split(r"(\d+)", name))
29
29
 
30
30
 
31
- class Component(ImmutableBaseModel):
31
+ class Component(ImmutableBaseModel): # noqa: D101
32
32
  name: str
33
33
  connections: tuple[str, ...] = ()
34
34
 
@@ -41,28 +41,28 @@ class Component(ImmutableBaseModel):
41
41
  return tuple(sorted(connections, key=_natural_sort_key))
42
42
 
43
43
 
44
- class Qubit(Component):
44
+ class Qubit(Component): # noqa: D101
45
45
  pass
46
46
 
47
47
 
48
- class Coupler(Component):
48
+ class Coupler(Component): # noqa: D101
49
49
  pass
50
50
 
51
51
 
52
- class ProbeLine(Component):
52
+ class ProbeLine(Component): # noqa: D101
53
53
  pass
54
54
 
55
55
 
56
- class Launcher(Component):
56
+ class Launcher(Component): # noqa: D101
57
57
  pin: str
58
58
  function: str
59
59
 
60
60
 
61
- class ComputationalResonator(Component):
61
+ class ComputationalResonator(Component): # noqa: D101
62
62
  pass
63
63
 
64
64
 
65
- class Components(ImmutableBaseModel):
65
+ class Components(ImmutableBaseModel): # noqa: D101
66
66
  # Alias list of components to plurals rather than singulars to follow normal naming conventions
67
67
  qubits: tuple[Qubit, ...] = Field((), alias="qubit")
68
68
  couplers: tuple[Coupler, ...] = Field((), alias="tunable_coupler")
@@ -83,7 +83,7 @@ class Components(ImmutableBaseModel):
83
83
  return {component.name: component for component in components}
84
84
 
85
85
 
86
- class CHAD(ImmutableBaseModel):
86
+ class CHAD(ImmutableBaseModel): # noqa: D101
87
87
  mask_set_name: str
88
88
  variant: str
89
89
  components: Components
@@ -25,7 +25,7 @@ from requests.adapters import BaseAdapter
25
25
  from six import BytesIO
26
26
 
27
27
 
28
- class FileAdapter(BaseAdapter):
28
+ class FileAdapter(BaseAdapter): # noqa: D101
29
29
  def __init__(self, set_content_length=True): # noqa: ANN001
30
30
  super(FileAdapter, self).__init__()
31
31
  self._set_content_length = set_content_length
@@ -18,7 +18,7 @@ from pydantic import BaseModel, ConfigDict
18
18
 
19
19
 
20
20
  # Change the behaviour of pydantic globally
21
- class ImmutableBaseModel(BaseModel):
21
+ class ImmutableBaseModel(BaseModel): # noqa: D101
22
22
  # Unable to use cached_property
23
23
  # https://github.com/pydantic/pydantic/issues/1241
24
24
  model_config = ConfigDict(frozen=True, ignored_types=(cached_property,))
@@ -20,8 +20,7 @@ serializing and deserializing sweep arguments before saving them to database.
20
20
  import json
21
21
  from typing import Any, cast
22
22
 
23
- from exa.common.control.sweep.sweep import Sweep
24
- from exa.common.data.parameter import Parameter
23
+ from exa.common.data.parameter import Parameter, Sweep
25
24
  from exa.common.data.setting_node import SettingNode
26
25
  from exa.common.helpers import json_helper
27
26
  from exa.common.helpers.json_helper import decode_json, get_json_encoder
exa/common/sweep/util.py CHANGED
@@ -17,8 +17,7 @@ user-friendly format to canonic ones.
17
17
  """
18
18
 
19
19
  from exa.common.control.sweep.option import StartStopOptions
20
- from exa.common.control.sweep.sweep import Sweep
21
- from exa.common.data.parameter import Parameter
20
+ from exa.common.data.parameter import Parameter, Sweep
22
21
 
23
22
  # One sweep where many sweeps are executed together, like a zip. Type hint alias.
24
23
  ParallelSweep = tuple[Sweep, ...]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: iqm-exa-common
3
- Version: 27.3.1
3
+ Version: 27.4.0
4
4
  Summary: Framework for control and measurement of superconducting qubits: common library
5
5
  Author-email: IQM Finland Oy <info@meetiqm.com>
6
6
  License: Apache License
@@ -204,7 +204,7 @@ License: Apache License
204
204
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
205
205
  See the License for the specific language governing permissions and
206
206
  limitations under the License.
207
- Project-URL: Documentation, https://iqm-finland.github.io/docs/iqm-exa-common/
207
+ Project-URL: Documentation, https://docs.meetiqm.com/iqm-exa-common/
208
208
  Project-URL: Homepage, https://pypi.org/project/iqm-exa-common/
209
209
  Classifier: Development Status :: 4 - Beta
210
210
  Classifier: Programming Language :: Python :: 3 :: Only
@@ -231,7 +231,7 @@ EXA-common
231
231
 
232
232
  A Python-based project with abstract interfaces, helpers, etc. that are used both in backend and experiment layers.
233
233
 
234
- See `API documentation <https://iqm-finland.github.io/docs/iqm-exa-common/>`_.
234
+ See `API documentation <https://docs.meetiqm.com/iqm-exa-common/>`_.
235
235
 
236
236
  Copyright
237
237
  ---------
@@ -5,12 +5,12 @@ exa/common/api/proto_serialization/__init__.py,sha256=Vn2C79OqovFu5wJus9EHsMtK3O
5
5
  exa/common/api/proto_serialization/_parameter.py,sha256=d_LHc_Tl3OqiQmTGe6Y6mkHvQkknzFl5KPEJauPEKPM,3050
6
6
  exa/common/api/proto_serialization/array.py,sha256=CvuOV5jNyFAAdqrYsh_z4DeQA6kYvfidW9bEv_M7Ugo,3127
7
7
  exa/common/api/proto_serialization/datum.py,sha256=x9PJi3iiqAcG7aMUhBaho6vTNBQsm7pzY0HCFxB_zfM,4915
8
- exa/common/api/proto_serialization/nd_sweep.py,sha256=5Wi_iz4XqQE9GgSzt3vUTpYKwO5uCPGBa2OqwOMOXcQ,2912
8
+ exa/common/api/proto_serialization/nd_sweep.py,sha256=mquxmfQ-VG2wbsHqoRtnxOc75bUhwxVeBKVAAhNmcow,2870
9
9
  exa/common/api/proto_serialization/sequence.py,sha256=4yQgdTUenbsY8yNu7JqSQSq2Ushd1zlzuciaqmyP7OY,2568
10
10
  exa/common/api/proto_serialization/setting_node.py,sha256=oAlJOmkQTmMSd6wpofoDLz3YIlkiqxX7kY84WnZZ4b4,4073
11
11
  exa/common/control/__init__.py,sha256=00T_xV0lL20QZcEt__vWq81N1oGF0KpJMhTitfAI4VI,629
12
12
  exa/common/control/sweep/__init__.py,sha256=GzKoQdQsLutcHhmrLPyPrW1n7Cpg766p3OWDHlRpuTs,607
13
- exa/common/control/sweep/sweep.py,sha256=7iaW_8baA0vZZjR7s6P1jkkG-B5Ncjez25xyExbKlf4,2260
13
+ exa/common/control/sweep/sweep.py,sha256=K_7qzzOtlRqzYb7IIJ-clbMTAhSW-bmXmRfXNUWzOMs,708
14
14
  exa/common/control/sweep/sweep_values.py,sha256=c868qpnh3SP6DYN3eAt0SLaePuzzQwxTWYwnQwL4A-I,2277
15
15
  exa/common/control/sweep/option/__init__.py,sha256=Z01JS0FpchMvR8zfWBCs3jcPjh2H8X29YkN0SFxWLTY,906
16
16
  exa/common/control/sweep/option/center_span_base_options.py,sha256=uHWt4euQVF7EVXJid8wnIXo8PtJnyUdydxxAXPEMnV4,2558
@@ -23,16 +23,16 @@ exa/common/control/sweep/option/start_stop_options.py,sha256=vJottC6QX80MhVyg9_R
23
23
  exa/common/control/sweep/option/sweep_options.py,sha256=BhKB7RHP0VXJ9iUQKVzeQOM4j_x9AsMhRJgoR3gkiaY,933
24
24
  exa/common/data/__init__.py,sha256=F5SRe5QHBTjef4XJVQ63kO5Oxc_AiZnPbV560i7La0Y,644
25
25
  exa/common/data/base_model.py,sha256=foW3gtxoBtHfkDOjZPS7Eo1lcVKZwsDtyn-_0B7WnR8,1836
26
- exa/common/data/parameter.py,sha256=4CtvR6u5XT-5TJb_bTe9DYvBhOCNMlvOMepeGgr80FA,24500
26
+ exa/common/data/parameter.py,sha256=nf5kiGxh0JBdAi1YNJe3dmer09u99ICXKBLkmDYblZ0,25297
27
27
  exa/common/data/setting_node.py,sha256=rTXo-D9v42L8HkJoNoCMtm8cyUEuNtpYGhHfi45ZPhA,44782
28
28
  exa/common/data/settingnode_v2.html.jinja2,sha256=mo-rlLLmU-Xxf6znJAisispAZK8sbV-2C13byKAtj_Q,3166
29
29
  exa/common/data/value.py,sha256=mtMws5UPGx1pCADK6Q2Tx4BwCXznvVRSNQRfcQ3NMmY,1853
30
30
  exa/common/errors/__init__.py,sha256=ArMBdpmx1EUenBpzrSNG63kmUf7PM0gCqSYnaCnL9Qk,597
31
31
  exa/common/errors/exa_error.py,sha256=wFfJbdeGs15XVF0VJvXPEjNavC2hXVJjchFcLfCfAiw,560
32
- exa/common/errors/station_control_errors.py,sha256=s0LimSOthQF8NWKyW556p-9vEapOxtn_W5ZiZVPTv_g,4489
32
+ exa/common/errors/station_control_errors.py,sha256=_dI4rD7WZ7As2Kiz8GtjBmkWP8KWTkCcPYwLocmydsE,4990
33
33
  exa/common/helpers/__init__.py,sha256=IgtVD3tojIFA4MTV2mT5uYM6jb2qny9kBIIhEZT2PuI,610
34
- exa/common/helpers/data_helper.py,sha256=-AP0vwrf7WgyumLsicDtNP2VP5rhG4_oiOZgG4alNb4,2001
35
- exa/common/helpers/deprecation.py,sha256=n9_9Ii8UVW0dry7mvH_DOpSOwGQpbgw48EvhtLcgUc0,710
34
+ exa/common/helpers/data_helper.py,sha256=1HP4EGt8lpzLY8kSdDk9FjQdLaKmY3THalgpNtr2exc,1792
35
+ exa/common/helpers/deprecation.py,sha256=EUAHUiQZhvoI7zDAZICYQXVCUAWQ4wBWCnEBBAQ8pHs,724
36
36
  exa/common/helpers/json_helper.py,sha256=LoTrL6FREML1o0X3Zznf1baI4kn0kh03NE1nqBHgYss,2699
37
37
  exa/common/helpers/numpy_helper.py,sha256=KKKyZ_fD0O1gn7_InEQROYnX3WGMA6C1qHh8KzzjtUI,1062
38
38
  exa/common/helpers/software_version_helper.py,sha256=q7SVw7dSFBZIJQGwEpAR3rAFDlrC_s48-bM3Tqu5CQ0,5428
@@ -40,17 +40,17 @@ exa/common/helpers/yaml_helper.py,sha256=wLy-7Nyit597FoWBemduUilYP2VCk_aDDT8y62i
40
40
  exa/common/logger/__init__.py,sha256=1bIsGxHzfujXlkgtcAnWToKMkw3dpU5PEd_7LE_NpgQ,686
41
41
  exa/common/logger/logger.py,sha256=TA9HxFZDyFB7ai8C6mCZOm1cx3JMRAhB8DcMCwDAKt0,5713
42
42
  exa/common/qcm_data/__init__.py,sha256=VtsYkGoaniSjCkY0oQlqkcYJCtmC2sTDxfrIe_kpqZg,567
43
- exa/common/qcm_data/chad_model.py,sha256=1vWpB8gsrnIEDqEOqqQAXrofN2jM6c8AypZvOSH5I18,11279
43
+ exa/common/qcm_data/chad_model.py,sha256=kk5j_ij1XL87o5ZggpuIP9jUxAqeZB8kTZuoVoFaL6w,11391
44
44
  exa/common/qcm_data/chip_layout.py,sha256=jDEMsujltH_KqLjj2Ja-XEEJubfsMg_HPlqnC4-L9YE,4555
45
45
  exa/common/qcm_data/chip_topology.py,sha256=cQTxuIouQ3yGSfMNbKzu76vERQGlK_TguhkJYN_ehB0,20075
46
- exa/common/qcm_data/file_adapter.py,sha256=VAvyV4FrCE93bvy7YP2DDlS_cgHQe-uwPdMQwMlZveQ,2319
47
- exa/common/qcm_data/immutable_base_model.py,sha256=QXmKIWQbsbWQvovXwKT1d9jtyf2LNJtjQquIwO52zOU,901
46
+ exa/common/qcm_data/file_adapter.py,sha256=EvGXs5c2EWj0F-OUU0mu9vMUMXtyHJJC7RmkPyXSupw,2333
47
+ exa/common/qcm_data/immutable_base_model.py,sha256=Mhz1nzxtx3c2KHs-HowGvh83rswz2oCm4MPQr9p6BvI,915
48
48
  exa/common/qcm_data/qcm_data_client.py,sha256=Rze6yQd0xUeH6eUMv3wduYbiDCTP3C4WECtCe7ONmyc,6061
49
49
  exa/common/sweep/__init__.py,sha256=uEKk5AtzSgSnf8Y0geRPwUpqXIBIXpeCxsN64sX7F1o,591
50
- exa/common/sweep/database_serialization.py,sha256=9n96OqmEnjy1x2F1HwaNOQgwX_39HjLtE9EUoetSw0E,7493
51
- exa/common/sweep/util.py,sha256=-QE2AaH-WDkYAVH5-Z-30leLgY0x4efmby4kc1JTCgY,3732
52
- iqm_exa_common-27.3.1.dist-info/LICENSE.txt,sha256=R6Q7eUrLyoCQgWYorQ8WJmVmWKYU3dxA3jYUp0wwQAw,11332
53
- iqm_exa_common-27.3.1.dist-info/METADATA,sha256=MuX5ZtCxb1efqRQSTH-LZKzOm5lkxBOKwyfdLQeBca4,14741
54
- iqm_exa_common-27.3.1.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
55
- iqm_exa_common-27.3.1.dist-info/top_level.txt,sha256=Clphg2toaZ3_jSFRPhjMNEmLurkMNMc4lkK2EFYsSlM,4
56
- iqm_exa_common-27.3.1.dist-info/RECORD,,
50
+ exa/common/sweep/database_serialization.py,sha256=ZcvKpg5dREc8ynxp4alD4vdIwMsDOe2X5piavRWMtTU,7451
51
+ exa/common/sweep/util.py,sha256=brUD6uDpQBCT0MMg5LdQj-ADWcJnaK3oZTiDzJbGHoc,3690
52
+ iqm_exa_common-27.4.0.dist-info/LICENSE.txt,sha256=R6Q7eUrLyoCQgWYorQ8WJmVmWKYU3dxA3jYUp0wwQAw,11332
53
+ iqm_exa_common-27.4.0.dist-info/METADATA,sha256=nc5ka-UkscDjNj6uXot2rN_pEJvwFroaisXgxDnHjUQ,14721
54
+ iqm_exa_common-27.4.0.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
55
+ iqm_exa_common-27.4.0.dist-info/top_level.txt,sha256=Clphg2toaZ3_jSFRPhjMNEmLurkMNMc4lkK2EFYsSlM,4
56
+ iqm_exa_common-27.4.0.dist-info/RECORD,,