QuLab 2.9.2__tar.gz → 2.9.3__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.
- {qulab-2.9.2 → qulab-2.9.3}/PKG-INFO +1 -1
- {qulab-2.9.2 → qulab-2.9.3}/QuLab.egg-info/PKG-INFO +1 -1
- {qulab-2.9.2 → qulab-2.9.3}/qulab/executor/load.py +5 -10
- {qulab-2.9.2 → qulab-2.9.3}/qulab/executor/template.py +14 -9
- {qulab-2.9.2 → qulab-2.9.3}/qulab/scan/server.py +2 -1
- qulab-2.9.3/qulab/sys/__init__.py +2 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/device/basedevice.py +18 -8
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/device/loader.py +1 -1
- qulab-2.9.3/qulab/sys/drivers/FakeInstrument.py +68 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/net/nginx.py +16 -14
- qulab-2.9.3/qulab/version.py +1 -0
- qulab-2.9.2/qulab/sys/drivers/FakeInstrument.py +0 -52
- qulab-2.9.2/qulab/tools/__init__.py +0 -0
- qulab-2.9.2/qulab/version.py +0 -1
- {qulab-2.9.2 → qulab-2.9.3}/LICENSE +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/MANIFEST.in +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/QuLab.egg-info/SOURCES.txt +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/QuLab.egg-info/dependency_links.txt +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/QuLab.egg-info/entry_points.txt +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/QuLab.egg-info/requires.txt +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/QuLab.egg-info/top_level.txt +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/README.md +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/pyproject.toml +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/__init__.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/__main__.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/cli/__init__.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/cli/commands.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/cli/config.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/dicttree.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/executor/__init__.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/executor/cli.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/executor/schedule.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/executor/storage.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/executor/transform.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/executor/utils.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/monitor/__init__.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/monitor/__main__.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/monitor/config.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/monitor/dataset.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/monitor/event_queue.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/monitor/mainwindow.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/monitor/monitor.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/monitor/ploter.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/monitor/qt_compat.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/monitor/toolbar.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/scan/__init__.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/scan/curd.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/scan/expression.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/scan/models.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/scan/optimize.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/scan/query.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/scan/record.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/scan/scan.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/scan/space.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/scan/utils.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/storage/__init__.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/storage/__main__.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/storage/backend/__init__.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/storage/backend/redis.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/storage/base_dataset.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/storage/chunk.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/storage/dataset.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/storage/file.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/storage/models/__init__.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/storage/models/base.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/storage/models/config.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/storage/models/file.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/storage/models/ipy.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/storage/models/models.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/storage/models/record.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/storage/models/report.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/storage/models/tag.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/storage/storage.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/chat.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/device/__init__.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/device/utils.py +0 -0
- {qulab-2.9.2/qulab/sys → qulab-2.9.3/qulab/sys/drivers}/__init__.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/ipy_events.py +0 -0
- {qulab-2.9.2/qulab/sys/drivers → qulab-2.9.3/qulab/sys/net}/__init__.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/net/bencoder.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/net/cli.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/net/dhcp.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/net/dhcpd.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/net/kad.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/net/kcp.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/progress.py +0 -0
- {qulab-2.9.2/qulab/sys/net → qulab-2.9.3/qulab/sys/rpc}/__init__.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/rpc/client.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/rpc/exceptions.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/rpc/msgpack.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/rpc/msgpack.pyi +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/rpc/router.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/rpc/rpc.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/rpc/serialize.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/rpc/server.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/rpc/socket.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/rpc/utils.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/rpc/worker.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/sys/rpc/zmq_socket.py +0 -0
- {qulab-2.9.2/qulab/sys/rpc → qulab-2.9.3/qulab/tools}/__init__.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/tools/connection_helper.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/typing.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/utils.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/visualization/__init__.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/visualization/__main__.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/visualization/_autoplot.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/visualization/plot_circ.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/visualization/plot_layout.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/visualization/plot_seq.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/visualization/qdat.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/visualization/rot3d.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/qulab/visualization/widgets.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/setup.cfg +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/setup.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/src/qulab.h +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/tests/test_kad.py +0 -0
- {qulab-2.9.2 → qulab-2.9.3}/tests/test_scan.py +0 -0
@@ -421,14 +421,10 @@ def _load_workflow_list(workflow, lst, code_path):
|
|
421
421
|
for i, n in enumerate(lst):
|
422
422
|
try:
|
423
423
|
ret.append(load_workflow(n, code_path, mtime=workflow.__mtime__))
|
424
|
-
except TemplateKeyError:
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
except TemplateTypeError:
|
429
|
-
raise TemplateTypeError(
|
430
|
-
f"Workflow {workflow.__workflow_id__} type error in {i}th {n[0]} dependent mapping."
|
431
|
-
)
|
424
|
+
except TemplateKeyError as e:
|
425
|
+
msg, *_ = e.args
|
426
|
+
e.args = (f"Workflow {workflow.__workflow_id__} entry {i}: {msg}", )
|
427
|
+
raise e
|
432
428
|
return ret
|
433
429
|
|
434
430
|
|
@@ -470,8 +466,7 @@ def get_entries(workflow: WorkflowType,
|
|
470
466
|
|
471
467
|
def make_graph(workflow: WorkflowType, graph: dict, code_path: str | Path):
|
472
468
|
if workflow.__workflow_id__ in graph:
|
473
|
-
|
474
|
-
f"Workflow {workflow.__workflow_id__} has a circular dependency")
|
469
|
+
return graph
|
475
470
|
graph[workflow.__workflow_id__] = []
|
476
471
|
|
477
472
|
if hasattr(workflow, 'entries'):
|
@@ -77,16 +77,18 @@ class TemplateVarExtractor(ast.NodeVisitor):
|
|
77
77
|
if not isinstance(arg, ast.Constant) or not isinstance(
|
78
78
|
arg.value, str):
|
79
79
|
raise SyntaxError(
|
80
|
-
f"Argument of VAR function must be a string.
|
80
|
+
f"Argument of VAR function must be a string."
|
81
|
+
f" {self.fname}:{node.lineno}"
|
81
82
|
)
|
82
83
|
if len(node.args) != 1:
|
83
84
|
raise SyntaxError(
|
84
|
-
f"VAR function only accept one argument.
|
85
|
+
f"VAR function only accept one argument."
|
86
|
+
f" {self.fname}:{node.lineno}"
|
85
87
|
)
|
86
88
|
default = _notset
|
87
89
|
for k in node.keywords:
|
88
90
|
if k.arg == 'default':
|
89
|
-
|
91
|
+
default = k.value
|
90
92
|
# if isinstance(k.value, ast.Constant):
|
91
93
|
# # default = k.value.value
|
92
94
|
# default = k.value
|
@@ -97,7 +99,8 @@ class TemplateVarExtractor(ast.NodeVisitor):
|
|
97
99
|
# # )
|
98
100
|
else:
|
99
101
|
raise SyntaxError(
|
100
|
-
f"VAR function only accept keyword argument 'default'.
|
102
|
+
f"VAR function only accept keyword argument 'default'."
|
103
|
+
f" {self.fname}:{node.lineno}"
|
101
104
|
)
|
102
105
|
|
103
106
|
if default is _notset:
|
@@ -107,7 +110,8 @@ class TemplateVarExtractor(ast.NodeVisitor):
|
|
107
110
|
# ctx=ast.Load())
|
108
111
|
if arg.value not in self.mapping:
|
109
112
|
raise TemplateKeyError(
|
110
|
-
f"The variable '{arg.value}' is not provided in mapping.
|
113
|
+
f"The variable '{arg.value}' is not provided in mapping."
|
114
|
+
f" {self.fname}:{node.lineno}"
|
111
115
|
)
|
112
116
|
self.replacements[(node.lineno, node.end_lineno,
|
113
117
|
node.col_offset,
|
@@ -147,12 +151,13 @@ class TemplateVarExtractor(ast.NodeVisitor):
|
|
147
151
|
for var_name in template.get_identifiers():
|
148
152
|
if var_name not in self.mapping:
|
149
153
|
raise TemplateKeyError(
|
150
|
-
f"The variable '{var_name}' is not provided in mapping.
|
151
|
-
|
154
|
+
f"The variable '{var_name}' is not provided in mapping."
|
155
|
+
f" {self.fname}:{current_lineno}")
|
152
156
|
if not isinstance(self.mapping[var_name], str):
|
153
157
|
raise TemplateTypeError(
|
154
|
-
f"Mapping value for '{var_name}' must be a string
|
155
|
-
|
158
|
+
f"Mapping value for '{var_name}' must be a string,"
|
159
|
+
f" but got {type(self.mapping[var_name])}."
|
160
|
+
f" {self.fname}:{current_lineno}")
|
156
161
|
self.str_variables.add(var_name)
|
157
162
|
start, stop = 0, len(line)
|
158
163
|
if current_lineno == lineno:
|
@@ -125,7 +125,8 @@ def get_record(session: Session, id: int, datapath: Path) -> Record:
|
|
125
125
|
record = record_cache[id][1]
|
126
126
|
clear_cache()
|
127
127
|
logger.debug(f"update lru time for record cache: {id=}")
|
128
|
-
|
128
|
+
if record:
|
129
|
+
record_cache[id] = time.time(), record
|
129
130
|
return record
|
130
131
|
|
131
132
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import itertools
|
2
2
|
import logging
|
3
3
|
import re
|
4
|
+
import string
|
4
5
|
from collections import defaultdict
|
5
6
|
from functools import partial
|
6
7
|
from typing import Any, Callable, Literal, NamedTuple
|
@@ -87,7 +88,8 @@ def _add_action(attrs: dict, key: str, method: str, func: Callable, doc: dict,
|
|
87
88
|
matrix[arg] = attrs[arg]
|
88
89
|
for values in itertools.product(*[matrix[arg] for arg in arguments]):
|
89
90
|
kwds = dict(zip(arguments, values))
|
90
|
-
mapping[key.format(**kwds)] = partial(func, **kwds)
|
91
|
+
# mapping[key.format(**kwds)] = partial(func, **kwds)
|
92
|
+
mapping[string.Template(key).substitute(kwds)] = partial(func, **kwds)
|
91
93
|
|
92
94
|
|
93
95
|
def _build_docs(mapping: dict, attrs: dict) -> str:
|
@@ -180,6 +182,8 @@ class BaseDevice(metaclass=DeviceMeta):
|
|
180
182
|
|
181
183
|
class VisaDevice(BaseDevice):
|
182
184
|
|
185
|
+
error_query = 'SYST:ERR?'
|
186
|
+
|
183
187
|
def open(self) -> None:
|
184
188
|
import pyvisa
|
185
189
|
kwds = self.options.copy()
|
@@ -188,6 +192,7 @@ class VisaDevice(BaseDevice):
|
|
188
192
|
else:
|
189
193
|
rm = pyvisa.ResourceManager()
|
190
194
|
self.resource = rm.open_resource(self.address, **kwds)
|
195
|
+
self.errors = []
|
191
196
|
|
192
197
|
def close(self) -> None:
|
193
198
|
self.resource.close()
|
@@ -196,6 +201,15 @@ class VisaDevice(BaseDevice):
|
|
196
201
|
super().reset()
|
197
202
|
self.resource.write('*RST')
|
198
203
|
|
204
|
+
def check_error(self):
|
205
|
+
if self.error_query:
|
206
|
+
while True:
|
207
|
+
error = self.resource.query(self.error_query)
|
208
|
+
error_code = int(error.split(',')[0])
|
209
|
+
if error_code == 0:
|
210
|
+
break
|
211
|
+
self.errors.append(error)
|
212
|
+
|
199
213
|
@get('idn')
|
200
214
|
def get_idn(self) -> str:
|
201
215
|
"""Get instrument identification."""
|
@@ -209,13 +223,9 @@ class VisaDevice(BaseDevice):
|
|
209
223
|
@get('errors')
|
210
224
|
def get_errors(self) -> list[str]:
|
211
225
|
"""Get error queue."""
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
error_code = int(error.split(',')[0])
|
216
|
-
if error_code == 0:
|
217
|
-
break
|
218
|
-
errors.append(error)
|
226
|
+
self.check_error()
|
227
|
+
errors = self.errors
|
228
|
+
self.errors = []
|
219
229
|
return errors
|
220
230
|
|
221
231
|
@set('timeout')
|
@@ -79,7 +79,7 @@ def create_device(driver_name: str, *args, **kwds) -> BaseDevice:
|
|
79
79
|
except:
|
80
80
|
pass
|
81
81
|
|
82
|
-
dev = create_device_from_module(f"
|
82
|
+
dev = create_device_from_module(f"qulab.sys.drivers.{driver_name}",
|
83
83
|
args, kwds)
|
84
84
|
return dev
|
85
85
|
except:
|
@@ -0,0 +1,68 @@
|
|
1
|
+
import numpy as np
|
2
|
+
|
3
|
+
from qulab.sys import BaseDevice, exclude, get, set
|
4
|
+
|
5
|
+
|
6
|
+
class Device(BaseDevice):
|
7
|
+
|
8
|
+
channel = [
|
9
|
+
'X1', 'X2', 'X3', 'X4', 'Y1', 'Y2', 'Y3', 'Y4', 'Z1', 'Z2', 'Z3', 'Z4',
|
10
|
+
'M1', 'M2'
|
11
|
+
]
|
12
|
+
|
13
|
+
@get('IDN')
|
14
|
+
def get_idn(self) -> str:
|
15
|
+
return 'Fake Instrument'
|
16
|
+
|
17
|
+
@get('${channel_type}${channel_num}.SampleRate',
|
18
|
+
channel_type=['X', 'Y'],
|
19
|
+
channel_num=[1, 2, 3, 4])
|
20
|
+
def get_sample_rate_DDS(self, channel_type: str,
|
21
|
+
channel_num: int) -> float:
|
22
|
+
return 6e9
|
23
|
+
|
24
|
+
@get('${channel}.SampleRate', channel=['Z1', 'Z2', 'Z3', 'Z4'])
|
25
|
+
def get_sample_rate_Z(self, channel: str) -> float:
|
26
|
+
return 2e9
|
27
|
+
|
28
|
+
@get('${channel}.SampleRate', channel=['M1', 'M2'])
|
29
|
+
def get_sample_rate_AD(self, channel: str) -> float:
|
30
|
+
return 1e9
|
31
|
+
|
32
|
+
@set('${channel}.Vpp', channel=exclude(['M1', 'M2']))
|
33
|
+
def set_voltage(self, value: float, channel: str) -> None:
|
34
|
+
self.log.info(f'Set {channel} Vpp to {value}')
|
35
|
+
|
36
|
+
# @get('${channel}.Vpp', channel=exclude(['M1', 'M2']))
|
37
|
+
# def get_voltage(self, channel: str, default=0.0) -> float:
|
38
|
+
# return self._status.get(f'{channel}.Vpp', default)
|
39
|
+
|
40
|
+
@set('${channel}.Offset', channel=exclude(['M1', 'M2']))
|
41
|
+
def set_offset(
|
42
|
+
self,
|
43
|
+
value: float,
|
44
|
+
channel: str,
|
45
|
+
) -> None:
|
46
|
+
self.log.info(f'Set {channel} offset to {value}')
|
47
|
+
|
48
|
+
# @get('${channel}.Offset', channel=exclude(['M1', 'M2']))
|
49
|
+
# def get_offset(self, channel: str, default=0.0) -> float:
|
50
|
+
# return self._status.get(f'{channel}.Offset', default)
|
51
|
+
|
52
|
+
@set('${channel}.Waveform', channel=exclude(['M1', 'M2']))
|
53
|
+
def set_waveform(self, value, channel: str) -> None:
|
54
|
+
self.log.info(f'Set {channel} waveform to {value!r}')
|
55
|
+
|
56
|
+
# @get('${channel}.Waveform', channel=exclude(['M1', 'M2']))
|
57
|
+
# def get_waveform(self, channel: str, default=None) -> str:
|
58
|
+
# return self._status.get(f'{channel}.Waveform', default)
|
59
|
+
|
60
|
+
@set('${channel}.Size', channel=['M1', 'M2'])
|
61
|
+
def set_size(self, value, channel: str) -> None:
|
62
|
+
self.log.info(f'Set {channel} size to {value!r}')
|
63
|
+
|
64
|
+
@get('${channel}.Trace', channel=['M1', 'M2'])
|
65
|
+
def get_random_data(self, channel: str) -> np.ndarray:
|
66
|
+
size = self._status.get(f'{channel}.Size', 1024)
|
67
|
+
shots = self._status.get(f'{channel}.Shots', 128)
|
68
|
+
return np.random.randn(shots, size)
|
@@ -6,6 +6,9 @@ from fastapi import FastAPI, Request
|
|
6
6
|
from fastapi.responses import Response
|
7
7
|
from pydantic import BaseModel
|
8
8
|
|
9
|
+
NGINX_DIR = 'C:/Users/Administrator/Desktop/nginx/nginx-1.20.2'
|
10
|
+
HOST_URL = 'https://systemq.baqis.ac.cn'
|
11
|
+
|
9
12
|
db = {
|
10
13
|
"n01": {
|
11
14
|
"notebook_port": 1000,
|
@@ -28,7 +31,8 @@ db = {
|
|
28
31
|
}
|
29
32
|
|
30
33
|
|
31
|
-
def fmt_config(ip, notebook_port, codeserver_port, local_notebook_port,
|
34
|
+
def fmt_config(ip, notebook_port, codeserver_port, local_notebook_port,
|
35
|
+
local_codeserver_port, page):
|
32
36
|
return """
|
33
37
|
server {""" + f"""
|
34
38
|
listen {notebook_port} ssl;
|
@@ -108,6 +112,7 @@ server {""" + f"""
|
|
108
112
|
}
|
109
113
|
"""
|
110
114
|
|
115
|
+
|
111
116
|
def fmt_page(notebook_url, codeserver_url):
|
112
117
|
return """
|
113
118
|
<!DOCTYPE html>
|
@@ -142,7 +147,7 @@ class Node(BaseModel):
|
|
142
147
|
app = FastAPI()
|
143
148
|
|
144
149
|
|
145
|
-
@app.post("/
|
150
|
+
@app.post("/auth")
|
146
151
|
async def auth(request: Request, node: Node):
|
147
152
|
try:
|
148
153
|
assert node.name in db
|
@@ -156,34 +161,31 @@ async def auth(request: Request, node: Node):
|
|
156
161
|
else:
|
157
162
|
print(" CHANGE IP", db[node.name]['ip'], "===>", ip)
|
158
163
|
db[node.name]['ip'] = ip
|
159
|
-
|
164
|
+
|
160
165
|
#ip = request.headers.get('x-real-ip')
|
161
166
|
local_notebook_port = node.notebook_port
|
162
167
|
local_codeserver_port = node.codeserver_port
|
163
168
|
codeserver_path = quote_plus(node.codeserver_path)
|
164
169
|
|
165
|
-
codeserver_url = f"
|
166
|
-
notebook_url = f"
|
170
|
+
codeserver_url = f"{HOST_URL}:{codeserver_port}?tkn=lZBAQISFF532&folder={codeserver_path}"
|
171
|
+
notebook_url = f"{HOST_URL}:{notebook_port}/tree"
|
167
172
|
|
168
173
|
page = fmt_page(notebook_url, codeserver_url)
|
169
174
|
page = ''.join(page.splitlines())
|
170
175
|
|
171
|
-
config = fmt_config(ip, notebook_port, codeserver_port,
|
176
|
+
config = fmt_config(ip, notebook_port, codeserver_port,
|
177
|
+
local_notebook_port, local_codeserver_port, page)
|
172
178
|
|
173
|
-
with open(
|
174
|
-
f"C:/Users/Administrator/Desktop/nginx/nginx-1.20.2/conf/servers/{node.name}.conf",
|
175
|
-
"w") as f:
|
179
|
+
with open(f"{NGINX_DIR}/conf/servers/{node.name}.conf", "w") as f:
|
176
180
|
f.write(config)
|
177
181
|
|
178
182
|
await asyncio.sleep(0.1)
|
179
|
-
|
183
|
+
|
180
184
|
cwd = os.getcwd()
|
181
185
|
|
182
|
-
os.chdir(
|
186
|
+
os.chdir(NGINX_DIR)
|
183
187
|
|
184
|
-
os.system(
|
185
|
-
r'C:\Users\Administrator\Desktop\nginx\nginx-1.20.2\nginx.exe -s reload'
|
186
|
-
)
|
188
|
+
os.system(f'{NGINX_DIR}/nginx.exe -s reload')
|
187
189
|
|
188
190
|
os.chdir(cwd)
|
189
191
|
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "2.9.3"
|
@@ -1,52 +0,0 @@
|
|
1
|
-
from waveforms.sys.device import BaseDevice, exclude, get, set
|
2
|
-
|
3
|
-
|
4
|
-
class Device(BaseDevice):
|
5
|
-
|
6
|
-
channel = [
|
7
|
-
'X1', 'X2', 'X3', 'X4', 'Y1', 'Y2', 'Y3', 'Y4', 'Z1', 'Z2', 'Z3', 'Z4',
|
8
|
-
'M1', 'M2'
|
9
|
-
]
|
10
|
-
|
11
|
-
@get('IDN')
|
12
|
-
def get_idn(self) -> str:
|
13
|
-
return 'Fake Instrument'
|
14
|
-
|
15
|
-
@set('{channel}.Vpp', channel=exclude(['M1', 'M2']))
|
16
|
-
def set_voltage(self, value: float, channel: str) -> None:
|
17
|
-
self.log.info(f'Set {channel} Vpp to {value}')
|
18
|
-
|
19
|
-
@get('{channel}.Vpp', channel=exclude(['M1', 'M2']))
|
20
|
-
def get_voltage(self, channel: str, default=0.0) -> float:
|
21
|
-
return self._status.get(f'{channel}.Vpp', default)
|
22
|
-
|
23
|
-
@set('{channel}.Offset', channel=exclude(['M1', 'M2']))
|
24
|
-
def set_frequency(
|
25
|
-
self,
|
26
|
-
value: float,
|
27
|
-
channel: str,
|
28
|
-
) -> None:
|
29
|
-
self.log.info(f'Set {channel} offset to {value}')
|
30
|
-
|
31
|
-
@get('{channel}.Offset', channel=exclude(['M1', 'M2']))
|
32
|
-
def get_frequency(self, channel: str, default=0.0) -> float:
|
33
|
-
return self._status.get(f'{channel}.Offset', default)
|
34
|
-
|
35
|
-
@set('{channel}.Waveform', channel=exclude(['M1', 'M2']))
|
36
|
-
def set_waveform(self, value, channel: str) -> None:
|
37
|
-
self.log.info(f'Set {channel} waveform to {value!r}')
|
38
|
-
|
39
|
-
@get('{channel}.Waveform', channel=exclude(['M1', 'M2']))
|
40
|
-
def get_waveform(self, channel: str, default=None) -> str:
|
41
|
-
return self._status.get(f'{channel}.Waveform', default)
|
42
|
-
|
43
|
-
@set('{channel}.Size', channel=['M1', 'M2'])
|
44
|
-
def set_size(self, value, channel: str) -> None:
|
45
|
-
self.log.info(f'Set {channel} size to {value!r}')
|
46
|
-
|
47
|
-
@get('{channel}.Trace', channel=['M1', 'M2'])
|
48
|
-
def get_size(self, channel: str) -> str:
|
49
|
-
import numpy as np
|
50
|
-
size = self._status.get(f'{channel}.Size', 1024)
|
51
|
-
shots = self._status.get(f'{channel}.Shots', 128)
|
52
|
-
return np.random.randn(shots, size)
|
File without changes
|
qulab-2.9.2/qulab/version.py
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
__version__ = "2.9.2"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|