QuLab 2.7.7__cp310-cp310-win_amd64.whl → 2.7.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.7.7.dist-info → QuLab-2.7.10.dist-info}/METADATA +1 -1
- {QuLab-2.7.7.dist-info → QuLab-2.7.10.dist-info}/RECORD +11 -11
- qulab/executor/schedule.py +107 -81
- qulab/executor/storage.py +52 -37
- qulab/executor/transform.py +4 -4
- qulab/fun.cp310-win_amd64.pyd +0 -0
- qulab/version.py +1 -1
- {QuLab-2.7.7.dist-info → QuLab-2.7.10.dist-info}/LICENSE +0 -0
- {QuLab-2.7.7.dist-info → QuLab-2.7.10.dist-info}/WHEEL +0 -0
- {QuLab-2.7.7.dist-info → QuLab-2.7.10.dist-info}/entry_points.txt +0 -0
- {QuLab-2.7.7.dist-info → QuLab-2.7.10.dist-info}/top_level.txt +0 -0
@@ -1,19 +1,19 @@
|
|
1
1
|
qulab/__init__.py,sha256=RZme5maBSMZpP6ckXymqZpo2sRYttwEpTYCIzIvys1c,292
|
2
2
|
qulab/__main__.py,sha256=FL4YsGZL1jEtmcPc5WbleArzhOHLMsWl7OH3O-1d1ss,72
|
3
3
|
qulab/dicttree.py,sha256=ZoSJVWK4VMqfzj42gPb_n5RqLlM6K1Me0WmLIfLEYf8,14195
|
4
|
-
qulab/fun.cp310-win_amd64.pyd,sha256=
|
4
|
+
qulab/fun.cp310-win_amd64.pyd,sha256=y0aR1tHQkJeC9hmGmZpfrLsZQ2V_xhoGnFZ_V9MOSWU,31232
|
5
5
|
qulab/typing.py,sha256=PRtwbCHWY2ROKK8GHq4Bo8llXrIGo6xC73DrQf7S9os,71
|
6
6
|
qulab/utils.py,sha256=UyZNPIyvis5t2MJBkXXLO5EmYP3mQZbt87zmYAHgoyk,1291
|
7
|
-
qulab/version.py,sha256=
|
7
|
+
qulab/version.py,sha256=jdPSCkDOwzHQzdidl89buWuyX5dorFZluLWAvXtMdIU,22
|
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=tNmH4ggdgrFqcQa2WZKLpidiYTg95_UnT0paDJ4fi4c,3204
|
11
11
|
qulab/executor/__init__.py,sha256=LosPzOMaljSZY1thy_Fxtbrgq7uubJszMABEB7oM7tU,101
|
12
12
|
qulab/executor/cli.py,sha256=gGka2M6xccfM8facsIJ2qZ1y2Yx8C4BRhc1JG6nK9mo,8932
|
13
13
|
qulab/executor/load.py,sha256=4FY_SwumLDUewC265v4j_ZGGpfYOgH4c8PtglYcWpBw,18077
|
14
|
-
qulab/executor/schedule.py,sha256=
|
15
|
-
qulab/executor/storage.py,sha256=
|
16
|
-
qulab/executor/transform.py,sha256=
|
14
|
+
qulab/executor/schedule.py,sha256=S8zRdkM2_I9-EqMUCEGI9boe3sfc68Gn5NRK057ShAw,17997
|
15
|
+
qulab/executor/storage.py,sha256=gI6g28BmKKEZ_Pl-hFwvpiOj3mF8Su-yjj3hfMXs1VY,11630
|
16
|
+
qulab/executor/transform.py,sha256=4DyGXv1Iw36cCPqbqXlsn0Lw6gFjQpp_6Hcta50YQxU,2181
|
17
17
|
qulab/executor/utils.py,sha256=cF6-2jlvlHyTjNHdxXKG04Fjfm3_3wfDQAF1G8DQphk,5686
|
18
18
|
qulab/monitor/__init__.py,sha256=xEVDkJF8issrsDeLqQmDsvtRmrf-UiViFcGTWuzdlFU,43
|
19
19
|
qulab/monitor/__main__.py,sha256=k2H1H5Zf9LLXTDLISJkbikLH-z0f1e5i5i6wXXYPOrE,105
|
@@ -94,9 +94,9 @@ qulab/visualization/plot_seq.py,sha256=Uo1-dB1YE9IN_A9tuaOs9ZG3S5dKDQ_l98iD2Wbxp
|
|
94
94
|
qulab/visualization/qdat.py,sha256=HubXFu4nfcA7iUzghJGle1C86G6221hicLR0b-GqhKQ,5887
|
95
95
|
qulab/visualization/rot3d.py,sha256=jGHJcqj1lEWBUV-W4GUGONGacqjrYvuFoFCwPse5h1Y,757
|
96
96
|
qulab/visualization/widgets.py,sha256=HcYwdhDtLreJiYaZuN3LfofjJmZcLwjMfP5aasebgDo,3266
|
97
|
-
QuLab-2.7.
|
98
|
-
QuLab-2.7.
|
99
|
-
QuLab-2.7.
|
100
|
-
QuLab-2.7.
|
101
|
-
QuLab-2.7.
|
102
|
-
QuLab-2.7.
|
97
|
+
QuLab-2.7.10.dist-info/LICENSE,sha256=b4NRQ-GFVpJMT7RuExW3NwhfbrYsX7AcdB7Gudok-fs,1086
|
98
|
+
QuLab-2.7.10.dist-info/METADATA,sha256=AfZd0GQ9mjSrXkCkGbvWEHs7uJ_jt7QKh4T6wZtZ5ws,3804
|
99
|
+
QuLab-2.7.10.dist-info/WHEEL,sha256=rzGfZgUcGeKSgIHGYMuqg4xE4VPHxnaldXH6BG0zjVk,101
|
100
|
+
QuLab-2.7.10.dist-info/entry_points.txt,sha256=b0v1GXOwmxY-nCCsPN_rHZZvY9CtTbWqrGj8u1m8yHo,45
|
101
|
+
QuLab-2.7.10.dist-info/top_level.txt,sha256=3T886LbAsbvjonu_TDdmgxKYUn939BVTRPxPl9r4cEg,6
|
102
|
+
QuLab-2.7.10.dist-info/RECORD,,
|
qulab/executor/schedule.py
CHANGED
@@ -7,8 +7,8 @@ from pathlib import Path
|
|
7
7
|
from loguru import logger
|
8
8
|
|
9
9
|
from .load import WorkflowType, get_dependents
|
10
|
-
from .storage import (Report, find_report, get_heads, renew_report,
|
11
|
-
revoke_report, save_report)
|
10
|
+
from .storage import (Report, find_report, get_head, get_heads, renew_report,
|
11
|
+
revoke_report, save_item, save_report)
|
12
12
|
from .transform import current_config, obey_the_oracle, update_parameters
|
13
13
|
|
14
14
|
__session_id = None
|
@@ -69,6 +69,16 @@ def veryfy_analyzed_report(report: Report, script: str, method: str):
|
|
69
69
|
)
|
70
70
|
|
71
71
|
|
72
|
+
def get_source(workflow: WorkflowType, code_path: str | Path) -> str:
|
73
|
+
if isinstance(code_path, str):
|
74
|
+
code_path = Path(code_path)
|
75
|
+
try:
|
76
|
+
with open(code_path / workflow.__workflow_id__, 'r') as f:
|
77
|
+
return f.read()
|
78
|
+
except:
|
79
|
+
return ''
|
80
|
+
|
81
|
+
|
72
82
|
def check_state(workflow: WorkflowType, code_path: str | Path,
|
73
83
|
state_path: str | Path) -> bool:
|
74
84
|
"""
|
@@ -91,6 +101,11 @@ def check_state(workflow: WorkflowType, code_path: str | Path,
|
|
91
101
|
f'check_state: "{workflow.__workflow_id__}" has custom check_state method'
|
92
102
|
)
|
93
103
|
return workflow.check_state(report)
|
104
|
+
if datetime.fromtimestamp(workflow.__mtime__) > report.checked_time:
|
105
|
+
logger.debug(
|
106
|
+
f'check_state failed: "{workflow.__workflow_id__}" has been modified after last calibration'
|
107
|
+
)
|
108
|
+
return False
|
94
109
|
if workflow.__timeout__ is not None and datetime.now(
|
95
110
|
) > report.checked_time + timedelta(seconds=workflow.__timeout__):
|
96
111
|
logger.debug(
|
@@ -120,42 +135,6 @@ def check_state(workflow: WorkflowType, code_path: str | Path,
|
|
120
135
|
return True
|
121
136
|
|
122
137
|
|
123
|
-
def call_analyzer(node: WorkflowType,
|
124
|
-
report: Report,
|
125
|
-
history: Report | None,
|
126
|
-
check=False,
|
127
|
-
plot=False) -> Report:
|
128
|
-
if check:
|
129
|
-
report = node.check_analyze(report, history=history)
|
130
|
-
veryfy_analyzed_report(report, node.__workflow_id__, "check_analyze")
|
131
|
-
report.fully_calibrated = False
|
132
|
-
else:
|
133
|
-
report = node.analyze(report, history=history)
|
134
|
-
veryfy_analyzed_report(report, node.__workflow_id__, "analyze")
|
135
|
-
if hasattr(node, 'oracle') and callable(node.oracle):
|
136
|
-
logger.debug(
|
137
|
-
f'"{node.__workflow_id__}" has oracle method, calling ...')
|
138
|
-
try:
|
139
|
-
report = node.oracle(report,
|
140
|
-
history=history,
|
141
|
-
system_state=get_heads(report.base_path))
|
142
|
-
except Exception as e:
|
143
|
-
logger.exception(e)
|
144
|
-
report.oracle = {}
|
145
|
-
if not isinstance(report, Report):
|
146
|
-
raise TypeError(
|
147
|
-
f'"{node.__workflow_id__}" : function "oracle" must return a Report object'
|
148
|
-
)
|
149
|
-
if not is_pickleable(report.oracle):
|
150
|
-
raise TypeError(
|
151
|
-
f'"{node.__workflow_id__}" : function "oracle" return not pickleable data'
|
152
|
-
)
|
153
|
-
report.fully_calibrated = True
|
154
|
-
if plot:
|
155
|
-
call_plot(node, report)
|
156
|
-
return report
|
157
|
-
|
158
|
-
|
159
138
|
@logger.catch()
|
160
139
|
def call_plot(node: WorkflowType, report: Report, check=False):
|
161
140
|
if hasattr(node, 'plot') and callable(node.plot):
|
@@ -177,12 +156,13 @@ def call_check(workflow: WorkflowType, session_id: str, state_path: Path):
|
|
177
156
|
data=data,
|
178
157
|
config_path=current_config(state_path),
|
179
158
|
base_path=state_path,
|
180
|
-
heads=get_heads(state_path)
|
159
|
+
heads=get_heads(state_path),
|
160
|
+
previous_path=get_head(workflow.__workflow_id__,
|
161
|
+
state_path),
|
162
|
+
script_path=save_item(get_source(workflow, state_path),
|
163
|
+
state_path))
|
181
164
|
|
182
|
-
save_report(workflow.__workflow_id__,
|
183
|
-
report,
|
184
|
-
state_path,
|
185
|
-
refresh_heads=False)
|
165
|
+
save_report(workflow.__workflow_id__, report, state_path)
|
186
166
|
|
187
167
|
set_cache(session_id, (workflow, 'check'), report)
|
188
168
|
return report
|
@@ -203,7 +183,11 @@ def call_calibrate(workflow: WorkflowType, session_id: str, state_path: Path):
|
|
203
183
|
data=data,
|
204
184
|
config_path=current_config(state_path),
|
205
185
|
base_path=state_path,
|
206
|
-
heads=get_heads(state_path)
|
186
|
+
heads=get_heads(state_path),
|
187
|
+
previous_path=get_head(workflow.__workflow_id__,
|
188
|
+
state_path),
|
189
|
+
script_path=save_item(get_source(workflow, state_path),
|
190
|
+
state_path))
|
207
191
|
|
208
192
|
save_report(workflow.__workflow_id__, report, state_path)
|
209
193
|
|
@@ -211,8 +195,66 @@ def call_calibrate(workflow: WorkflowType, session_id: str, state_path: Path):
|
|
211
195
|
return report
|
212
196
|
|
213
197
|
|
214
|
-
def
|
215
|
-
|
198
|
+
def call_check_analyzer(node: WorkflowType,
|
199
|
+
report: Report,
|
200
|
+
history: Report | None,
|
201
|
+
state_path: Path,
|
202
|
+
plot=False) -> Report:
|
203
|
+
report = node.check_analyze(report, history=history)
|
204
|
+
veryfy_analyzed_report(report, node.__workflow_id__, "check_analyze")
|
205
|
+
report.fully_calibrated = False
|
206
|
+
if report.in_spec:
|
207
|
+
logger.debug(
|
208
|
+
f'"{node.__workflow_id__}": checked in spec, renewing report')
|
209
|
+
if report.previous is not None:
|
210
|
+
renew_report(node.__workflow_id__, report.previous, state_path)
|
211
|
+
else:
|
212
|
+
renew_report(node.__workflow_id__, report, state_path)
|
213
|
+
else:
|
214
|
+
logger.debug(
|
215
|
+
f'"{node.__workflow_id__}": checked out of spec, revoking report')
|
216
|
+
if report.previous is not None:
|
217
|
+
revoke_report(node.__workflow_id__, report.previous, state_path)
|
218
|
+
else:
|
219
|
+
revoke_report(node.__workflow_id__, report, state_path)
|
220
|
+
return report
|
221
|
+
|
222
|
+
|
223
|
+
def call_analyzer(node: WorkflowType,
|
224
|
+
report: Report,
|
225
|
+
history: Report | None,
|
226
|
+
state_path: Path,
|
227
|
+
plot=False) -> Report:
|
228
|
+
|
229
|
+
report = node.analyze(report, history=history)
|
230
|
+
veryfy_analyzed_report(report, node.__workflow_id__, "analyze")
|
231
|
+
if hasattr(node, 'oracle') and callable(node.oracle):
|
232
|
+
logger.debug(
|
233
|
+
f'"{node.__workflow_id__}" has oracle method, calling ...')
|
234
|
+
try:
|
235
|
+
report = node.oracle(report,
|
236
|
+
history=history,
|
237
|
+
system_state=get_heads(report.base_path))
|
238
|
+
except Exception as e:
|
239
|
+
logger.exception(e)
|
240
|
+
report.oracle = {}
|
241
|
+
if not isinstance(report, Report):
|
242
|
+
raise TypeError(
|
243
|
+
f'"{node.__workflow_id__}" : function "oracle" must return a Report object'
|
244
|
+
)
|
245
|
+
if not is_pickleable(report.oracle):
|
246
|
+
raise TypeError(
|
247
|
+
f'"{node.__workflow_id__}" : function "oracle" return not pickleable data'
|
248
|
+
)
|
249
|
+
report.fully_calibrated = True
|
250
|
+
save_report(node.__workflow_id__, report, state_path, overwrite=True)
|
251
|
+
if plot:
|
252
|
+
call_plot(node, report)
|
253
|
+
return report
|
254
|
+
|
255
|
+
|
256
|
+
def check_data(workflow: WorkflowType, state_path: str | Path, plot: bool,
|
257
|
+
session_id: str) -> Report:
|
216
258
|
"""
|
217
259
|
check data answers two questions:
|
218
260
|
Is the parameter associated with this cal in spec,
|
@@ -225,7 +267,11 @@ def check_data(workflow: WorkflowType, code_path: str | Path,
|
|
225
267
|
report = Report(workflow=workflow.__workflow_id__,
|
226
268
|
config_path=current_config(state_path),
|
227
269
|
base_path=state_path,
|
228
|
-
heads=get_heads(state_path)
|
270
|
+
heads=get_heads(state_path),
|
271
|
+
previous_path=get_head(workflow.__workflow_id__,
|
272
|
+
state_path),
|
273
|
+
script_path=save_item(get_source(workflow, state_path),
|
274
|
+
state_path))
|
229
275
|
report.in_spec = False
|
230
276
|
report.bad_data = False
|
231
277
|
return report
|
@@ -250,21 +296,11 @@ def check_data(workflow: WorkflowType, code_path: str | Path,
|
|
250
296
|
report = call_check(workflow, session_id, state_path)
|
251
297
|
|
252
298
|
logger.debug(f'Checked "{workflow.__workflow_id__}" !')
|
253
|
-
report =
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
if report.in_spec:
|
259
|
-
logger.debug(
|
260
|
-
f'"{workflow.__workflow_id__}": checked in spec, renewing report'
|
261
|
-
)
|
262
|
-
renew_report(workflow.__workflow_id__, report, state_path)
|
263
|
-
else:
|
264
|
-
logger.debug(
|
265
|
-
f'"{workflow.__workflow_id__}": checked out of spec, revoking report'
|
266
|
-
)
|
267
|
-
revoke_report(workflow.__workflow_id__, report, state_path)
|
299
|
+
report = call_check_analyzer(workflow,
|
300
|
+
report,
|
301
|
+
history,
|
302
|
+
state_path,
|
303
|
+
plot=plot)
|
268
304
|
else:
|
269
305
|
logger.debug(
|
270
306
|
f'Checking "{workflow.__workflow_id__}" with "calibrate" method ...'
|
@@ -276,17 +312,13 @@ def check_data(workflow: WorkflowType, code_path: str | Path,
|
|
276
312
|
report = call_analyzer(workflow,
|
277
313
|
report,
|
278
314
|
history,
|
279
|
-
|
315
|
+
state_path,
|
280
316
|
plot=plot)
|
281
|
-
save_report(workflow.__workflow_id__,
|
282
|
-
report,
|
283
|
-
state_path,
|
284
|
-
overwrite=True)
|
285
317
|
return report
|
286
318
|
|
287
319
|
|
288
|
-
def calibrate(workflow: WorkflowType,
|
289
|
-
|
320
|
+
def calibrate(workflow: WorkflowType, state_path: str | Path, plot: bool,
|
321
|
+
session_id: str) -> Report:
|
290
322
|
history = find_report(workflow.__workflow_id__, state_path)
|
291
323
|
|
292
324
|
logger.debug(f'Calibrating "{workflow.__workflow_id__}" ...')
|
@@ -295,9 +327,7 @@ def calibrate(workflow: WorkflowType, code_path: str | Path,
|
|
295
327
|
|
296
328
|
logger.debug(f'Calibrated "{workflow.__workflow_id__}" !')
|
297
329
|
|
298
|
-
report = call_analyzer(workflow, report, history,
|
299
|
-
|
300
|
-
save_report(workflow.__workflow_id__, report, state_path, overwrite=True)
|
330
|
+
report = call_analyzer(workflow, report, history, state_path, plot=plot)
|
301
331
|
return report
|
302
332
|
|
303
333
|
|
@@ -308,7 +338,7 @@ def diagnose(workflow: WorkflowType, code_path: str | Path,
|
|
308
338
|
'''
|
309
339
|
logger.debug(f'diagnose "{workflow.__workflow_id__}"')
|
310
340
|
# check_data
|
311
|
-
report = check_data(workflow,
|
341
|
+
report = check_data(workflow, state_path, plot, session_id)
|
312
342
|
# in spec case
|
313
343
|
if report.in_spec:
|
314
344
|
logger.debug(
|
@@ -350,7 +380,7 @@ def diagnose(workflow: WorkflowType, code_path: str | Path,
|
|
350
380
|
else:
|
351
381
|
logger.error(f'Never reach: recalibrate "{workflow.__workflow_id__}"')
|
352
382
|
|
353
|
-
report = calibrate(workflow,
|
383
|
+
report = calibrate(workflow, state_path, plot, session_id)
|
354
384
|
if report.bad_data or not report.in_spec:
|
355
385
|
obey_the_oracle(report, state_path)
|
356
386
|
raise CalibrationFailedError(
|
@@ -393,7 +423,7 @@ def maintain(workflow: WorkflowType,
|
|
393
423
|
f'"{workflow.__workflow_id__}": In spec, no need to maintain')
|
394
424
|
return
|
395
425
|
# check_data
|
396
|
-
report = check_data(workflow,
|
426
|
+
report = check_data(workflow, state_path, plot, session_id)
|
397
427
|
if report.in_spec:
|
398
428
|
if not run:
|
399
429
|
logger.debug(
|
@@ -412,7 +442,7 @@ def maintain(workflow: WorkflowType,
|
|
412
442
|
f'"{workflow.__workflow_id__}": All dependents diagnosed')
|
413
443
|
# calibrate
|
414
444
|
logger.debug(f'recalibrate "{workflow.__workflow_id__}"')
|
415
|
-
report = calibrate(workflow,
|
445
|
+
report = calibrate(workflow, state_path, plot, session_id)
|
416
446
|
if report.bad_data or not report.in_spec:
|
417
447
|
if not freeze:
|
418
448
|
obey_the_oracle(report, state_path)
|
@@ -432,11 +462,7 @@ def run(workflow: WorkflowType,
|
|
432
462
|
freeze: bool = False):
|
433
463
|
session_id = uuid.uuid4().hex
|
434
464
|
logger.debug(f'run "{workflow.__workflow_id__}" without dependences.')
|
435
|
-
report = calibrate(workflow,
|
436
|
-
code_path,
|
437
|
-
state_path,
|
438
|
-
plot,
|
439
|
-
session_id=session_id)
|
465
|
+
report = calibrate(workflow, state_path, plot, session_id=session_id)
|
440
466
|
if report.bad_data or not report.in_spec:
|
441
467
|
if not freeze:
|
442
468
|
obey_the_oracle(report, state_path)
|
qulab/executor/storage.py
CHANGED
@@ -34,6 +34,7 @@ class Report():
|
|
34
34
|
base_path: Path | None = field(default=None, repr=False)
|
35
35
|
path: Path | None = field(default=None, repr=False)
|
36
36
|
config_path: Path | None = field(default=None, repr=False)
|
37
|
+
script_path: Path | None = field(default=None, repr=False)
|
37
38
|
|
38
39
|
@property
|
39
40
|
def previous(self):
|
@@ -54,13 +55,6 @@ class Report():
|
|
54
55
|
state = 'Outdated'
|
55
56
|
return state
|
56
57
|
|
57
|
-
@property
|
58
|
-
def config(self):
|
59
|
-
if self.config_path is not None and self.base_path is not None:
|
60
|
-
return load_config(self.config_path, self.base_path)
|
61
|
-
else:
|
62
|
-
return None
|
63
|
-
|
64
58
|
@state.setter
|
65
59
|
def state(self, state: Literal['OK', 'Bad', 'Outdated', 'In spec',
|
66
60
|
'Out of spec', 'Bad data']):
|
@@ -80,6 +74,20 @@ class Report():
|
|
80
74
|
self.bad_data = False
|
81
75
|
self.in_spec = False
|
82
76
|
|
77
|
+
@property
|
78
|
+
def config(self):
|
79
|
+
if self.config_path is not None and self.base_path is not None:
|
80
|
+
return load_item(self.config_path, self.base_path)
|
81
|
+
else:
|
82
|
+
return None
|
83
|
+
|
84
|
+
@property
|
85
|
+
def script(self):
|
86
|
+
if self.script_path is not None and self.base_path is not None:
|
87
|
+
return load_item(self.script_path, self.base_path)
|
88
|
+
else:
|
89
|
+
return None
|
90
|
+
|
83
91
|
|
84
92
|
def random_path(base: Path) -> Path:
|
85
93
|
while True:
|
@@ -149,27 +157,27 @@ def save_report(workflow: str,
|
|
149
157
|
f'Saving report for "{workflow}", {report.in_spec=}, {report.bad_data=}, {report.fully_calibrated=}'
|
150
158
|
)
|
151
159
|
base_path = Path(base_path)
|
152
|
-
|
160
|
+
try:
|
153
161
|
buf = lzma.compress(pickle.dumps(report))
|
162
|
+
except:
|
163
|
+
raise ValueError(f"Can't pickle report for {workflow}")
|
164
|
+
if overwrite:
|
154
165
|
path = report.path
|
155
166
|
if path is None:
|
156
167
|
raise ValueError("Report path is None, can't overwrite.")
|
157
|
-
with open(base_path / '
|
168
|
+
with open(base_path / 'reports' / path, "rb") as f:
|
158
169
|
index = int.from_bytes(f.read(8), 'big')
|
159
170
|
report.index = index
|
160
171
|
else:
|
161
|
-
|
162
|
-
|
163
|
-
path = random_path(base_path / 'objects')
|
164
|
-
(base_path / 'objects' / path).parent.mkdir(parents=True,
|
172
|
+
path = random_path(base_path / 'reports')
|
173
|
+
(base_path / 'reports' / path).parent.mkdir(parents=True,
|
165
174
|
exist_ok=True)
|
166
175
|
report.path = path
|
167
176
|
report.index = create_index("report",
|
168
177
|
base_path,
|
169
178
|
context=str(path),
|
170
179
|
width=35)
|
171
|
-
|
172
|
-
with open(base_path / 'objects' / path, "wb") as f:
|
180
|
+
with open(base_path / 'reports' / path, "wb") as f:
|
173
181
|
f.write(report.index.to_bytes(8, 'big'))
|
174
182
|
f.write(buf)
|
175
183
|
if refresh_heads:
|
@@ -179,9 +187,9 @@ def save_report(workflow: str,
|
|
179
187
|
|
180
188
|
def load_report(path: str | Path, base_path: str | Path) -> Report | None:
|
181
189
|
base_path = Path(base_path)
|
182
|
-
path = base_path / '
|
190
|
+
path = base_path / 'reports' / path
|
183
191
|
|
184
|
-
with open(base_path / '
|
192
|
+
with open(base_path / 'reports' / path, "rb") as f:
|
185
193
|
index = int.from_bytes(f.read(8), 'big')
|
186
194
|
report = pickle.loads(lzma.decompress(f.read()))
|
187
195
|
report.base_path = base_path
|
@@ -202,22 +210,30 @@ def find_report(
|
|
202
210
|
return load_report(path, base_path)
|
203
211
|
|
204
212
|
|
205
|
-
def renew_report(workflow: str, report, base_path: str | Path):
|
213
|
+
def renew_report(workflow: str, report: Report | None, base_path: str | Path):
|
206
214
|
logger.debug(f'Renewing report for "{workflow}"')
|
207
|
-
report = find_report(workflow, base_path)
|
208
215
|
if report is not None:
|
209
216
|
report.checked_time = datetime.now()
|
210
|
-
return save_report(workflow,
|
217
|
+
return save_report(workflow,
|
218
|
+
report,
|
219
|
+
base_path,
|
220
|
+
overwrite=True,
|
221
|
+
refresh_heads=True)
|
222
|
+
else:
|
223
|
+
raise ValueError(f"Can't renew report for {workflow}")
|
211
224
|
|
212
225
|
|
213
|
-
def revoke_report(workflow: str, report, base_path: str | Path):
|
226
|
+
def revoke_report(workflow: str, report: Report | None, base_path: str | Path):
|
214
227
|
logger.debug(f'Revoking report for "{workflow}"')
|
215
228
|
base_path = Path(base_path)
|
216
|
-
|
217
|
-
if path is not None:
|
218
|
-
report = load_report(path, base_path)
|
229
|
+
if report is not None:
|
219
230
|
report.in_spec = False
|
220
|
-
|
231
|
+
report.previous_path = report.path
|
232
|
+
return save_report(workflow,
|
233
|
+
report,
|
234
|
+
base_path,
|
235
|
+
overwrite=False,
|
236
|
+
refresh_heads=True)
|
221
237
|
|
222
238
|
|
223
239
|
def set_head(workflow: str, path: Path, base_path: str | Path):
|
@@ -307,18 +323,17 @@ def get_report_by_index(
|
|
307
323
|
return None
|
308
324
|
|
309
325
|
|
310
|
-
def
|
311
|
-
|
312
|
-
buf = pickle.dumps(
|
326
|
+
def save_item(item, data_path):
|
327
|
+
salt = 0
|
328
|
+
buf = pickle.dumps(item)
|
313
329
|
buf = lzma.compress(buf)
|
314
330
|
h = hashlib.md5(buf)
|
315
331
|
|
316
332
|
while True:
|
317
|
-
|
318
|
-
h.update(salt)
|
333
|
+
h.update(f"{salt}".encode())
|
319
334
|
hashstr = h.hexdigest()
|
320
|
-
|
321
|
-
path = Path(data_path) / '
|
335
|
+
item_id = Path(hashstr[:2]) / hashstr[2:4] / hashstr[4:]
|
336
|
+
path = Path(data_path) / 'items' / item_id
|
322
337
|
if not path.exists():
|
323
338
|
path.parent.mkdir(parents=True, exist_ok=True)
|
324
339
|
with open(path, 'wb') as f:
|
@@ -326,13 +341,13 @@ def save_config(cfg, data_path):
|
|
326
341
|
break
|
327
342
|
elif path.read_bytes() == buf:
|
328
343
|
break
|
329
|
-
|
330
|
-
return str(
|
344
|
+
salt += 1
|
345
|
+
return str(item_id)
|
331
346
|
|
332
347
|
|
333
|
-
@lru_cache(maxsize=
|
334
|
-
def
|
335
|
-
path = Path(data_path) / '
|
348
|
+
@lru_cache(maxsize=4096)
|
349
|
+
def load_item(id, data_path):
|
350
|
+
path = Path(data_path) / 'items' / id
|
336
351
|
with open(path, 'rb') as f:
|
337
352
|
buf = f.read()
|
338
353
|
cfg = pickle.loads(lzma.decompress(buf))
|
qulab/executor/transform.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from .storage import Report,
|
1
|
+
from .storage import Report, save_item
|
2
2
|
|
3
3
|
__current_config_id = None
|
4
4
|
|
@@ -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 =
|
50
|
+
__current_config_id = save_item(cfg, 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 =
|
57
|
+
__current_config_id = save_item(cfg, 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 =
|
64
|
+
__current_config_id = save_item(cfg, data_path)
|
65
65
|
return __current_config_id
|
66
66
|
|
67
67
|
|
qulab/fun.cp310-win_amd64.pyd
CHANGED
Binary file
|
qulab/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "2.7.
|
1
|
+
__version__ = "2.7.10"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|