QuLab 2.9.2__cp312-cp312-win_amd64.whl → 2.9.4__cp312-cp312-win_amd64.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.
- qulab/executor/load.py +25 -17
- qulab/executor/schedule.py +6 -3
- qulab/executor/storage.py +22 -14
- qulab/executor/template.py +14 -9
- qulab/executor/transform.py +3 -3
- qulab/fun.cp312-win_amd64.pyd +0 -0
- qulab/scan/server.py +2 -1
- qulab/sys/__init__.py +2 -0
- qulab/sys/device/basedevice.py +18 -8
- qulab/sys/device/loader.py +1 -1
- qulab/sys/drivers/FakeInstrument.py +34 -18
- qulab/sys/net/nginx.py +16 -14
- qulab/version.py +1 -1
- {qulab-2.9.2.dist-info → qulab-2.9.4.dist-info}/METADATA +1 -1
- {qulab-2.9.2.dist-info → qulab-2.9.4.dist-info}/RECORD +19 -19
- {qulab-2.9.2.dist-info → qulab-2.9.4.dist-info}/WHEEL +0 -0
- {qulab-2.9.2.dist-info → qulab-2.9.4.dist-info}/entry_points.txt +0 -0
- {qulab-2.9.2.dist-info → qulab-2.9.4.dist-info}/licenses/LICENSE +0 -0
- {qulab-2.9.2.dist-info → qulab-2.9.4.dist-info}/top_level.txt +0 -0
qulab/executor/load.py
CHANGED
@@ -329,6 +329,23 @@ def load_workflow_from_file(file_name: str,
|
|
329
329
|
return module
|
330
330
|
|
331
331
|
|
332
|
+
def _generate_target_file_path(template_path: str | Path, hash_str: str,
|
333
|
+
content: str, base_path: str | Path) -> Path:
|
334
|
+
path = Path(template_path)
|
335
|
+
if path.stem == 'template':
|
336
|
+
path = path.parent / f'tmp{hash_str}.py'
|
337
|
+
elif path.stem.endswith('_template'):
|
338
|
+
path = path.parent / path.stem.replace('_template',
|
339
|
+
f'_tmp{hash_str}.py')
|
340
|
+
else:
|
341
|
+
path = path.parent / f'{path.stem}_tmp{hash_str}.py'
|
342
|
+
|
343
|
+
if 'templates' in path.parts:
|
344
|
+
path = Path(*['run' if p == 'templates' else p for p in path.parts])
|
345
|
+
else:
|
346
|
+
return Path('run') / path
|
347
|
+
|
348
|
+
|
332
349
|
def load_workflow_from_template(template_path: str,
|
333
350
|
mapping: dict[str, str],
|
334
351
|
base_path: str | Path,
|
@@ -346,13 +363,8 @@ def load_workflow_from_template(template_path: str,
|
|
346
363
|
content, hash_str = inject_mapping(template, mapping, str(path))
|
347
364
|
|
348
365
|
if target_path is None:
|
349
|
-
|
350
|
-
|
351
|
-
elif path.stem.endswith('_template'):
|
352
|
-
path = path.parent / path.stem.replace('_template',
|
353
|
-
f'_tmp{hash_str}.py')
|
354
|
-
else:
|
355
|
-
path = path.parent / f'{path.stem}_tmp{hash_str}.py'
|
366
|
+
path = _generate_target_file_path(template_path, hash_str, content,
|
367
|
+
base_path)
|
356
368
|
else:
|
357
369
|
path = target_path
|
358
370
|
|
@@ -421,14 +433,11 @@ def _load_workflow_list(workflow, lst, code_path):
|
|
421
433
|
for i, n in enumerate(lst):
|
422
434
|
try:
|
423
435
|
ret.append(load_workflow(n, code_path, mtime=workflow.__mtime__))
|
424
|
-
except TemplateKeyError:
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
raise TemplateTypeError(
|
430
|
-
f"Workflow {workflow.__workflow_id__} type error in {i}th {n[0]} dependent mapping."
|
431
|
-
)
|
436
|
+
except TemplateKeyError as e:
|
437
|
+
msg, *_ = e.args
|
438
|
+
e.args = (
|
439
|
+
f"Workflow {workflow.__workflow_id__} entry {i}: {msg}", )
|
440
|
+
raise e
|
432
441
|
return ret
|
433
442
|
|
434
443
|
|
@@ -470,8 +479,7 @@ def get_entries(workflow: WorkflowType,
|
|
470
479
|
|
471
480
|
def make_graph(workflow: WorkflowType, graph: dict, code_path: str | Path):
|
472
481
|
if workflow.__workflow_id__ in graph:
|
473
|
-
|
474
|
-
f"Workflow {workflow.__workflow_id__} has a circular dependency")
|
482
|
+
return graph
|
475
483
|
graph[workflow.__workflow_id__] = []
|
476
484
|
|
477
485
|
if hasattr(workflow, 'entries'):
|
qulab/executor/schedule.py
CHANGED
@@ -150,7 +150,8 @@ def call_check(workflow: WorkflowType, session_id: str, state_path: Path):
|
|
150
150
|
heads=get_heads(state_path),
|
151
151
|
previous_path=get_head(workflow.__workflow_id__,
|
152
152
|
state_path),
|
153
|
-
script_path=save_item(workflow.__source__,
|
153
|
+
script_path=save_item(workflow.__source__, 'items',
|
154
|
+
state_path))
|
154
155
|
|
155
156
|
save_report(workflow.__workflow_id__, report, state_path)
|
156
157
|
|
@@ -176,7 +177,8 @@ def call_calibrate(workflow: WorkflowType, session_id: str, state_path: Path):
|
|
176
177
|
heads=get_heads(state_path),
|
177
178
|
previous_path=get_head(workflow.__workflow_id__,
|
178
179
|
state_path),
|
179
|
-
script_path=save_item(workflow.__source__,
|
180
|
+
script_path=save_item(workflow.__source__, 'items',
|
181
|
+
state_path))
|
180
182
|
|
181
183
|
save_report(workflow.__workflow_id__, report, state_path)
|
182
184
|
|
@@ -274,7 +276,8 @@ def check_data(workflow: WorkflowType, state_path: str | Path, plot: bool,
|
|
274
276
|
heads=get_heads(state_path),
|
275
277
|
previous_path=get_head(workflow.__workflow_id__,
|
276
278
|
state_path),
|
277
|
-
script_path=save_item(workflow.__source__,
|
279
|
+
script_path=save_item(workflow.__source__, 'items',
|
280
|
+
state_path))
|
278
281
|
report.in_spec = False
|
279
282
|
report.bad_data = False
|
280
283
|
return report
|
qulab/executor/storage.py
CHANGED
@@ -118,14 +118,14 @@ class Report():
|
|
118
118
|
@property
|
119
119
|
def config(self):
|
120
120
|
if self.config_path is not None and self.base_path is not None:
|
121
|
-
return load_item(self.config_path, self.base_path)
|
121
|
+
return load_item(self.config_path, 'items', self.base_path)
|
122
122
|
else:
|
123
123
|
return None
|
124
124
|
|
125
125
|
@property
|
126
126
|
def script(self):
|
127
127
|
if self.script_path is not None and self.base_path is not None:
|
128
|
-
source = load_item(self.script_path, self.base_path)
|
128
|
+
source = load_item(self.script_path, 'items', self.base_path)
|
129
129
|
if isinstance(source, str):
|
130
130
|
return source
|
131
131
|
else:
|
@@ -137,7 +137,7 @@ class Report():
|
|
137
137
|
@property
|
138
138
|
def template_source(self):
|
139
139
|
if self.script_path is not None and self.base_path is not None:
|
140
|
-
source = load_item(self.script_path, self.base_path)
|
140
|
+
source = load_item(self.script_path, 'items', self.base_path)
|
141
141
|
return source
|
142
142
|
else:
|
143
143
|
return None
|
@@ -296,7 +296,7 @@ def create_index(name: str,
|
|
296
296
|
return index
|
297
297
|
|
298
298
|
|
299
|
-
def save_item(item, data_path):
|
299
|
+
def save_item(item, group, data_path):
|
300
300
|
salt = 0
|
301
301
|
buf = pickle.dumps(item)
|
302
302
|
buf = lzma.compress(buf)
|
@@ -306,7 +306,7 @@ def save_item(item, data_path):
|
|
306
306
|
h.update(f"{salt}".encode())
|
307
307
|
hashstr = h.hexdigest()
|
308
308
|
item_id = Path(hashstr[:2]) / hashstr[2:4] / hashstr[4:]
|
309
|
-
path = Path(data_path) /
|
309
|
+
path = Path(data_path) / group / item_id
|
310
310
|
if not path.exists():
|
311
311
|
path.parent.mkdir(parents=True, exist_ok=True)
|
312
312
|
with open(path, 'wb') as f:
|
@@ -318,6 +318,14 @@ def save_item(item, data_path):
|
|
318
318
|
return str(item_id)
|
319
319
|
|
320
320
|
|
321
|
+
def append_item_data(data, id, group, base_path):
|
322
|
+
path = Path(base_path) / group / id
|
323
|
+
if not path.exists():
|
324
|
+
raise ValueError(f"Item {id} does not exist.")
|
325
|
+
with open(path, 'ab') as f:
|
326
|
+
f.write(data)
|
327
|
+
|
328
|
+
|
321
329
|
def save_config_key_history(key: str, report: Report,
|
322
330
|
base_path: str | Path) -> int:
|
323
331
|
global __current_config_cache
|
@@ -412,20 +420,20 @@ def query_index(name: str, base_path: str | Path, index: int):
|
|
412
420
|
|
413
421
|
|
414
422
|
@lru_cache(maxsize=4096)
|
415
|
-
def load_item(id, base_path):
|
423
|
+
def load_item(id, group, base_path):
|
416
424
|
if isinstance(base_path, str) and base_path.startswith('ssh://'):
|
417
425
|
with SSHClient() as client:
|
418
426
|
cfg = parse_ssh_uri(base_path)
|
419
427
|
remote_base_path = cfg.pop('remote_file_path')
|
420
428
|
client.load_system_host_keys()
|
421
429
|
client.connect(**cfg)
|
422
|
-
buf = load_item_buf_from_scp(id, remote_base_path, client)
|
430
|
+
buf = load_item_buf_from_scp(id, group, remote_base_path, client)
|
423
431
|
else:
|
424
432
|
base_path = Path(base_path)
|
425
433
|
if zipfile.is_zipfile(base_path):
|
426
|
-
buf = load_item_buf_from_zipfile(id, base_path)
|
434
|
+
buf = load_item_buf_from_zipfile(id, group, base_path)
|
427
435
|
else:
|
428
|
-
path = Path(base_path) /
|
436
|
+
path = Path(base_path) / group / id
|
429
437
|
with open(path, 'rb') as f:
|
430
438
|
buf = f.read()
|
431
439
|
item = pickle.loads(lzma.decompress(buf))
|
@@ -494,9 +502,9 @@ def query_index_from_zipfile(name: str, base_path: str | Path, index: int):
|
|
494
502
|
return context.rstrip()
|
495
503
|
|
496
504
|
|
497
|
-
def load_item_buf_from_zipfile(id, base_path):
|
505
|
+
def load_item_buf_from_zipfile(id, group, base_path):
|
498
506
|
with zipfile.ZipFile(base_path) as zf:
|
499
|
-
with zf.open(f"{base_path.stem}/
|
507
|
+
with zf.open(f"{base_path.stem}/{group}/{id}") as f:
|
500
508
|
return f.read()
|
501
509
|
|
502
510
|
|
@@ -597,11 +605,11 @@ def query_index_from_scp(name: str, base_path: Path, client: SSHClient,
|
|
597
605
|
return None
|
598
606
|
|
599
607
|
|
600
|
-
def load_item_buf_from_scp(id: str,
|
608
|
+
def load_item_buf_from_scp(id: str, group: str, base_path: Path,
|
609
|
+
client: SSHClient):
|
601
610
|
try:
|
602
611
|
with client.open_sftp() as sftp:
|
603
|
-
with sftp.open(str(Path(base_path) /
|
604
|
-
'rb') as f:
|
612
|
+
with sftp.open(str(Path(base_path) / group / str(id)), 'rb') as f:
|
605
613
|
return f.read()
|
606
614
|
except SSHException:
|
607
615
|
return None
|
qulab/executor/template.py
CHANGED
@@ -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:
|
qulab/executor/transform.py
CHANGED
@@ -47,21 +47,21 @@ def obey_the_oracle(report: Report, data_path):
|
|
47
47
|
global __current_config_id
|
48
48
|
update_config(report.oracle)
|
49
49
|
cfg = export_config()
|
50
|
-
__current_config_id = save_item(cfg, data_path)
|
50
|
+
__current_config_id = save_item(cfg, 'items', data_path)
|
51
51
|
|
52
52
|
|
53
53
|
def update_parameters(report: Report, data_path):
|
54
54
|
global __current_config_id
|
55
55
|
update_config(report.parameters)
|
56
56
|
cfg = export_config()
|
57
|
-
__current_config_id = save_item(cfg, data_path)
|
57
|
+
__current_config_id = save_item(cfg, 'items', data_path)
|
58
58
|
|
59
59
|
|
60
60
|
def current_config(data_path):
|
61
61
|
global __current_config_id
|
62
62
|
if __current_config_id is None:
|
63
63
|
cfg = export_config()
|
64
|
-
__current_config_id = save_item(cfg, data_path)
|
64
|
+
__current_config_id = save_item(cfg, 'items', data_path)
|
65
65
|
return __current_config_id
|
66
66
|
|
67
67
|
|
qulab/fun.cp312-win_amd64.pyd
CHANGED
Binary file
|
qulab/scan/server.py
CHANGED
@@ -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
|
|
qulab/sys/__init__.py
CHANGED
qulab/sys/device/basedevice.py
CHANGED
@@ -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')
|
qulab/sys/device/loader.py
CHANGED
@@ -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:
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
import numpy as np
|
2
|
+
|
3
|
+
from qulab.sys import BaseDevice, exclude, get, set
|
2
4
|
|
3
5
|
|
4
6
|
class Device(BaseDevice):
|
@@ -12,41 +14,55 @@ class Device(BaseDevice):
|
|
12
14
|
def get_idn(self) -> str:
|
13
15
|
return 'Fake Instrument'
|
14
16
|
|
15
|
-
@
|
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']))
|
16
33
|
def set_voltage(self, value: float, channel: str) -> None:
|
17
34
|
self.log.info(f'Set {channel} Vpp to {value}')
|
18
35
|
|
19
|
-
@get('{channel}.Vpp', channel=exclude(['M1', 'M2']))
|
20
|
-
def get_voltage(self, channel: str, default=0.0) -> float:
|
21
|
-
|
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)
|
22
39
|
|
23
|
-
@set('{channel}.Offset', channel=exclude(['M1', 'M2']))
|
24
|
-
def
|
40
|
+
@set('${channel}.Offset', channel=exclude(['M1', 'M2']))
|
41
|
+
def set_offset(
|
25
42
|
self,
|
26
43
|
value: float,
|
27
44
|
channel: str,
|
28
45
|
) -> None:
|
29
46
|
self.log.info(f'Set {channel} offset to {value}')
|
30
47
|
|
31
|
-
@get('{channel}.Offset', channel=exclude(['M1', 'M2']))
|
32
|
-
def
|
33
|
-
|
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)
|
34
51
|
|
35
|
-
@set('{channel}.Waveform', channel=exclude(['M1', 'M2']))
|
52
|
+
@set('${channel}.Waveform', channel=exclude(['M1', 'M2']))
|
36
53
|
def set_waveform(self, value, channel: str) -> None:
|
37
54
|
self.log.info(f'Set {channel} waveform to {value!r}')
|
38
55
|
|
39
|
-
@get('{channel}.Waveform', channel=exclude(['M1', 'M2']))
|
40
|
-
def get_waveform(self, channel: str, default=None) -> str:
|
41
|
-
|
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)
|
42
59
|
|
43
|
-
@set('{channel}.Size', channel=['M1', 'M2'])
|
60
|
+
@set('${channel}.Size', channel=['M1', 'M2'])
|
44
61
|
def set_size(self, value, channel: str) -> None:
|
45
62
|
self.log.info(f'Set {channel} size to {value!r}')
|
46
63
|
|
47
|
-
@get('{channel}.Trace', channel=['M1', 'M2'])
|
48
|
-
def
|
49
|
-
import numpy as np
|
64
|
+
@get('${channel}.Trace', channel=['M1', 'M2'])
|
65
|
+
def get_random_data(self, channel: str) -> np.ndarray:
|
50
66
|
size = self._status.get(f'{channel}.Size', 1024)
|
51
67
|
shots = self._status.get(f'{channel}.Shots', 128)
|
52
68
|
return np.random.randn(shots, size)
|
qulab/sys/net/nginx.py
CHANGED
@@ -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
|
|
qulab/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "2.9.
|
1
|
+
__version__ = "2.9.4"
|
@@ -1,20 +1,20 @@
|
|
1
1
|
qulab/__init__.py,sha256=RrWRvG8Lw27zMr7XP8s-z43b09-wiwPi0ZtiNWbky-c,328
|
2
2
|
qulab/__main__.py,sha256=FL4YsGZL1jEtmcPc5WbleArzhOHLMsWl7OH3O-1d1ss,72
|
3
3
|
qulab/dicttree.py,sha256=ZoSJVWK4VMqfzj42gPb_n5RqLlM6K1Me0WmLIfLEYf8,14195
|
4
|
-
qulab/fun.cp312-win_amd64.pyd,sha256=
|
4
|
+
qulab/fun.cp312-win_amd64.pyd,sha256=q9jFCiecFi223J1brJR0UGqm1TiqR-fOfbTK2qVs1yQ,32256
|
5
5
|
qulab/typing.py,sha256=PRtwbCHWY2ROKK8GHq4Bo8llXrIGo6xC73DrQf7S9os,71
|
6
6
|
qulab/utils.py,sha256=65N2Xj7kqRsQ4epoLNY6tL-i5ts6Wk8YuJYee3Te6zI,3077
|
7
|
-
qulab/version.py,sha256=
|
7
|
+
qulab/version.py,sha256=CNO-J_I4xO7wq79g0PqvHvoxcy0QHZ0CMdgoYP0rkOI,21
|
8
8
|
qulab/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
9
|
qulab/cli/commands.py,sha256=6xd2eYw32k1NmfAuYSu__1kaP12Oz1QVqwbkYXdWno4,588
|
10
10
|
qulab/cli/config.py,sha256=7h3k0K8FYHhI6LVWt8BoDdKrX2ApFDBAUAUuXhHwst4,3799
|
11
11
|
qulab/executor/__init__.py,sha256=LosPzOMaljSZY1thy_Fxtbrgq7uubJszMABEB7oM7tU,101
|
12
12
|
qulab/executor/cli.py,sha256=8d-8bRWZ5lmsMtjASsl1zu1rV-syeAESMNVthvIQxlo,10018
|
13
|
-
qulab/executor/load.py,sha256=
|
14
|
-
qulab/executor/schedule.py,sha256=
|
15
|
-
qulab/executor/storage.py,sha256=
|
16
|
-
qulab/executor/template.py,sha256=
|
17
|
-
qulab/executor/transform.py,sha256=
|
13
|
+
qulab/executor/load.py,sha256=cSmP4xICJDNjtHdRh3Hs1nHqfw4OTi7adPaMnrml_yg,17736
|
14
|
+
qulab/executor/schedule.py,sha256=XRimchHYCgnMAOtCvNLjwMv9IkcTAyBAUCHKQs5RBRw,18745
|
15
|
+
qulab/executor/storage.py,sha256=PWQIDYjQaoyLGgAKh0X1tlNQTgDWR8bI-HVie4hSkyA,21075
|
16
|
+
qulab/executor/template.py,sha256=dKQM3IlADdTi9qp0fnOYjyycRNEl7KeSCBZhwbmP8bQ,10828
|
17
|
+
qulab/executor/transform.py,sha256=ABrnD0l53NI2y2e8ETYO7lmqGtyiE6EAY965kFRqme0,2311
|
18
18
|
qulab/executor/utils.py,sha256=l_b0y2kMwYKyyXeFtoblPYwKNU-wiFQ9PMo9QlWl9wE,6213
|
19
19
|
qulab/monitor/__init__.py,sha256=xEVDkJF8issrsDeLqQmDsvtRmrf-UiViFcGTWuzdlFU,43
|
20
20
|
qulab/monitor/__main__.py,sha256=k2H1H5Zf9LLXTDLISJkbikLH-z0f1e5i5i6wXXYPOrE,105
|
@@ -34,7 +34,7 @@ qulab/scan/optimize.py,sha256=zOR4Wp96bLarTSiPJ-cTAfT-V_MU-YEgB-XqYsBhS30,2637
|
|
34
34
|
qulab/scan/query.py,sha256=RM8bG4Tcx_PaNk8tv9HdlTZ1dGuuSr3sZVkYVq2BtfQ,12183
|
35
35
|
qulab/scan/record.py,sha256=MVmxhIzwmOju7eWxJEWsqJZlVgrDeRXGMfNvXImj7Ms,21883
|
36
36
|
qulab/scan/scan.py,sha256=p7LZvmjDSnUHeszgILlEXFIspHVPLk9Rt2dVqFtNsaQ,40645
|
37
|
-
qulab/scan/server.py,sha256=
|
37
|
+
qulab/scan/server.py,sha256=zyzuO6yFu3Xv3qOK5bKmPXlEX6lku6WHG42fy21SrCg,20588
|
38
38
|
qulab/scan/space.py,sha256=t8caa_gKlnhaAIEksJyxINUTecOS7lMWAz1HDKlVcds,6909
|
39
39
|
qulab/scan/utils.py,sha256=YXFA19HEakHB5TaPOU9CjQ1Lc3GUJaSIGOtiWjAWsG4,6353
|
40
40
|
qulab/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -55,15 +55,15 @@ qulab/storage/models/models.py,sha256=h7nPI0uctftbxe8_cu3WkF59tKS4BuAIGCBmaHsuRB
|
|
55
55
|
qulab/storage/models/record.py,sha256=F5yu-Sf1aK9pkfCihb2AUU8b5HLlYZAUzrkUkBDpx_4,5131
|
56
56
|
qulab/storage/models/report.py,sha256=WO_hahL3VwWn3vn8tFZQ2ffYahV7RllIlAJPFmbVkdA,820
|
57
57
|
qulab/storage/models/tag.py,sha256=KPpiEm0SHI613-XLu3NBYE-qeIO9gwuKPw6se2obgPw,2432
|
58
|
-
qulab/sys/__init__.py,sha256=
|
58
|
+
qulab/sys/__init__.py,sha256=Z8_77Ddg3NpewBVx1BOeRWLs42QReZeiXllA2Y1pVJo,124
|
59
59
|
qulab/sys/chat.py,sha256=t7wSlREOQ_Ke0pO9bfpkik9wY1qeiTbRF1dial9IbII,23137
|
60
60
|
qulab/sys/ipy_events.py,sha256=rGjsApv58_Gwd_TH6ecPnyXK34_ZYZsaX8tk32ozLGY,3014
|
61
61
|
qulab/sys/progress.py,sha256=2iYskzRdOC2EM4wtbzm0u1kovjGrF_A0W1kCxbftyzE,5540
|
62
62
|
qulab/sys/device/__init__.py,sha256=ZZxPJ9_MHModvghQoZOSWjIdeo3vhg2TJETDdrwQvkU,152
|
63
|
-
qulab/sys/device/basedevice.py,sha256=
|
64
|
-
qulab/sys/device/loader.py,sha256=
|
63
|
+
qulab/sys/device/basedevice.py,sha256=lTPv5geL556h9Hfp9zqJQ5miuX8CK2PBHJ9xY1ix4g4,7017
|
64
|
+
qulab/sys/device/loader.py,sha256=RyUoykxGyfn-k22NWo-B06_AK_TMH8to4FzSkODLJHM,2583
|
65
65
|
qulab/sys/device/utils.py,sha256=5uqGOcaZlubCIw7gsknpB-tiFQyq8y6ebQxHcouQGUs,2393
|
66
|
-
qulab/sys/drivers/FakeInstrument.py,sha256=
|
66
|
+
qulab/sys/drivers/FakeInstrument.py,sha256=xBz-uuOivB1mKeJEfJJMEDTZujtpwDPJRWiIaoam0KM,2479
|
67
67
|
qulab/sys/drivers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
68
68
|
qulab/sys/net/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
69
69
|
qulab/sys/net/bencoder.py,sha256=tsMjTG-E_EQokfWrZgJvxO3dTGaM6NOVzPPKsify23A,5164
|
@@ -72,7 +72,7 @@ qulab/sys/net/dhcp.py,sha256=zKd4jQvSc8xYr7PcyR0tLlChpUYBb-WUr7-RzKBnClM,24052
|
|
72
72
|
qulab/sys/net/dhcpd.py,sha256=NB3lVTdk8xkwf4B-v9pOB0ylNj6SbYELGLSPgEQkOak,5498
|
73
73
|
qulab/sys/net/kad.py,sha256=uf9bNU2M3JLk6ZH04PDEdrChs4OOkHYoBHYodGIn_WE,40123
|
74
74
|
qulab/sys/net/kcp.py,sha256=NUDSkCXAneZoL-KDi_yGNfIdWycSCJRSpH0KL-tvpVQ,5952
|
75
|
-
qulab/sys/net/nginx.py,sha256=
|
75
|
+
qulab/sys/net/nginx.py,sha256=dRjkHTpGIGzf3lCsD1uyIsNwqjaE4lypK4aBuqZD3rc,5084
|
76
76
|
qulab/sys/rpc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
77
77
|
qulab/sys/rpc/client.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
78
78
|
qulab/sys/rpc/exceptions.py,sha256=ZXfQYcF9MhUp4tvm7LI6h0jKbF8LUStEOfiW-keoGC0,2663
|
@@ -97,9 +97,9 @@ qulab/visualization/plot_seq.py,sha256=Uo1-dB1YE9IN_A9tuaOs9ZG3S5dKDQ_l98iD2Wbxp
|
|
97
97
|
qulab/visualization/qdat.py,sha256=HubXFu4nfcA7iUzghJGle1C86G6221hicLR0b-GqhKQ,5887
|
98
98
|
qulab/visualization/rot3d.py,sha256=jGHJcqj1lEWBUV-W4GUGONGacqjrYvuFoFCwPse5h1Y,757
|
99
99
|
qulab/visualization/widgets.py,sha256=HcYwdhDtLreJiYaZuN3LfofjJmZcLwjMfP5aasebgDo,3266
|
100
|
-
qulab-2.9.
|
101
|
-
qulab-2.9.
|
102
|
-
qulab-2.9.
|
103
|
-
qulab-2.9.
|
104
|
-
qulab-2.9.
|
105
|
-
qulab-2.9.
|
100
|
+
qulab-2.9.4.dist-info/licenses/LICENSE,sha256=b4NRQ-GFVpJMT7RuExW3NwhfbrYsX7AcdB7Gudok-fs,1086
|
101
|
+
qulab-2.9.4.dist-info/METADATA,sha256=JUsYx6qDV_tYVQkAFe6ioNjMx-5RhBBtO1cog0pDFKw,3826
|
102
|
+
qulab-2.9.4.dist-info/WHEEL,sha256=ovhA9_Ei_7ok2fAych90j-feDV4goiAxbO7REePtvw0,101
|
103
|
+
qulab-2.9.4.dist-info/entry_points.txt,sha256=b0v1GXOwmxY-nCCsPN_rHZZvY9CtTbWqrGj8u1m8yHo,45
|
104
|
+
qulab-2.9.4.dist-info/top_level.txt,sha256=3T886LbAsbvjonu_TDdmgxKYUn939BVTRPxPl9r4cEg,6
|
105
|
+
qulab-2.9.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|