QuLab 2.4.8__cp310-cp310-win_amd64.whl → 2.4.10__cp310-cp310-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-2.4.8.dist-info → QuLab-2.4.10.dist-info}/METADATA +1 -1
- {QuLab-2.4.8.dist-info → QuLab-2.4.10.dist-info}/RECORD +11 -11
- qulab/executor/__main__.py +50 -10
- qulab/executor/load.py +1 -1
- qulab/executor/schedule.py +21 -6
- qulab/fun.cp310-win_amd64.pyd +0 -0
- qulab/version.py +1 -1
- {QuLab-2.4.8.dist-info → QuLab-2.4.10.dist-info}/LICENSE +0 -0
- {QuLab-2.4.8.dist-info → QuLab-2.4.10.dist-info}/WHEEL +0 -0
- {QuLab-2.4.8.dist-info → QuLab-2.4.10.dist-info}/entry_points.txt +0 -0
- {QuLab-2.4.8.dist-info → QuLab-2.4.10.dist-info}/top_level.txt +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
qulab/__init__.py,sha256=vkFybY8YSsQilYdThPRD83-btPAR41sy_WCXiM-6mME,141
|
|
2
2
|
qulab/__main__.py,sha256=sQ1z8lk9Q4pq7X9lEzLcY8t6Izr6uxQXO0t3qnTUxEs,575
|
|
3
3
|
qulab/dicttree.py,sha256=ZoSJVWK4VMqfzj42gPb_n5RqLlM6K1Me0WmLIfLEYf8,14195
|
|
4
|
-
qulab/fun.cp310-win_amd64.pyd,sha256=
|
|
5
|
-
qulab/version.py,sha256=
|
|
4
|
+
qulab/fun.cp310-win_amd64.pyd,sha256=KAsRuAJTtGSRKXTifm4XSgrCYw2fJgSo2okOeGjpzaU,31232
|
|
5
|
+
qulab/version.py,sha256=xpqAldAat_EPvLePX9Bp7bPX0gGKeKjd9kZbsEQVax4,22
|
|
6
6
|
qulab/executor/__init__.py,sha256=LosPzOMaljSZY1thy_Fxtbrgq7uubJszMABEB7oM7tU,101
|
|
7
|
-
qulab/executor/__main__.py,sha256=
|
|
8
|
-
qulab/executor/load.py,sha256=
|
|
9
|
-
qulab/executor/schedule.py,sha256=
|
|
7
|
+
qulab/executor/__main__.py,sha256=MMkkqpCH-Upwb1gBfvaN2ZuehXkJIMJGa1amYXEjn-Q,4017
|
|
8
|
+
qulab/executor/load.py,sha256=pxq8oFaJLJOT21ue9q-BNlFeJZcjxmGNN0Cz_TColxA,6211
|
|
9
|
+
qulab/executor/schedule.py,sha256=edPjE9U6_WQisSiOCcqov4DVbBVKTPWrBFwcy0ReC2s,10213
|
|
10
10
|
qulab/executor/storage.py,sha256=M66Q5_Uc5MMfc_QAuuaaexwAz7wxBPMkeleB5nRpQmI,4621
|
|
11
11
|
qulab/executor/transform.py,sha256=inaOn6eqCs22ZZ0xAQl8s8YCoEACaXSwFNNu7jqdwAk,2148
|
|
12
12
|
qulab/executor/utils.py,sha256=n3uCSKh-qdDFFeNvOpj7_es2_B4AaC-ASAlV9gPmSO0,3086
|
|
@@ -89,9 +89,9 @@ qulab/visualization/plot_seq.py,sha256=Uo1-dB1YE9IN_A9tuaOs9ZG3S5dKDQ_l98iD2Wbxp
|
|
|
89
89
|
qulab/visualization/qdat.py,sha256=HubXFu4nfcA7iUzghJGle1C86G6221hicLR0b-GqhKQ,5887
|
|
90
90
|
qulab/visualization/rot3d.py,sha256=jGHJcqj1lEWBUV-W4GUGONGacqjrYvuFoFCwPse5h1Y,757
|
|
91
91
|
qulab/visualization/widgets.py,sha256=HcYwdhDtLreJiYaZuN3LfofjJmZcLwjMfP5aasebgDo,3266
|
|
92
|
-
QuLab-2.4.
|
|
93
|
-
QuLab-2.4.
|
|
94
|
-
QuLab-2.4.
|
|
95
|
-
QuLab-2.4.
|
|
96
|
-
QuLab-2.4.
|
|
97
|
-
QuLab-2.4.
|
|
92
|
+
QuLab-2.4.10.dist-info/LICENSE,sha256=b4NRQ-GFVpJMT7RuExW3NwhfbrYsX7AcdB7Gudok-fs,1086
|
|
93
|
+
QuLab-2.4.10.dist-info/METADATA,sha256=NaE66YybeLcxWfsqXuotu8HuNYogTN6I68L0N33IlUg,3804
|
|
94
|
+
QuLab-2.4.10.dist-info/WHEEL,sha256=rzGfZgUcGeKSgIHGYMuqg4xE4VPHxnaldXH6BG0zjVk,101
|
|
95
|
+
QuLab-2.4.10.dist-info/entry_points.txt,sha256=b0v1GXOwmxY-nCCsPN_rHZZvY9CtTbWqrGj8u1m8yHo,45
|
|
96
|
+
QuLab-2.4.10.dist-info/top_level.txt,sha256=3T886LbAsbvjonu_TDdmgxKYUn939BVTRPxPl9r4cEg,6
|
|
97
|
+
QuLab-2.4.10.dist-info/RECORD,,
|
qulab/executor/__main__.py
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import functools
|
|
1
2
|
import importlib
|
|
3
|
+
import sys, os
|
|
2
4
|
from pathlib import Path
|
|
3
5
|
|
|
4
6
|
import click
|
|
7
|
+
from loguru import logger
|
|
5
8
|
|
|
6
9
|
from .load import find_unreferenced_workflows
|
|
7
10
|
from .schedule import maintain as maintain_workflow
|
|
@@ -10,6 +13,31 @@ from .transform import set_config_api
|
|
|
10
13
|
from .utils import workflow_template
|
|
11
14
|
|
|
12
15
|
|
|
16
|
+
def log_options(func):
|
|
17
|
+
|
|
18
|
+
@click.option("--debug", is_flag=True, help="Enable debug mode.")
|
|
19
|
+
@click.option("--log", type=str, help="Log file path.")
|
|
20
|
+
@functools.wraps(func) # 保持函数元信息
|
|
21
|
+
def wrapper(*args, log=None, debug=False, **kwargs):
|
|
22
|
+
print(f"{func} {log=}, {debug=}")
|
|
23
|
+
if log is None and not debug:
|
|
24
|
+
logger.remove()
|
|
25
|
+
logger.add(sys.stderr, level='INFO')
|
|
26
|
+
elif log is None and debug:
|
|
27
|
+
logger.remove()
|
|
28
|
+
logger.add(sys.stderr, level='DEBUG')
|
|
29
|
+
elif log is not None and not debug:
|
|
30
|
+
logger.configure(handlers=[dict(sink=log, level='INFO')])
|
|
31
|
+
elif log is not None and debug:
|
|
32
|
+
logger.configure(handlers=[
|
|
33
|
+
dict(sink=log, level='DEBUG'),
|
|
34
|
+
dict(sink=sys.stderr, level='DEBUG')
|
|
35
|
+
])
|
|
36
|
+
return func(*args, **kwargs)
|
|
37
|
+
|
|
38
|
+
return wrapper
|
|
39
|
+
|
|
40
|
+
|
|
13
41
|
@click.group()
|
|
14
42
|
def cli():
|
|
15
43
|
pass
|
|
@@ -17,7 +45,7 @@ def cli():
|
|
|
17
45
|
|
|
18
46
|
@click.command()
|
|
19
47
|
@click.argument('workflow')
|
|
20
|
-
@click.option('--code', '-c', default=None)
|
|
48
|
+
@click.option('--code', '-c', default=None, help='The path of the code.')
|
|
21
49
|
def create(workflow, code):
|
|
22
50
|
"""
|
|
23
51
|
Create a new workflow file.
|
|
@@ -26,6 +54,7 @@ def create(workflow, code):
|
|
|
26
54
|
code = Path.cwd()
|
|
27
55
|
|
|
28
56
|
fname = Path(code) / f'{workflow}'
|
|
57
|
+
fname = Path(os.path.expanduser(fname))
|
|
29
58
|
if fname.exists():
|
|
30
59
|
click.echo(f'{workflow} already exists')
|
|
31
60
|
return
|
|
@@ -40,11 +69,15 @@ def create(workflow, code):
|
|
|
40
69
|
|
|
41
70
|
@click.command()
|
|
42
71
|
@click.argument('workflow')
|
|
43
|
-
@click.option('--code', '-c', default=None)
|
|
44
|
-
@click.option('--data', '-d', default=None)
|
|
45
|
-
@click.option('--api', '-a', default=None)
|
|
46
|
-
@click.option('--plot', '-p', is_flag=True)
|
|
47
|
-
@click.option('--no-dependents',
|
|
72
|
+
@click.option('--code', '-c', default=None, help='The path of the code.')
|
|
73
|
+
@click.option('--data', '-d', default=None, help='The path of the data.')
|
|
74
|
+
@click.option('--api', '-a', default=None, help='The modlule name of the api.')
|
|
75
|
+
@click.option('--plot', '-p', is_flag=True, help='Plot the result.')
|
|
76
|
+
@click.option('--no-dependents',
|
|
77
|
+
'-n',
|
|
78
|
+
is_flag=True,
|
|
79
|
+
help='Do not run dependents.')
|
|
80
|
+
@log_options
|
|
48
81
|
def run(workflow, code, data, api, plot, no_dependents):
|
|
49
82
|
"""
|
|
50
83
|
Run a workflow.
|
|
@@ -57,6 +90,9 @@ def run(workflow, code, data, api, plot, no_dependents):
|
|
|
57
90
|
if data is None:
|
|
58
91
|
data = Path(code) / 'logs'
|
|
59
92
|
|
|
93
|
+
code = Path(os.path.expanduser(code))
|
|
94
|
+
data = Path(os.path.expanduser(data))
|
|
95
|
+
|
|
60
96
|
if no_dependents:
|
|
61
97
|
run_workflow(workflow, code, data, plot=plot)
|
|
62
98
|
else:
|
|
@@ -65,10 +101,11 @@ def run(workflow, code, data, api, plot, no_dependents):
|
|
|
65
101
|
|
|
66
102
|
@click.command()
|
|
67
103
|
@click.argument('workflow')
|
|
68
|
-
@click.option('--code', '-c', default=None)
|
|
69
|
-
@click.option('--data', '-d', default=None)
|
|
70
|
-
@click.option('--api', '-a', default=None)
|
|
71
|
-
@click.option('--plot', '-p', is_flag=True)
|
|
104
|
+
@click.option('--code', '-c', default=None, help='The path of the code.')
|
|
105
|
+
@click.option('--data', '-d', default=None, help='The path of the data.')
|
|
106
|
+
@click.option('--api', '-a', default=None, help='The modlule name of the api.')
|
|
107
|
+
@click.option('--plot', '-p', is_flag=True, help='Plot the result.')
|
|
108
|
+
@log_options
|
|
72
109
|
def maintain(workflow, code, data, api, plot):
|
|
73
110
|
"""
|
|
74
111
|
Maintain a workflow.
|
|
@@ -81,6 +118,9 @@ def maintain(workflow, code, data, api, plot):
|
|
|
81
118
|
if data is None:
|
|
82
119
|
data = Path(code) / 'logs'
|
|
83
120
|
|
|
121
|
+
code = Path(os.path.expanduser(code))
|
|
122
|
+
data = Path(os.path.expanduser(data))
|
|
123
|
+
|
|
84
124
|
maintain_workflow(workflow, code, data, run=False, plot=plot)
|
|
85
125
|
|
|
86
126
|
|
qulab/executor/load.py
CHANGED
|
@@ -150,7 +150,7 @@ def find_unreferenced_workflows(path: str) -> list[str]:
|
|
|
150
150
|
)
|
|
151
151
|
continue
|
|
152
152
|
try:
|
|
153
|
-
depends_list = depends_func()
|
|
153
|
+
depends_list = depends_func()[0]
|
|
154
154
|
except Exception as e:
|
|
155
155
|
warnings.warn(f"Error calling depends() in {rel_str}: {e}")
|
|
156
156
|
continue
|
qulab/executor/schedule.py
CHANGED
|
@@ -82,7 +82,7 @@ def call_plot(node, result, check=False):
|
|
|
82
82
|
node.plot(state, params, other)
|
|
83
83
|
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
@functools.lru_cache(maxsize=128)
|
|
86
86
|
def check_data(workflow: str, code_path: str | Path, state_path: str | Path,
|
|
87
87
|
plot: bool, session_id: str) -> Result:
|
|
88
88
|
"""
|
|
@@ -140,7 +140,7 @@ def check_data(workflow: str, code_path: str | Path, state_path: str | Path,
|
|
|
140
140
|
return result
|
|
141
141
|
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
@functools.lru_cache(maxsize=128)
|
|
144
144
|
def calibrate(workflow, code_path: str | Path, state_path: str | Path,
|
|
145
145
|
plot: bool, session_id: str) -> Result:
|
|
146
146
|
node = load_workflow(workflow, code_path)
|
|
@@ -172,15 +172,29 @@ def diagnose(node, code_path: str | Path, state_path: str | Path, plot: bool,
|
|
|
172
172
|
# bad data case
|
|
173
173
|
recalibrated = []
|
|
174
174
|
if result.bad_data:
|
|
175
|
+
logger.debug(f'"{node}": Bad data, diagnosing dependents')
|
|
175
176
|
recalibrated = [
|
|
176
177
|
diagnose(n, code_path, state_path, plot, session_id)
|
|
177
178
|
for n in get_dependents(node, code_path)
|
|
178
179
|
]
|
|
179
|
-
if not any(recalibrated)
|
|
180
|
+
if not any(recalibrated):
|
|
181
|
+
if result.bad_data:
|
|
182
|
+
raise CalibrationFailedError(
|
|
183
|
+
f'"{node}": bad data but no dependents recalibrated.')
|
|
180
184
|
logger.debug(f'"{node}": no dependents recalibrated.')
|
|
181
|
-
return False
|
|
182
185
|
# calibrate
|
|
183
|
-
|
|
186
|
+
if any(recalibrated):
|
|
187
|
+
logger.debug(
|
|
188
|
+
f'recalibrate "{node}" because some dependents recalibrated.')
|
|
189
|
+
elif not result.in_spec and not result.bad_data:
|
|
190
|
+
logger.debug(f'recalibrate "{node}" because out of spec.')
|
|
191
|
+
elif result.in_spec:
|
|
192
|
+
logger.error(f'Never reach: recalibrate "{node}" because in spec.')
|
|
193
|
+
elif result.bad_data:
|
|
194
|
+
logger.error(f'Never reach: recalibrate "{node}" because bad data.')
|
|
195
|
+
else:
|
|
196
|
+
logger.error(f'Never reach: recalibrate "{node}"')
|
|
197
|
+
|
|
184
198
|
result = calibrate(node, code_path, state_path, plot, session_id)
|
|
185
199
|
if result.bad_data or not result.in_spec:
|
|
186
200
|
raise CalibrationFailedError(
|
|
@@ -193,7 +207,7 @@ def get_dependents(workflow: str, code_path: str | Path) -> list[str]:
|
|
|
193
207
|
return [n for n in load_workflow(workflow, code_path).depends()[0]]
|
|
194
208
|
|
|
195
209
|
|
|
196
|
-
|
|
210
|
+
@logger.catch(reraise=True)
|
|
197
211
|
def maintain(node,
|
|
198
212
|
code_path: str | Path,
|
|
199
213
|
state_path: str | Path,
|
|
@@ -236,6 +250,7 @@ def maintain(node,
|
|
|
236
250
|
return
|
|
237
251
|
|
|
238
252
|
|
|
253
|
+
@logger.catch(reraise=True)
|
|
239
254
|
def run(node,
|
|
240
255
|
code_path: str | Path,
|
|
241
256
|
state_path: str | Path,
|
qulab/fun.cp310-win_amd64.pyd
CHANGED
|
Binary file
|
qulab/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "2.4.
|
|
1
|
+
__version__ = "2.4.10"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|