boulder-opal-scale-up-sdk 1.0.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.
- boulder_opal_scale_up_sdk-1.0.0.dist-info/METADATA +38 -0
- boulder_opal_scale_up_sdk-1.0.0.dist-info/RECORD +50 -0
- boulder_opal_scale_up_sdk-1.0.0.dist-info/WHEEL +4 -0
- boulderopalscaleupsdk/__init__.py +14 -0
- boulderopalscaleupsdk/agent/__init__.py +29 -0
- boulderopalscaleupsdk/agent/worker.py +244 -0
- boulderopalscaleupsdk/common/__init__.py +12 -0
- boulderopalscaleupsdk/common/dtypes.py +353 -0
- boulderopalscaleupsdk/common/typeclasses.py +85 -0
- boulderopalscaleupsdk/device/__init__.py +16 -0
- boulderopalscaleupsdk/device/common.py +58 -0
- boulderopalscaleupsdk/device/config_loader.py +88 -0
- boulderopalscaleupsdk/device/controller/__init__.py +32 -0
- boulderopalscaleupsdk/device/controller/base.py +18 -0
- boulderopalscaleupsdk/device/controller/qblox.py +664 -0
- boulderopalscaleupsdk/device/controller/quantum_machines.py +139 -0
- boulderopalscaleupsdk/device/device.py +35 -0
- boulderopalscaleupsdk/device/processor/__init__.py +23 -0
- boulderopalscaleupsdk/device/processor/common.py +148 -0
- boulderopalscaleupsdk/device/processor/superconducting_processor.py +291 -0
- boulderopalscaleupsdk/experiments/__init__.py +44 -0
- boulderopalscaleupsdk/experiments/common.py +96 -0
- boulderopalscaleupsdk/experiments/power_rabi.py +60 -0
- boulderopalscaleupsdk/experiments/ramsey.py +55 -0
- boulderopalscaleupsdk/experiments/resonator_spectroscopy.py +64 -0
- boulderopalscaleupsdk/experiments/resonator_spectroscopy_by_bias.py +76 -0
- boulderopalscaleupsdk/experiments/resonator_spectroscopy_by_power.py +64 -0
- boulderopalscaleupsdk/grpc_interceptors/__init__.py +16 -0
- boulderopalscaleupsdk/grpc_interceptors/auth.py +101 -0
- boulderopalscaleupsdk/plotting/__init__.py +24 -0
- boulderopalscaleupsdk/plotting/dtypes.py +221 -0
- boulderopalscaleupsdk/protobuf/v1/agent_pb2.py +48 -0
- boulderopalscaleupsdk/protobuf/v1/agent_pb2.pyi +53 -0
- boulderopalscaleupsdk/protobuf/v1/agent_pb2_grpc.py +138 -0
- boulderopalscaleupsdk/protobuf/v1/device_pb2.py +71 -0
- boulderopalscaleupsdk/protobuf/v1/device_pb2.pyi +110 -0
- boulderopalscaleupsdk/protobuf/v1/device_pb2_grpc.py +274 -0
- boulderopalscaleupsdk/protobuf/v1/task_pb2.py +53 -0
- boulderopalscaleupsdk/protobuf/v1/task_pb2.pyi +118 -0
- boulderopalscaleupsdk/protobuf/v1/task_pb2_grpc.py +119 -0
- boulderopalscaleupsdk/py.typed +0 -0
- boulderopalscaleupsdk/routines/__init__.py +9 -0
- boulderopalscaleupsdk/routines/common.py +10 -0
- boulderopalscaleupsdk/routines/resonator_mapping.py +13 -0
- boulderopalscaleupsdk/third_party/__init__.py +14 -0
- boulderopalscaleupsdk/third_party/quantum_machines/__init__.py +51 -0
- boulderopalscaleupsdk/third_party/quantum_machines/config.py +597 -0
- boulderopalscaleupsdk/third_party/quantum_machines/constants.py +20 -0
- boulderopalscaleupsdk/utils/__init__.py +12 -0
- boulderopalscaleupsdk/utils/serial_utils.py +62 -0
@@ -0,0 +1,96 @@
|
|
1
|
+
# Copyright 2025 Q-CTRL. All rights reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
|
4
|
+
# copying or use of this file, via any medium, is strictly prohibited.
|
5
|
+
# Proprietary and confidential. You may not use this file except in compliance
|
6
|
+
# with the License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# https://q-ctrl.com/terms
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS. See the
|
12
|
+
# License for the specific language.
|
13
|
+
|
14
|
+
from typing import Literal
|
15
|
+
|
16
|
+
from pydantic import BaseModel, ConfigDict, Field
|
17
|
+
from pydantic.dataclasses import dataclass
|
18
|
+
|
19
|
+
|
20
|
+
class Experiment(BaseModel):
|
21
|
+
model_config = ConfigDict(extra="forbid")
|
22
|
+
_experiment_name: str
|
23
|
+
|
24
|
+
@property
|
25
|
+
def experiment_name(self) -> str:
|
26
|
+
return self._experiment_name
|
27
|
+
|
28
|
+
|
29
|
+
class LinspaceIterable(BaseModel):
|
30
|
+
"""A linear space of float values."""
|
31
|
+
|
32
|
+
dtype: Literal["linspace"] = "linspace"
|
33
|
+
|
34
|
+
# The starting value.
|
35
|
+
start: float
|
36
|
+
# The final value.
|
37
|
+
stop: float
|
38
|
+
# The number of values. Defaults to 101.
|
39
|
+
count: int = Field(default=101)
|
40
|
+
|
41
|
+
|
42
|
+
class RangeIterable(BaseModel):
|
43
|
+
"""A range of values with a specified step."""
|
44
|
+
|
45
|
+
dtype: Literal["range"] = "range"
|
46
|
+
|
47
|
+
# The starting value.
|
48
|
+
start: float
|
49
|
+
# The final value.
|
50
|
+
stop: float
|
51
|
+
# The step between values.
|
52
|
+
step: float
|
53
|
+
|
54
|
+
|
55
|
+
class CWSIterable(BaseModel):
|
56
|
+
"""A range of linearly spaced values in center ± width/2."""
|
57
|
+
|
58
|
+
dtype: Literal["cws"] = "cws"
|
59
|
+
|
60
|
+
# The central value. Defaults to the expected value.
|
61
|
+
center: float | None
|
62
|
+
# The range width.
|
63
|
+
width: float
|
64
|
+
# The step between values.
|
65
|
+
step: float
|
66
|
+
|
67
|
+
|
68
|
+
class HypIterable(BaseModel):
|
69
|
+
"""
|
70
|
+
A hyperbolic iterable of values in center ± width/2,
|
71
|
+
with points more concentrated around the center.
|
72
|
+
"""
|
73
|
+
|
74
|
+
dtype: Literal["hyp"] = "hyp"
|
75
|
+
|
76
|
+
# The central value. Defaults to the expected value.
|
77
|
+
center: float | None
|
78
|
+
# The range width.
|
79
|
+
width: float
|
80
|
+
# The number of values. Defaults to 51.
|
81
|
+
count: int = Field(default=51)
|
82
|
+
|
83
|
+
|
84
|
+
@dataclass
|
85
|
+
class ConstantWaveform:
|
86
|
+
duration_ns: int
|
87
|
+
scale: float
|
88
|
+
waveform_type: Literal["constant"] = "constant"
|
89
|
+
|
90
|
+
|
91
|
+
@dataclass
|
92
|
+
class GaussianWaveform:
|
93
|
+
duration_ns: int
|
94
|
+
amplitude: float
|
95
|
+
sigma: float
|
96
|
+
waveform_type: Literal["gaussian"] = "gaussian"
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# Copyright 2025 Q-CTRL. All rights reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
|
4
|
+
# copying or use of this file, via any medium, is strictly prohibited.
|
5
|
+
# Proprietary and confidential. You may not use this file except in compliance
|
6
|
+
# with the License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# https://q-ctrl.com/terms
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS. See the
|
12
|
+
# License for the specific language.
|
13
|
+
|
14
|
+
from pydantic import PrivateAttr
|
15
|
+
|
16
|
+
from .common import (
|
17
|
+
ConstantWaveform,
|
18
|
+
CWSIterable,
|
19
|
+
Experiment,
|
20
|
+
GaussianWaveform,
|
21
|
+
HypIterable,
|
22
|
+
LinspaceIterable,
|
23
|
+
RangeIterable,
|
24
|
+
)
|
25
|
+
|
26
|
+
DEFAULT_SHOT_COUNT = 400
|
27
|
+
|
28
|
+
|
29
|
+
class PowerRabi(Experiment):
|
30
|
+
"""
|
31
|
+
Parameters for running a Power Rabi experiment.
|
32
|
+
|
33
|
+
Parameters
|
34
|
+
----------
|
35
|
+
qubit : int
|
36
|
+
The qubit whose resonator to target in the experiment.
|
37
|
+
scales : list[float] or LinspaceIterable or RangeIterable
|
38
|
+
or CWSIterable or HypIterable or None, optional
|
39
|
+
The scaling factors for the drive pulse amplitude. If None, a default scan will be used.
|
40
|
+
drive_waveform : GaussianWaveform
|
41
|
+
The waveform to use for the drive pulse.
|
42
|
+
measure_waveform : ConstantWaveform
|
43
|
+
The waveform to use for the measurement pulse.
|
44
|
+
recycle_delay_ns : int
|
45
|
+
The delay time between consecutive shots of the experiment, in nanoseconds.
|
46
|
+
shot_count : int, optional
|
47
|
+
The number of shots to be taken in the experiment. Defaults to 400.
|
48
|
+
pulse_vp : float, optional
|
49
|
+
The voltage per pulse. If None, a default value will be used.
|
50
|
+
"""
|
51
|
+
|
52
|
+
_experiment_name: str = PrivateAttr("power_rabi")
|
53
|
+
|
54
|
+
qubit: int
|
55
|
+
scales: list[float] | LinspaceIterable | RangeIterable | CWSIterable | HypIterable | None = None
|
56
|
+
drive_waveform: GaussianWaveform
|
57
|
+
measure_waveform: ConstantWaveform
|
58
|
+
recycle_delay_ns: int
|
59
|
+
shot_count: int = DEFAULT_SHOT_COUNT
|
60
|
+
pulse_vp: float | None = None
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# Copyright 2025 Q-CTRL. All rights reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
|
4
|
+
# copying or use of this file, via any medium, is strictly prohibited.
|
5
|
+
# Proprietary and confidential. You may not use this file except in compliance
|
6
|
+
# with the License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# https://q-ctrl.com/terms
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS. See the
|
12
|
+
# License for the specific language.
|
13
|
+
|
14
|
+
from pydantic import PrivateAttr
|
15
|
+
|
16
|
+
from .common import Experiment
|
17
|
+
|
18
|
+
DEFAULT_RECYCLE_DELAY_NS = 10_000
|
19
|
+
DEFAULT_SHOT_COUNT = 400
|
20
|
+
|
21
|
+
|
22
|
+
class Ramsey(Experiment):
|
23
|
+
"""
|
24
|
+
Parameters for running a Ramsey experiment.
|
25
|
+
|
26
|
+
Parameters
|
27
|
+
----------
|
28
|
+
qubit : int
|
29
|
+
The qubit whose resonator to target in the experiment.
|
30
|
+
max_delay_ns : int
|
31
|
+
The maximum delay time, in nanoseconds.
|
32
|
+
min_delay_ns : int
|
33
|
+
The minimum delay time, in nanoseconds.
|
34
|
+
delay_step_ns : int
|
35
|
+
The step for generating the list of delays, in nanoseconds.
|
36
|
+
detuning : float
|
37
|
+
The difference between the drive signal frequency and the qubit frequency,
|
38
|
+
in Hz.
|
39
|
+
recycle_delay_ns : float, optional
|
40
|
+
The delay time between consecutive shots of the experiment, in nanoseconds.
|
41
|
+
Defaults to 10000 ns.
|
42
|
+
shot_count : int, optional
|
43
|
+
The number of shots to be taken in the experiment.
|
44
|
+
Defaults to 400.
|
45
|
+
"""
|
46
|
+
|
47
|
+
_experiment_name: str = PrivateAttr("ramsey")
|
48
|
+
|
49
|
+
qubit: int
|
50
|
+
max_delay_ns: int
|
51
|
+
min_delay_ns: int
|
52
|
+
delay_step_ns: int
|
53
|
+
detuning: float
|
54
|
+
recycle_delay_ns: int = DEFAULT_RECYCLE_DELAY_NS
|
55
|
+
shot_count: int = DEFAULT_SHOT_COUNT
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# Copyright 2025 Q-CTRL. All rights reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
|
4
|
+
# copying or use of this file, via any medium, is strictly prohibited.
|
5
|
+
# Proprietary and confidential. You may not use this file except in compliance
|
6
|
+
# with the License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# https://q-ctrl.com/terms
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS. See the
|
12
|
+
# License for the specific language.
|
13
|
+
|
14
|
+
from pydantic import PrivateAttr
|
15
|
+
|
16
|
+
from .common import (
|
17
|
+
CWSIterable,
|
18
|
+
Experiment,
|
19
|
+
HypIterable,
|
20
|
+
LinspaceIterable,
|
21
|
+
RangeIterable,
|
22
|
+
)
|
23
|
+
|
24
|
+
DEFAULT_DURATION_NS = 2000 # ns
|
25
|
+
DEFAULT_RECYCLE_DELAY_NS = 1000 # ns
|
26
|
+
DEFAULT_SHOT_COUNT = 100
|
27
|
+
|
28
|
+
|
29
|
+
class ResonatorSpectroscopy(Experiment):
|
30
|
+
"""
|
31
|
+
Parameters for running a resonator spectroscopy experiment.
|
32
|
+
|
33
|
+
Parameters
|
34
|
+
----------
|
35
|
+
qubit : int
|
36
|
+
The qubit whose resonator to target in the experiment.
|
37
|
+
frequencies : list[int] or LinspaceIterable or RangeIterable or CWSIterable
|
38
|
+
or HypIterable or None, optional
|
39
|
+
The frequencies at which to scan.
|
40
|
+
If None, frequencies around the readout frequency will be used.
|
41
|
+
readout_amplitude : float, optional
|
42
|
+
The amplitude of the readout pulse.
|
43
|
+
If None, a default amplitude will be used.
|
44
|
+
duration_ns : int, optional
|
45
|
+
The duration of the readout pulse, in nanoseconds.
|
46
|
+
Defaults to 2000 ns.
|
47
|
+
recycle_delay_ns :int, optional
|
48
|
+
The delay time between consecutive shots of the experiment, in nanoseconds.
|
49
|
+
Defaults to 1000 ns.
|
50
|
+
shot_count : int, optional
|
51
|
+
The number of shots to be taken in the experiment.
|
52
|
+
Defaults to 100.
|
53
|
+
"""
|
54
|
+
|
55
|
+
_experiment_name: str = PrivateAttr("resonator_spectroscopy")
|
56
|
+
|
57
|
+
qubit: int
|
58
|
+
frequencies: list[int] | LinspaceIterable | RangeIterable | CWSIterable | HypIterable | None = (
|
59
|
+
None
|
60
|
+
)
|
61
|
+
readout_amplitude: float | None = None
|
62
|
+
duration_ns: int = DEFAULT_DURATION_NS
|
63
|
+
recycle_delay_ns: int = DEFAULT_RECYCLE_DELAY_NS
|
64
|
+
shot_count: int = DEFAULT_SHOT_COUNT
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# Copyright 2025 Q-CTRL. All rights reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
|
4
|
+
# copying or use of this file, via any medium, is strictly prohibited.
|
5
|
+
# Proprietary and confidential. You may not use this file except in compliance
|
6
|
+
# with the License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# https://q-ctrl.com/terms
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS. See the
|
12
|
+
# License for the specific language.
|
13
|
+
|
14
|
+
from pydantic import PrivateAttr
|
15
|
+
|
16
|
+
from .common import (
|
17
|
+
CWSIterable,
|
18
|
+
Experiment,
|
19
|
+
HypIterable,
|
20
|
+
LinspaceIterable,
|
21
|
+
RangeIterable,
|
22
|
+
)
|
23
|
+
|
24
|
+
DEFAULT_DURATION_NS = 2000
|
25
|
+
DEFAULT_SHOT_COUNT = 100
|
26
|
+
DEFAULT_RECYCLE_DELAY_NS = 10_000
|
27
|
+
DEFAULT_BIASES = LinspaceIterable(start=-0.49, stop=0.49, count=21)
|
28
|
+
|
29
|
+
|
30
|
+
class ResonatorSpectroscopyByBias(Experiment):
|
31
|
+
"""
|
32
|
+
Parameters for running a resonator spectroscopy by power experiment.
|
33
|
+
|
34
|
+
Parameters
|
35
|
+
----------
|
36
|
+
qubit : int
|
37
|
+
The qubit whose resonator to target in the experiment.
|
38
|
+
bias_qubits : list[int] or None, optional
|
39
|
+
The qubits whose biases to target.
|
40
|
+
If None, defaults to the qubit.
|
41
|
+
frequencies : list[float] or LinspaceIterable or RangeIterable or CWSIterable
|
42
|
+
or HypIterable or None, optional
|
43
|
+
The frequencies at which to scan.
|
44
|
+
If None, frequencies around the readout frequency will be used.
|
45
|
+
biases : list[int] or LinspaceIterable or RangeIterable or CWSIterable
|
46
|
+
or HypIterable, optional
|
47
|
+
The biases at which to scan.
|
48
|
+
If None, defaults to 21 points between -0.49 and 0.49.
|
49
|
+
readout_amplitude : float, optional
|
50
|
+
The amplitude of the readout pulse.
|
51
|
+
Defaults to None.
|
52
|
+
duration_ns : float, optional
|
53
|
+
The duration of the pulse, in nanoseconds.
|
54
|
+
Defaults to 2000 ns.
|
55
|
+
recycle_delay_ns : float, optional
|
56
|
+
The delay time between consecutive shots of the experiment, in nanoseconds.
|
57
|
+
Defaults to 10000 ns.
|
58
|
+
shot_count : int, optional
|
59
|
+
The number of shots to be taken in the experiment.
|
60
|
+
Defaults to 100.
|
61
|
+
"""
|
62
|
+
|
63
|
+
_experiment_name: str = PrivateAttr("resonator_spectroscopy_by_bias")
|
64
|
+
|
65
|
+
qubit: int
|
66
|
+
bias_qubits: list[int] | None = None
|
67
|
+
frequencies: list[int] | LinspaceIterable | RangeIterable | CWSIterable | HypIterable | None = (
|
68
|
+
None
|
69
|
+
)
|
70
|
+
biases: list[float] | LinspaceIterable | RangeIterable | CWSIterable | HypIterable = (
|
71
|
+
DEFAULT_BIASES
|
72
|
+
)
|
73
|
+
readout_amplitude: float | None = None
|
74
|
+
duration_ns: int = DEFAULT_DURATION_NS
|
75
|
+
recycle_delay_ns: int = DEFAULT_RECYCLE_DELAY_NS
|
76
|
+
shot_count: int = DEFAULT_SHOT_COUNT
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# Copyright 2025 Q-CTRL. All rights reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
|
4
|
+
# copying or use of this file, via any medium, is strictly prohibited.
|
5
|
+
# Proprietary and confidential. You may not use this file except in compliance
|
6
|
+
# with the License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# https://q-ctrl.com/terms
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS. See the
|
12
|
+
# License for the specific language.
|
13
|
+
|
14
|
+
from pydantic import PrivateAttr
|
15
|
+
|
16
|
+
from .common import (
|
17
|
+
CWSIterable,
|
18
|
+
Experiment,
|
19
|
+
HypIterable,
|
20
|
+
LinspaceIterable,
|
21
|
+
RangeIterable,
|
22
|
+
)
|
23
|
+
|
24
|
+
DEFAULT_DURATION_NS = 2000 # ns
|
25
|
+
DEFAULT_RECYCLE_DELAY_NS = 1000 # ns
|
26
|
+
DEFAULT_SHOT_COUNT = 100
|
27
|
+
|
28
|
+
|
29
|
+
class ResonatorSpectroscopyByPower(Experiment):
|
30
|
+
"""
|
31
|
+
Parameters for running a resonator spectroscopy by power experiment.
|
32
|
+
|
33
|
+
Parameters
|
34
|
+
----------
|
35
|
+
qubit : int
|
36
|
+
The qubit whose resonator to target in the experiment.
|
37
|
+
frequencies : list[int] or LinspaceIterable or RangeIterable or CWSIterable
|
38
|
+
or HypIterable or None, optional
|
39
|
+
The frequencies at which to scan.
|
40
|
+
If None, frequencies around the readout frequency will be used.
|
41
|
+
powers : list[int] or None, optional
|
42
|
+
The powers at which to scan the readout pulse.
|
43
|
+
If None, a default power scan will be used.
|
44
|
+
duration_ns : int, optional
|
45
|
+
The duration of the readout pulse, in nanoseconds.
|
46
|
+
Defaults to 2000 ns.
|
47
|
+
recycle_delay_ns : int, optional
|
48
|
+
The delay time between consecutive shots of the experiment, in nanoseconds.
|
49
|
+
Defaults to 1000 ns.
|
50
|
+
shot_count : int, optional
|
51
|
+
The number of shots to be taken in the experiment.
|
52
|
+
Defaults to 100.
|
53
|
+
"""
|
54
|
+
|
55
|
+
_experiment_name: str = PrivateAttr("resonator_spectroscopy_by_power")
|
56
|
+
|
57
|
+
qubit: int
|
58
|
+
frequencies: list[int] | LinspaceIterable | RangeIterable | CWSIterable | HypIterable | None = (
|
59
|
+
None
|
60
|
+
)
|
61
|
+
powers: list[float] | None = None
|
62
|
+
duration_ns: int = DEFAULT_DURATION_NS
|
63
|
+
recycle_delay_ns: int = DEFAULT_RECYCLE_DELAY_NS
|
64
|
+
shot_count: int = DEFAULT_SHOT_COUNT
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Copyright 2025 Q-CTRL. All rights reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
|
4
|
+
# copying or use of this file, via any medium, is strictly prohibited.
|
5
|
+
# Proprietary and confidential. You may not use this file except in compliance
|
6
|
+
# with the License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# https://q-ctrl.com/terms
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS. See the
|
12
|
+
# License for the specific language.
|
13
|
+
|
14
|
+
from .auth import AuthInterceptor
|
15
|
+
|
16
|
+
__all__ = ["AuthInterceptor"]
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# Copyright 2025 Q-CTRL. All rights reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
|
4
|
+
# copying or use of this file, via any medium, is strictly prohibited.
|
5
|
+
# Proprietary and confidential. You may not use this file except in compliance
|
6
|
+
# with the License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# https://q-ctrl.com/terms
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS. See the
|
12
|
+
# License for the specific language.
|
13
|
+
|
14
|
+
import inspect
|
15
|
+
|
16
|
+
import grpc
|
17
|
+
import grpc.aio
|
18
|
+
from qctrlclient import ApiKeyAuth
|
19
|
+
|
20
|
+
|
21
|
+
class AuthInterceptor(
|
22
|
+
grpc.UnaryUnaryClientInterceptor,
|
23
|
+
grpc.UnaryStreamClientInterceptor,
|
24
|
+
grpc.StreamUnaryClientInterceptor,
|
25
|
+
grpc.StreamStreamClientInterceptor,
|
26
|
+
grpc.aio.UnaryUnaryClientInterceptor,
|
27
|
+
grpc.aio.UnaryStreamClientInterceptor,
|
28
|
+
grpc.aio.StreamUnaryClientInterceptor,
|
29
|
+
grpc.aio.StreamStreamClientInterceptor,
|
30
|
+
):
|
31
|
+
def __init__(self, auth: ApiKeyAuth):
|
32
|
+
self.auth = auth
|
33
|
+
|
34
|
+
def _add_auth_metadata(self, client_call_details):
|
35
|
+
token = self.auth.access_token
|
36
|
+
|
37
|
+
# Add Authorization header to metadata
|
38
|
+
metadata = client_call_details.metadata if client_call_details.metadata else []
|
39
|
+
metadata = [*metadata, ("authorization", f"Bearer {token}")]
|
40
|
+
|
41
|
+
return client_call_details._replace(metadata=metadata)
|
42
|
+
|
43
|
+
async def _async_intercept(self, continuation, client_call_details, request):
|
44
|
+
new_details = self._add_auth_metadata(client_call_details)
|
45
|
+
return await continuation(new_details, request)
|
46
|
+
|
47
|
+
def _sync_intercept(self, continuation, client_call_details, request):
|
48
|
+
new_details = self._add_auth_metadata(client_call_details)
|
49
|
+
return continuation(new_details, request)
|
50
|
+
|
51
|
+
def intercept_unary_unary(self, continuation, client_call_details, request): # type: ignore[override]
|
52
|
+
if inspect.iscoroutinefunction(continuation):
|
53
|
+
return self._async_intercept(continuation, client_call_details, request)
|
54
|
+
return self._sync_intercept(continuation, client_call_details, request)
|
55
|
+
|
56
|
+
async def intercept_unary_unary_async(
|
57
|
+
self,
|
58
|
+
continuation,
|
59
|
+
client_call_details,
|
60
|
+
request,
|
61
|
+
):
|
62
|
+
return await self._async_intercept(continuation, client_call_details, request)
|
63
|
+
|
64
|
+
def intercept_unary_stream(self, continuation, client_call_details, request): # type: ignore[override]
|
65
|
+
if inspect.iscoroutinefunction(continuation):
|
66
|
+
return self._async_intercept(continuation, client_call_details, request)
|
67
|
+
return self._sync_intercept(continuation, client_call_details, request)
|
68
|
+
|
69
|
+
async def intercept_unary_stream_async(
|
70
|
+
self,
|
71
|
+
continuation,
|
72
|
+
client_call_details,
|
73
|
+
request,
|
74
|
+
):
|
75
|
+
return await self._async_intercept(continuation, client_call_details, request)
|
76
|
+
|
77
|
+
def intercept_stream_unary(self, continuation, client_call_details, request_iterator): # type: ignore[override]
|
78
|
+
if inspect.iscoroutinefunction(continuation):
|
79
|
+
return self._async_intercept(continuation, client_call_details, request_iterator)
|
80
|
+
return self._sync_intercept(continuation, client_call_details, request_iterator)
|
81
|
+
|
82
|
+
async def intercept_stream_unary_async(
|
83
|
+
self,
|
84
|
+
continuation,
|
85
|
+
client_call_details,
|
86
|
+
request,
|
87
|
+
):
|
88
|
+
return await self._async_intercept(continuation, client_call_details, request)
|
89
|
+
|
90
|
+
def intercept_stream_stream(self, continuation, client_call_details, request_iterator): # type: ignore[override]
|
91
|
+
if inspect.iscoroutinefunction(continuation):
|
92
|
+
return self._async_intercept(continuation, client_call_details, request_iterator)
|
93
|
+
return self._sync_intercept(continuation, client_call_details, request_iterator)
|
94
|
+
|
95
|
+
async def intercept_stream_stream_async(
|
96
|
+
self,
|
97
|
+
continuation,
|
98
|
+
client_call_details,
|
99
|
+
request,
|
100
|
+
):
|
101
|
+
return await self._async_intercept(continuation, client_call_details, request)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Copyright 2025 Q-CTRL. All rights reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
|
4
|
+
# copying or use of this file, via any medium, is strictly prohibited.
|
5
|
+
# Proprietary and confidential. You may not use this file except in compliance
|
6
|
+
# with the License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# https://q-ctrl.com/terms
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS. See the
|
12
|
+
# License for the specific language.
|
13
|
+
|
14
|
+
"""Plotting library."""
|
15
|
+
|
16
|
+
__all__ = [
|
17
|
+
"Marker",
|
18
|
+
"Plot",
|
19
|
+
"PlotData1D",
|
20
|
+
"PlotData2D",
|
21
|
+
"VLine",
|
22
|
+
]
|
23
|
+
|
24
|
+
from .dtypes import Marker, Plot, PlotData1D, PlotData2D, VLine
|