QuLab 2.6.0__tar.gz → 2.6.2__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.6.0 → qulab-2.6.2}/PKG-INFO +1 -1
- {qulab-2.6.0 → qulab-2.6.2}/QuLab.egg-info/PKG-INFO +1 -1
- {qulab-2.6.0 → qulab-2.6.2}/qulab/__init__.py +1 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/executor/cli.py +59 -33
- {qulab-2.6.0 → qulab-2.6.2}/qulab/executor/load.py +8 -8
- {qulab-2.6.0 → qulab-2.6.2}/qulab/executor/schedule.py +8 -4
- {qulab-2.6.0 → qulab-2.6.2}/qulab/executor/storage.py +34 -2
- {qulab-2.6.0 → qulab-2.6.2}/qulab/executor/transform.py +8 -48
- {qulab-2.6.0 → qulab-2.6.2}/qulab/executor/utils.py +3 -3
- qulab-2.6.2/qulab/version.py +1 -0
- qulab-2.6.0/qulab/version.py +0 -1
- {qulab-2.6.0 → qulab-2.6.2}/LICENSE +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/MANIFEST.in +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/QuLab.egg-info/SOURCES.txt +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/QuLab.egg-info/dependency_links.txt +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/QuLab.egg-info/entry_points.txt +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/QuLab.egg-info/requires.txt +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/QuLab.egg-info/top_level.txt +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/README.md +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/pyproject.toml +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/__main__.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/cli/__init__.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/cli/commands.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/cli/config.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/dicttree.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/executor/__init__.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/monitor/__init__.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/monitor/__main__.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/monitor/config.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/monitor/dataset.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/monitor/event_queue.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/monitor/mainwindow.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/monitor/monitor.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/monitor/ploter.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/monitor/qt_compat.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/monitor/toolbar.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/__init__.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/curd.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/expression.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/models.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/optimize.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/query.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/record.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/scan.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/server.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/space.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/utils.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/__init__.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/__main__.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/backend/__init__.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/backend/redis.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/base_dataset.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/chunk.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/dataset.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/file.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/models/__init__.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/models/base.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/models/config.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/models/file.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/models/ipy.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/models/models.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/models/record.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/models/report.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/models/tag.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/storage.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/__init__.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/chat.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/device/__init__.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/device/basedevice.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/device/loader.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/device/utils.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/drivers/FakeInstrument.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/drivers/__init__.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/ipy_events.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/net/__init__.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/net/bencoder.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/net/cli.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/net/dhcp.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/net/dhcpd.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/net/kad.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/net/kcp.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/net/nginx.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/progress.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/__init__.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/client.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/exceptions.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/msgpack.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/msgpack.pyi +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/router.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/rpc.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/serialize.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/server.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/socket.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/utils.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/worker.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/zmq_socket.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/typing.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/visualization/__init__.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/visualization/__main__.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/visualization/_autoplot.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/visualization/plot_circ.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/visualization/plot_layout.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/visualization/plot_seq.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/visualization/qdat.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/visualization/rot3d.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/qulab/visualization/widgets.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/setup.cfg +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/setup.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/src/qulab.h +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/tests/test_kad.py +0 -0
- {qulab-2.6.0 → qulab-2.6.2}/tests/test_scan.py +0 -0
@@ -1,5 +1,6 @@
|
|
1
1
|
from .executor.storage import find_result
|
2
2
|
from .executor.storage import get_result_by_index as get_result
|
3
|
+
from .executor.utils import debug_analyze
|
3
4
|
from .scan import Scan, get_record, load_record, lookup, lookup_list
|
4
5
|
from .version import __version__
|
5
6
|
from .visualization import autoplot
|
@@ -12,6 +12,7 @@ from .load import (WorkflowType, find_unreferenced_workflows, get_entries,
|
|
12
12
|
load_workflow, make_graph)
|
13
13
|
from .schedule import maintain as maintain_workflow
|
14
14
|
from .schedule import run as run_workflow
|
15
|
+
from .schedule import CalibrationFailedError
|
15
16
|
from .transform import set_config_api
|
16
17
|
from .utils import workflow_template
|
17
18
|
|
@@ -135,16 +136,20 @@ def get(key, api):
|
|
135
136
|
'-n',
|
136
137
|
is_flag=True,
|
137
138
|
help='Do not run dependents.')
|
139
|
+
@click.option('--retry', '-r', default=1, type=int, help='Retry times.')
|
138
140
|
@click.option('--update', '-u', is_flag=True)
|
139
141
|
@log_options
|
140
142
|
@command_option('run')
|
141
|
-
def run(workflow, code, data, api, plot, no_dependents, update):
|
143
|
+
def run(workflow, code, data, api, plot, no_dependents, retry, update):
|
142
144
|
"""
|
143
145
|
Run a workflow.
|
144
146
|
"""
|
145
147
|
logger.info(
|
146
|
-
f'[CMD]: run {workflow} --code {code} --data {data} --api {api}
|
147
|
-
|
148
|
+
f'[CMD]: run {workflow} --code {code} --data {data} --api {api}'
|
149
|
+
f'{" --plot" if plot else ""}'
|
150
|
+
f'{" --no-dependents" if no_dependents else ""}'
|
151
|
+
f' --retry {retry}'
|
152
|
+
f'{" --update " if update else ""}')
|
148
153
|
if api is not None:
|
149
154
|
api = importlib.import_module(api)
|
150
155
|
set_config_api(api.query_config, api.update_config, api.export_config)
|
@@ -159,42 +164,56 @@ def run(workflow, code, data, api, plot, no_dependents, update):
|
|
159
164
|
wf = load_workflow(workflow, code)
|
160
165
|
check_toplogy(wf, code)
|
161
166
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
167
|
+
for i in range(retry):
|
168
|
+
try:
|
169
|
+
if no_dependents:
|
170
|
+
if hasattr(wf, 'entries'):
|
171
|
+
for entry in get_entries(wf, code):
|
172
|
+
run_workflow(entry,
|
173
|
+
code,
|
174
|
+
data,
|
175
|
+
plot=plot,
|
176
|
+
update=update)
|
177
|
+
else:
|
178
|
+
run_workflow(wf, code, data, plot=plot, update=update)
|
179
|
+
else:
|
180
|
+
if hasattr(wf, 'entries'):
|
181
|
+
for entry in get_entries(wf, code):
|
182
|
+
maintain_workflow(entry,
|
183
|
+
code,
|
184
|
+
data,
|
185
|
+
run=True,
|
186
|
+
plot=plot,
|
187
|
+
update=update)
|
188
|
+
else:
|
189
|
+
maintain_workflow(wf,
|
190
|
+
code,
|
191
|
+
data,
|
192
|
+
run=True,
|
193
|
+
plot=plot,
|
194
|
+
update=update)
|
195
|
+
break
|
196
|
+
except CalibrationFailedError as e:
|
197
|
+
if i == retry - 1:
|
198
|
+
raise e
|
199
|
+
logger.warning(f'Calibration failed, retrying ({i + 1}/{retry})')
|
200
|
+
continue
|
184
201
|
|
185
202
|
|
186
203
|
@click.command()
|
187
204
|
@click.argument('workflow')
|
205
|
+
@click.option('--retry', '-r', default=1, type=int, help='Retry times.')
|
188
206
|
@click.option('--plot', '-p', is_flag=True, help='Plot the result.')
|
189
207
|
@log_options
|
190
208
|
@command_option('maintain')
|
191
|
-
def maintain(workflow, code, data, api, plot):
|
209
|
+
def maintain(workflow, code, data, api, retry, plot):
|
192
210
|
"""
|
193
211
|
Maintain a workflow.
|
194
212
|
"""
|
195
213
|
logger.info(
|
196
|
-
f'[CMD]: maintain {workflow} --code {code} --data {data} --api {api}
|
197
|
-
|
214
|
+
f'[CMD]: maintain {workflow} --code {code} --data {data} --api {api}'
|
215
|
+
f' --retry {retry}'
|
216
|
+
f'{" --plot" if plot else ""}')
|
198
217
|
if api is not None:
|
199
218
|
api = importlib.import_module(api)
|
200
219
|
set_config_api(api.query_config, api.update_config, api.export_config)
|
@@ -209,8 +228,15 @@ def maintain(workflow, code, data, api, plot):
|
|
209
228
|
wf = load_workflow(workflow, code)
|
210
229
|
check_toplogy(wf, code)
|
211
230
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
231
|
+
for i in range(retry):
|
232
|
+
try:
|
233
|
+
if hasattr(wf, 'entries'):
|
234
|
+
for entry in get_entries(wf, code):
|
235
|
+
maintain_workflow(entry, code, data, run=False, plot=plot)
|
236
|
+
else:
|
237
|
+
maintain_workflow(wf, code, data, run=False, plot=plot)
|
238
|
+
except CalibrationFailedError as e:
|
239
|
+
if i == retry - 1:
|
240
|
+
raise e
|
241
|
+
logger.warning(f'Calibration failed, retrying ({i + 1}/{retry})')
|
242
|
+
continue
|
@@ -123,7 +123,7 @@ def verify_check_method(module: WorkflowType):
|
|
123
123
|
|
124
124
|
|
125
125
|
def verify_dependence_key(workflow: str | tuple[str, dict[str, Any]]
|
126
|
-
| tuple[str, str, dict[str, Any]]):
|
126
|
+
| tuple[str, str, dict[str, Any]], base_path: Path):
|
127
127
|
if isinstance(workflow, str):
|
128
128
|
return
|
129
129
|
if not isinstance(workflow, tuple) or len(workflow) not in [2, 3]:
|
@@ -135,7 +135,7 @@ def verify_dependence_key(workflow: str | tuple[str, dict[str, Any]]
|
|
135
135
|
raise FileNotFoundError(f"File not found: {file_name}")
|
136
136
|
elif len(workflow) == 3:
|
137
137
|
template_path, target_path, mapping = workflow
|
138
|
-
if not Path(template_path).exists():
|
138
|
+
if not (Path(base_path) / template_path).exists():
|
139
139
|
raise FileNotFoundError(f"File not found: {template_path}")
|
140
140
|
if not isinstance(target_path, (Path, str)) or target_path == '':
|
141
141
|
raise ValueError(f"Invalid target_path: {target_path}")
|
@@ -165,7 +165,7 @@ def verify_dependence_key(workflow: str | tuple[str, dict[str, Any]]
|
|
165
165
|
return
|
166
166
|
|
167
167
|
|
168
|
-
def verify_depends(module: WorkflowType):
|
168
|
+
def verify_depends(module: WorkflowType, base_path):
|
169
169
|
if not hasattr(module, 'depends'):
|
170
170
|
return
|
171
171
|
|
@@ -184,10 +184,10 @@ def verify_depends(module: WorkflowType):
|
|
184
184
|
f"Workflow {module.__file__} 'depends' should be a callable or a list"
|
185
185
|
)
|
186
186
|
for workflow in deps:
|
187
|
-
verify_dependence_key(workflow)
|
187
|
+
verify_dependence_key(workflow, base_path)
|
188
188
|
|
189
189
|
|
190
|
-
def verify_entries(module: WorkflowType):
|
190
|
+
def verify_entries(module: WorkflowType, base_path):
|
191
191
|
if not hasattr(module, 'entries'):
|
192
192
|
return
|
193
193
|
|
@@ -206,7 +206,7 @@ def verify_entries(module: WorkflowType):
|
|
206
206
|
f"Workflow {module.__file__} 'entries' should be a callable or a list"
|
207
207
|
)
|
208
208
|
for workflow in deps:
|
209
|
-
verify_dependence_key(workflow)
|
209
|
+
verify_dependence_key(workflow, base_path)
|
210
210
|
|
211
211
|
|
212
212
|
def is_workflow(module: ModuleType) -> bool:
|
@@ -307,7 +307,7 @@ def load_workflow_from_file(file_name: str,
|
|
307
307
|
module.__mtime__ = (base_path / path).stat().st_mtime
|
308
308
|
|
309
309
|
if hasattr(module, 'entries'):
|
310
|
-
verify_entries(module)
|
310
|
+
verify_entries(module, base_path)
|
311
311
|
return module
|
312
312
|
|
313
313
|
if not hasattr(module, '__timeout__'):
|
@@ -315,7 +315,7 @@ def load_workflow_from_file(file_name: str,
|
|
315
315
|
|
316
316
|
if not hasattr(module, 'depends'):
|
317
317
|
module.depends = lambda: []
|
318
|
-
verify_depends(module)
|
318
|
+
verify_depends(module, base_path)
|
319
319
|
verify_calibrate_method(module)
|
320
320
|
verify_check_method(module)
|
321
321
|
|
@@ -125,7 +125,8 @@ def check_data(workflow: WorkflowType, code_path: str | Path,
|
|
125
125
|
if history is None:
|
126
126
|
logger.debug(f'No history found for "{workflow.__workflow_id__}"')
|
127
127
|
result = Result(workflow=workflow.__workflow_id__,
|
128
|
-
config_path=current_config(state_path)
|
128
|
+
config_path=current_config(state_path),
|
129
|
+
base_path=state_path)
|
129
130
|
result.in_spec = False
|
130
131
|
result.bad_data = False
|
131
132
|
return result
|
@@ -153,7 +154,8 @@ def check_data(workflow: WorkflowType, code_path: str | Path,
|
|
153
154
|
)
|
154
155
|
result = Result(workflow=workflow.__workflow_id__,
|
155
156
|
data=data,
|
156
|
-
config_path=current_config(state_path)
|
157
|
+
config_path=current_config(state_path),
|
158
|
+
base_path=state_path)
|
157
159
|
#save_result(workflow.__workflow_id__, result, state_path)
|
158
160
|
|
159
161
|
logger.debug(f'Checked "{workflow.__workflow_id__}" !')
|
@@ -183,7 +185,8 @@ def check_data(workflow: WorkflowType, code_path: str | Path,
|
|
183
185
|
)
|
184
186
|
result = Result(workflow=workflow.__workflow_id__,
|
185
187
|
data=data,
|
186
|
-
config_path=current_config(state_path)
|
188
|
+
config_path=current_config(state_path),
|
189
|
+
base_path=state_path)
|
187
190
|
save_result(workflow.__workflow_id__, result, state_path)
|
188
191
|
|
189
192
|
logger.debug(f'Calibrated "{workflow}" !')
|
@@ -213,7 +216,8 @@ def calibrate(workflow: WorkflowType, code_path: str | Path,
|
|
213
216
|
)
|
214
217
|
result = Result(workflow=workflow.__workflow_id__,
|
215
218
|
data=data,
|
216
|
-
config_path=current_config(state_path)
|
219
|
+
config_path=current_config(state_path),
|
220
|
+
base_path=state_path)
|
217
221
|
save_result(workflow.__workflow_id__, result, state_path)
|
218
222
|
logger.debug(f'Calibrated "{workflow.__workflow_id__}" !')
|
219
223
|
result = call_analyzer(workflow, result, history, check=False, plot=plot)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import hashlib
|
1
2
|
import lzma
|
2
3
|
import pickle
|
3
4
|
import uuid
|
@@ -50,9 +51,8 @@ class Result():
|
|
50
51
|
|
51
52
|
@property
|
52
53
|
def config(self):
|
53
|
-
from . import transform
|
54
54
|
if self.config_path is not None and self.base_path is not None:
|
55
|
-
return
|
55
|
+
return load_config(self.config_path, self.base_path)
|
56
56
|
else:
|
57
57
|
return None
|
58
58
|
|
@@ -241,3 +241,35 @@ def get_result_by_index(
|
|
241
241
|
return load_result(path, base_path)
|
242
242
|
except:
|
243
243
|
return None
|
244
|
+
|
245
|
+
|
246
|
+
def save_config(cfg, data_path):
|
247
|
+
i = 0
|
248
|
+
buf = pickle.dumps(cfg)
|
249
|
+
buf = lzma.compress(buf)
|
250
|
+
h = hashlib.md5(buf)
|
251
|
+
|
252
|
+
while True:
|
253
|
+
salt = f"{i}".encode()
|
254
|
+
h.update(salt)
|
255
|
+
hashstr = h.hexdigest()
|
256
|
+
cfg_id = Path(hashstr[:2]) / hashstr[2:4] / hashstr[4:]
|
257
|
+
path = Path(data_path) / 'config' / cfg_id
|
258
|
+
if not path.exists():
|
259
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
260
|
+
with open(path, 'wb') as f:
|
261
|
+
f.write(buf)
|
262
|
+
break
|
263
|
+
elif path.read_bytes() == buf:
|
264
|
+
break
|
265
|
+
i += 1
|
266
|
+
return str(cfg_id)
|
267
|
+
|
268
|
+
|
269
|
+
@lru_cache(maxsize=1024)
|
270
|
+
def load_config(id, data_path):
|
271
|
+
path = Path(data_path) / 'config' / id
|
272
|
+
with open(path, 'rb') as f:
|
273
|
+
buf = f.read()
|
274
|
+
cfg = pickle.loads(lzma.decompress(buf))
|
275
|
+
return cfg
|
@@ -1,12 +1,6 @@
|
|
1
|
-
import
|
2
|
-
import hashlib
|
3
|
-
import lzma
|
4
|
-
import pickle
|
5
|
-
from pathlib import Path
|
1
|
+
from .storage import Result, save_config
|
6
2
|
|
7
|
-
|
8
|
-
|
9
|
-
__config_id = None
|
3
|
+
__current_config_id = None
|
10
4
|
|
11
5
|
|
12
6
|
def _query_config(name: str, default=None):
|
@@ -50,52 +44,18 @@ def _export_config() -> dict:
|
|
50
44
|
|
51
45
|
|
52
46
|
def update_parameters(result: Result, data_path):
|
53
|
-
global
|
47
|
+
global __current_config_id
|
54
48
|
update_config(result.parameters)
|
55
49
|
cfg = export_config()
|
56
|
-
|
50
|
+
__current_config_id = save_config(cfg, data_path)
|
57
51
|
|
58
52
|
|
59
53
|
def current_config(data_path):
|
60
|
-
global
|
61
|
-
if
|
54
|
+
global __current_config_id
|
55
|
+
if __current_config_id is None:
|
62
56
|
cfg = export_config()
|
63
|
-
|
64
|
-
return
|
65
|
-
|
66
|
-
|
67
|
-
def _save_config(cfg, data_path):
|
68
|
-
global __config_id
|
69
|
-
i = 0
|
70
|
-
buf = pickle.dumps(cfg)
|
71
|
-
buf = lzma.compress(buf)
|
72
|
-
h = hashlib.md5(buf)
|
73
|
-
|
74
|
-
while True:
|
75
|
-
salt = f"{i:08d}".encode()
|
76
|
-
h.update(salt)
|
77
|
-
hashstr = h.hexdigest()
|
78
|
-
cfg_id = Path(hashstr[:2]) / hashstr[2:4] / hashstr[4:]
|
79
|
-
path = Path(data_path) / 'config' / cfg_id
|
80
|
-
if not path.exists():
|
81
|
-
path.parent.mkdir(parents=True, exist_ok=True)
|
82
|
-
with open(path, 'wb') as f:
|
83
|
-
f.write(buf)
|
84
|
-
break
|
85
|
-
elif path.read_bytes() == buf:
|
86
|
-
break
|
87
|
-
i += 1
|
88
|
-
__config_id = str(cfg_id)
|
89
|
-
return __config_id
|
90
|
-
|
91
|
-
|
92
|
-
@functools.lru_cache(maxsize=1024)
|
93
|
-
def _load_config(id, data_path):
|
94
|
-
path = Path(data_path) / 'config' / id
|
95
|
-
with open(path, 'rb') as f:
|
96
|
-
buf = f.read()
|
97
|
-
cfg = pickle.loads(lzma.decompress(buf))
|
98
|
-
return cfg
|
57
|
+
__current_config_id = save_config(cfg, data_path)
|
58
|
+
return __current_config_id
|
99
59
|
|
100
60
|
|
101
61
|
query_config = _query_config
|
@@ -138,8 +138,8 @@ def check_analyze(result: Result, history: Result | None = None) -> Result:
|
|
138
138
|
|
139
139
|
def debug_analyze(
|
140
140
|
result_index: int,
|
141
|
-
code_path: str | Path = get_config_value('
|
142
|
-
data_path: str | Path = get_config_value('
|
141
|
+
code_path: str | Path = get_config_value('code', Path),
|
142
|
+
data_path: str | Path = get_config_value('data', Path),
|
143
143
|
) -> None:
|
144
144
|
from .storage import get_result_by_index
|
145
145
|
|
@@ -150,7 +150,7 @@ def debug_analyze(
|
|
150
150
|
wf = load_workflow(workflow, code_path)
|
151
151
|
if wf is None:
|
152
152
|
raise ValueError(f'Invalid workflow: {workflow}')
|
153
|
-
result = wf.analyze(result)
|
153
|
+
result = wf.analyze(result, result.previous)
|
154
154
|
if hasattr(wf, 'plot'):
|
155
155
|
wf.plot(result)
|
156
156
|
return result
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "2.6.2"
|
qulab-2.6.0/qulab/version.py
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
__version__ = "2.6.0"
|
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
|