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.
Files changed (111) hide show
  1. {qulab-2.6.0 → qulab-2.6.2}/PKG-INFO +1 -1
  2. {qulab-2.6.0 → qulab-2.6.2}/QuLab.egg-info/PKG-INFO +1 -1
  3. {qulab-2.6.0 → qulab-2.6.2}/qulab/__init__.py +1 -0
  4. {qulab-2.6.0 → qulab-2.6.2}/qulab/executor/cli.py +59 -33
  5. {qulab-2.6.0 → qulab-2.6.2}/qulab/executor/load.py +8 -8
  6. {qulab-2.6.0 → qulab-2.6.2}/qulab/executor/schedule.py +8 -4
  7. {qulab-2.6.0 → qulab-2.6.2}/qulab/executor/storage.py +34 -2
  8. {qulab-2.6.0 → qulab-2.6.2}/qulab/executor/transform.py +8 -48
  9. {qulab-2.6.0 → qulab-2.6.2}/qulab/executor/utils.py +3 -3
  10. qulab-2.6.2/qulab/version.py +1 -0
  11. qulab-2.6.0/qulab/version.py +0 -1
  12. {qulab-2.6.0 → qulab-2.6.2}/LICENSE +0 -0
  13. {qulab-2.6.0 → qulab-2.6.2}/MANIFEST.in +0 -0
  14. {qulab-2.6.0 → qulab-2.6.2}/QuLab.egg-info/SOURCES.txt +0 -0
  15. {qulab-2.6.0 → qulab-2.6.2}/QuLab.egg-info/dependency_links.txt +0 -0
  16. {qulab-2.6.0 → qulab-2.6.2}/QuLab.egg-info/entry_points.txt +0 -0
  17. {qulab-2.6.0 → qulab-2.6.2}/QuLab.egg-info/requires.txt +0 -0
  18. {qulab-2.6.0 → qulab-2.6.2}/QuLab.egg-info/top_level.txt +0 -0
  19. {qulab-2.6.0 → qulab-2.6.2}/README.md +0 -0
  20. {qulab-2.6.0 → qulab-2.6.2}/pyproject.toml +0 -0
  21. {qulab-2.6.0 → qulab-2.6.2}/qulab/__main__.py +0 -0
  22. {qulab-2.6.0 → qulab-2.6.2}/qulab/cli/__init__.py +0 -0
  23. {qulab-2.6.0 → qulab-2.6.2}/qulab/cli/commands.py +0 -0
  24. {qulab-2.6.0 → qulab-2.6.2}/qulab/cli/config.py +0 -0
  25. {qulab-2.6.0 → qulab-2.6.2}/qulab/dicttree.py +0 -0
  26. {qulab-2.6.0 → qulab-2.6.2}/qulab/executor/__init__.py +0 -0
  27. {qulab-2.6.0 → qulab-2.6.2}/qulab/monitor/__init__.py +0 -0
  28. {qulab-2.6.0 → qulab-2.6.2}/qulab/monitor/__main__.py +0 -0
  29. {qulab-2.6.0 → qulab-2.6.2}/qulab/monitor/config.py +0 -0
  30. {qulab-2.6.0 → qulab-2.6.2}/qulab/monitor/dataset.py +0 -0
  31. {qulab-2.6.0 → qulab-2.6.2}/qulab/monitor/event_queue.py +0 -0
  32. {qulab-2.6.0 → qulab-2.6.2}/qulab/monitor/mainwindow.py +0 -0
  33. {qulab-2.6.0 → qulab-2.6.2}/qulab/monitor/monitor.py +0 -0
  34. {qulab-2.6.0 → qulab-2.6.2}/qulab/monitor/ploter.py +0 -0
  35. {qulab-2.6.0 → qulab-2.6.2}/qulab/monitor/qt_compat.py +0 -0
  36. {qulab-2.6.0 → qulab-2.6.2}/qulab/monitor/toolbar.py +0 -0
  37. {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/__init__.py +0 -0
  38. {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/curd.py +0 -0
  39. {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/expression.py +0 -0
  40. {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/models.py +0 -0
  41. {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/optimize.py +0 -0
  42. {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/query.py +0 -0
  43. {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/record.py +0 -0
  44. {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/scan.py +0 -0
  45. {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/server.py +0 -0
  46. {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/space.py +0 -0
  47. {qulab-2.6.0 → qulab-2.6.2}/qulab/scan/utils.py +0 -0
  48. {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/__init__.py +0 -0
  49. {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/__main__.py +0 -0
  50. {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/backend/__init__.py +0 -0
  51. {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/backend/redis.py +0 -0
  52. {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/base_dataset.py +0 -0
  53. {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/chunk.py +0 -0
  54. {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/dataset.py +0 -0
  55. {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/file.py +0 -0
  56. {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/models/__init__.py +0 -0
  57. {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/models/base.py +0 -0
  58. {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/models/config.py +0 -0
  59. {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/models/file.py +0 -0
  60. {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/models/ipy.py +0 -0
  61. {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/models/models.py +0 -0
  62. {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/models/record.py +0 -0
  63. {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/models/report.py +0 -0
  64. {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/models/tag.py +0 -0
  65. {qulab-2.6.0 → qulab-2.6.2}/qulab/storage/storage.py +0 -0
  66. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/__init__.py +0 -0
  67. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/chat.py +0 -0
  68. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/device/__init__.py +0 -0
  69. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/device/basedevice.py +0 -0
  70. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/device/loader.py +0 -0
  71. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/device/utils.py +0 -0
  72. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/drivers/FakeInstrument.py +0 -0
  73. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/drivers/__init__.py +0 -0
  74. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/ipy_events.py +0 -0
  75. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/net/__init__.py +0 -0
  76. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/net/bencoder.py +0 -0
  77. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/net/cli.py +0 -0
  78. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/net/dhcp.py +0 -0
  79. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/net/dhcpd.py +0 -0
  80. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/net/kad.py +0 -0
  81. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/net/kcp.py +0 -0
  82. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/net/nginx.py +0 -0
  83. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/progress.py +0 -0
  84. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/__init__.py +0 -0
  85. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/client.py +0 -0
  86. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/exceptions.py +0 -0
  87. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/msgpack.py +0 -0
  88. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/msgpack.pyi +0 -0
  89. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/router.py +0 -0
  90. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/rpc.py +0 -0
  91. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/serialize.py +0 -0
  92. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/server.py +0 -0
  93. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/socket.py +0 -0
  94. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/utils.py +0 -0
  95. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/worker.py +0 -0
  96. {qulab-2.6.0 → qulab-2.6.2}/qulab/sys/rpc/zmq_socket.py +0 -0
  97. {qulab-2.6.0 → qulab-2.6.2}/qulab/typing.py +0 -0
  98. {qulab-2.6.0 → qulab-2.6.2}/qulab/visualization/__init__.py +0 -0
  99. {qulab-2.6.0 → qulab-2.6.2}/qulab/visualization/__main__.py +0 -0
  100. {qulab-2.6.0 → qulab-2.6.2}/qulab/visualization/_autoplot.py +0 -0
  101. {qulab-2.6.0 → qulab-2.6.2}/qulab/visualization/plot_circ.py +0 -0
  102. {qulab-2.6.0 → qulab-2.6.2}/qulab/visualization/plot_layout.py +0 -0
  103. {qulab-2.6.0 → qulab-2.6.2}/qulab/visualization/plot_seq.py +0 -0
  104. {qulab-2.6.0 → qulab-2.6.2}/qulab/visualization/qdat.py +0 -0
  105. {qulab-2.6.0 → qulab-2.6.2}/qulab/visualization/rot3d.py +0 -0
  106. {qulab-2.6.0 → qulab-2.6.2}/qulab/visualization/widgets.py +0 -0
  107. {qulab-2.6.0 → qulab-2.6.2}/setup.cfg +0 -0
  108. {qulab-2.6.0 → qulab-2.6.2}/setup.py +0 -0
  109. {qulab-2.6.0 → qulab-2.6.2}/src/qulab.h +0 -0
  110. {qulab-2.6.0 → qulab-2.6.2}/tests/test_kad.py +0 -0
  111. {qulab-2.6.0 → qulab-2.6.2}/tests/test_scan.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: QuLab
3
- Version: 2.6.0
3
+ Version: 2.6.2
4
4
  Summary: contral instruments and manage data
5
5
  Author-email: feihoo87 <feihoo87@gmail.com>
6
6
  Maintainer-email: feihoo87 <feihoo87@gmail.com>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: QuLab
3
- Version: 2.6.0
3
+ Version: 2.6.2
4
4
  Summary: contral instruments and manage data
5
5
  Author-email: feihoo87 <feihoo87@gmail.com>
6
6
  Maintainer-email: feihoo87 <feihoo87@gmail.com>
@@ -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}{" --plot" if plot else ""}{" --no-dependents" if no_dependents else ""}{" --update " if update else ""}'
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
- if no_dependents:
163
- if hasattr(wf, 'entries'):
164
- for entry in get_entries(wf, code):
165
- run_workflow(entry, code, data, plot=plot, update=update)
166
- else:
167
- run_workflow(wf, code, data, plot=plot, update=update)
168
- else:
169
- if hasattr(wf, 'entries'):
170
- for entry in get_entries(wf, code):
171
- maintain_workflow(entry,
172
- code,
173
- data,
174
- run=True,
175
- plot=plot,
176
- update=update)
177
- else:
178
- maintain_workflow(wf,
179
- code,
180
- data,
181
- run=True,
182
- plot=plot,
183
- update=update)
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}{" --plot" if plot else ""}'
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
- if hasattr(wf, 'entries'):
213
- for entry in get_entries(wf, code):
214
- maintain_workflow(entry, code, data, run=False, plot=plot)
215
- else:
216
- maintain_workflow(wf, code, data, run=False, plot=plot)
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 transform._load_config(self.config_path, self.base_path)
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 functools
2
- import hashlib
3
- import lzma
4
- import pickle
5
- from pathlib import Path
1
+ from .storage import Result, save_config
6
2
 
7
- from .storage import Result
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 __config_id
47
+ global __current_config_id
54
48
  update_config(result.parameters)
55
49
  cfg = export_config()
56
- __config_id = _save_config(cfg, data_path)
50
+ __current_config_id = save_config(cfg, data_path)
57
51
 
58
52
 
59
53
  def current_config(data_path):
60
- global __config_id
61
- if __config_id is None:
54
+ global __current_config_id
55
+ if __current_config_id is None:
62
56
  cfg = export_config()
63
- __config_id = _save_config(cfg, data_path)
64
- return __config_id
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('code_path', Path),
142
- data_path: str | Path = get_config_value('data_path', Path),
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"
@@ -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