experimaestro 2.0.0b8__py3-none-any.whl → 2.0.0b17__py3-none-any.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.

Potentially problematic release.


This version of experimaestro might be problematic. Click here for more details.

Files changed (152) hide show
  1. experimaestro/__init__.py +12 -5
  2. experimaestro/cli/__init__.py +239 -126
  3. experimaestro/cli/filter.py +48 -23
  4. experimaestro/cli/jobs.py +253 -71
  5. experimaestro/cli/refactor.py +1 -2
  6. experimaestro/commandline.py +7 -4
  7. experimaestro/connectors/__init__.py +9 -1
  8. experimaestro/connectors/local.py +43 -3
  9. experimaestro/core/arguments.py +18 -18
  10. experimaestro/core/identifier.py +11 -11
  11. experimaestro/core/objects/config.py +96 -39
  12. experimaestro/core/objects/config_walk.py +3 -3
  13. experimaestro/core/{subparameters.py → partial.py} +16 -16
  14. experimaestro/core/partial_lock.py +394 -0
  15. experimaestro/core/types.py +12 -15
  16. experimaestro/dynamic.py +290 -0
  17. experimaestro/experiments/__init__.py +6 -2
  18. experimaestro/experiments/cli.py +217 -50
  19. experimaestro/experiments/configuration.py +24 -0
  20. experimaestro/generators.py +5 -5
  21. experimaestro/ipc.py +118 -1
  22. experimaestro/launcherfinder/__init__.py +2 -2
  23. experimaestro/launcherfinder/registry.py +6 -7
  24. experimaestro/launcherfinder/specs.py +2 -9
  25. experimaestro/launchers/slurm/__init__.py +2 -2
  26. experimaestro/launchers/slurm/base.py +62 -0
  27. experimaestro/locking.py +957 -1
  28. experimaestro/notifications.py +89 -201
  29. experimaestro/progress.py +63 -366
  30. experimaestro/rpyc.py +0 -2
  31. experimaestro/run.py +29 -2
  32. experimaestro/scheduler/__init__.py +8 -1
  33. experimaestro/scheduler/base.py +629 -53
  34. experimaestro/scheduler/dependencies.py +20 -16
  35. experimaestro/scheduler/experiment.py +732 -167
  36. experimaestro/scheduler/interfaces.py +316 -101
  37. experimaestro/scheduler/jobs.py +58 -20
  38. experimaestro/scheduler/remote/adaptive_sync.py +265 -0
  39. experimaestro/scheduler/remote/client.py +171 -117
  40. experimaestro/scheduler/remote/protocol.py +8 -193
  41. experimaestro/scheduler/remote/server.py +95 -71
  42. experimaestro/scheduler/services.py +53 -28
  43. experimaestro/scheduler/state_provider.py +663 -2430
  44. experimaestro/scheduler/state_status.py +1247 -0
  45. experimaestro/scheduler/transient.py +31 -0
  46. experimaestro/scheduler/workspace.py +1 -1
  47. experimaestro/scheduler/workspace_state_provider.py +1273 -0
  48. experimaestro/scriptbuilder.py +4 -4
  49. experimaestro/settings.py +36 -0
  50. experimaestro/tests/conftest.py +33 -5
  51. experimaestro/tests/connectors/bin/executable.py +1 -1
  52. experimaestro/tests/fixtures/pre_experiment/experiment_check_env.py +16 -0
  53. experimaestro/tests/fixtures/pre_experiment/experiment_check_mock.py +14 -0
  54. experimaestro/tests/fixtures/pre_experiment/experiment_simple.py +12 -0
  55. experimaestro/tests/fixtures/pre_experiment/pre_setup_env.py +5 -0
  56. experimaestro/tests/fixtures/pre_experiment/pre_setup_error.py +3 -0
  57. experimaestro/tests/fixtures/pre_experiment/pre_setup_mock.py +8 -0
  58. experimaestro/tests/launchers/bin/test.py +1 -0
  59. experimaestro/tests/launchers/test_slurm.py +9 -9
  60. experimaestro/tests/partial_reschedule.py +46 -0
  61. experimaestro/tests/restart.py +3 -3
  62. experimaestro/tests/restart_main.py +1 -0
  63. experimaestro/tests/scripts/notifyandwait.py +1 -0
  64. experimaestro/tests/task_partial.py +38 -0
  65. experimaestro/tests/task_tokens.py +2 -2
  66. experimaestro/tests/tasks/test_dynamic.py +6 -6
  67. experimaestro/tests/test_dependencies.py +3 -3
  68. experimaestro/tests/test_deprecated.py +15 -15
  69. experimaestro/tests/test_dynamic_locking.py +317 -0
  70. experimaestro/tests/test_environment.py +24 -14
  71. experimaestro/tests/test_experiment.py +171 -36
  72. experimaestro/tests/test_identifier.py +25 -25
  73. experimaestro/tests/test_identifier_stability.py +3 -5
  74. experimaestro/tests/test_multitoken.py +2 -4
  75. experimaestro/tests/{test_subparameters.py → test_partial.py} +25 -25
  76. experimaestro/tests/test_partial_paths.py +81 -138
  77. experimaestro/tests/test_pre_experiment.py +219 -0
  78. experimaestro/tests/test_progress.py +2 -8
  79. experimaestro/tests/test_remote_state.py +560 -99
  80. experimaestro/tests/test_stray_jobs.py +261 -0
  81. experimaestro/tests/test_tasks.py +1 -2
  82. experimaestro/tests/test_token_locking.py +52 -67
  83. experimaestro/tests/test_tokens.py +5 -6
  84. experimaestro/tests/test_transient.py +225 -0
  85. experimaestro/tests/test_workspace_state_provider.py +768 -0
  86. experimaestro/tests/token_reschedule.py +1 -3
  87. experimaestro/tests/utils.py +2 -7
  88. experimaestro/tokens.py +227 -372
  89. experimaestro/tools/diff.py +1 -0
  90. experimaestro/tools/documentation.py +4 -5
  91. experimaestro/tools/jobs.py +1 -2
  92. experimaestro/tui/app.py +438 -1966
  93. experimaestro/tui/app.tcss +162 -0
  94. experimaestro/tui/dialogs.py +172 -0
  95. experimaestro/tui/log_viewer.py +253 -3
  96. experimaestro/tui/messages.py +137 -0
  97. experimaestro/tui/utils.py +54 -0
  98. experimaestro/tui/widgets/__init__.py +23 -0
  99. experimaestro/tui/widgets/experiments.py +468 -0
  100. experimaestro/tui/widgets/global_services.py +238 -0
  101. experimaestro/tui/widgets/jobs.py +972 -0
  102. experimaestro/tui/widgets/log.py +156 -0
  103. experimaestro/tui/widgets/orphans.py +363 -0
  104. experimaestro/tui/widgets/runs.py +185 -0
  105. experimaestro/tui/widgets/services.py +314 -0
  106. experimaestro/tui/widgets/stray_jobs.py +528 -0
  107. experimaestro/utils/__init__.py +1 -1
  108. experimaestro/utils/environment.py +105 -22
  109. experimaestro/utils/fswatcher.py +124 -0
  110. experimaestro/utils/jobs.py +1 -2
  111. experimaestro/utils/jupyter.py +1 -2
  112. experimaestro/utils/logging.py +72 -0
  113. experimaestro/version.py +2 -2
  114. experimaestro/webui/__init__.py +9 -0
  115. experimaestro/webui/app.py +117 -0
  116. experimaestro/{server → webui}/data/index.css +66 -11
  117. experimaestro/webui/data/index.css.map +1 -0
  118. experimaestro/{server → webui}/data/index.js +82763 -87217
  119. experimaestro/webui/data/index.js.map +1 -0
  120. experimaestro/webui/routes/__init__.py +5 -0
  121. experimaestro/webui/routes/auth.py +53 -0
  122. experimaestro/webui/routes/proxy.py +117 -0
  123. experimaestro/webui/server.py +200 -0
  124. experimaestro/webui/state_bridge.py +152 -0
  125. experimaestro/webui/websocket.py +413 -0
  126. {experimaestro-2.0.0b8.dist-info → experimaestro-2.0.0b17.dist-info}/METADATA +5 -6
  127. experimaestro-2.0.0b17.dist-info/RECORD +219 -0
  128. experimaestro/cli/progress.py +0 -269
  129. experimaestro/scheduler/state.py +0 -75
  130. experimaestro/scheduler/state_db.py +0 -437
  131. experimaestro/scheduler/state_sync.py +0 -891
  132. experimaestro/server/__init__.py +0 -467
  133. experimaestro/server/data/index.css.map +0 -1
  134. experimaestro/server/data/index.js.map +0 -1
  135. experimaestro/tests/test_cli_jobs.py +0 -615
  136. experimaestro/tests/test_file_progress.py +0 -425
  137. experimaestro/tests/test_file_progress_integration.py +0 -477
  138. experimaestro/tests/test_state_db.py +0 -434
  139. experimaestro-2.0.0b8.dist-info/RECORD +0 -187
  140. /experimaestro/{server → webui}/data/1815e00441357e01619e.ttf +0 -0
  141. /experimaestro/{server → webui}/data/2463b90d9a316e4e5294.woff2 +0 -0
  142. /experimaestro/{server → webui}/data/2582b0e4bcf85eceead0.ttf +0 -0
  143. /experimaestro/{server → webui}/data/89999bdf5d835c012025.woff2 +0 -0
  144. /experimaestro/{server → webui}/data/914997e1bdfc990d0897.ttf +0 -0
  145. /experimaestro/{server → webui}/data/c210719e60948b211a12.woff2 +0 -0
  146. /experimaestro/{server → webui}/data/favicon.ico +0 -0
  147. /experimaestro/{server → webui}/data/index.html +0 -0
  148. /experimaestro/{server → webui}/data/login.html +0 -0
  149. /experimaestro/{server → webui}/data/manifest.json +0 -0
  150. {experimaestro-2.0.0b8.dist-info → experimaestro-2.0.0b17.dist-info}/WHEEL +0 -0
  151. {experimaestro-2.0.0b8.dist-info → experimaestro-2.0.0b17.dist-info}/entry_points.txt +0 -0
  152. {experimaestro-2.0.0b8.dist-info → experimaestro-2.0.0b17.dist-info}/licenses/LICENSE +0 -0
@@ -1,434 +0,0 @@
1
- """Tests for workspace-level database models"""
2
-
3
- import pytest
4
- from pathlib import Path
5
- from experimaestro.scheduler.state_db import (
6
- ExperimentModel,
7
- ExperimentRunModel,
8
- JobModel,
9
- JobTagModel,
10
- ServiceModel,
11
- WorkspaceSyncMetadata,
12
- initialize_workspace_database,
13
- close_workspace_database,
14
- ALL_MODELS,
15
- )
16
- from experimaestro.scheduler.state_sync import sync_workspace_from_disk
17
- from experimaestro import Task, Param
18
- from experimaestro.tests.utils import TemporaryExperiment
19
-
20
-
21
- def test_database_initialization(tmp_path: Path):
22
- """Test that workspace database is initialized correctly"""
23
- db_path = tmp_path / "workspace.db"
24
-
25
- # Initialize database
26
- db, _ = initialize_workspace_database(db_path, read_only=False)
27
-
28
- # Verify all tables were created
29
- assert ExperimentModel.table_exists()
30
- assert ExperimentRunModel.table_exists()
31
- assert JobModel.table_exists()
32
- assert JobTagModel.table_exists()
33
- assert ServiceModel.table_exists()
34
- assert WorkspaceSyncMetadata.table_exists()
35
-
36
- # Verify WorkspaceSyncMetadata was initialized
37
- metadata = WorkspaceSyncMetadata.get_or_none(
38
- WorkspaceSyncMetadata.id == "workspace"
39
- )
40
- assert metadata is not None
41
- assert metadata.sync_interval_minutes == 5
42
-
43
- # Cleanup
44
- close_workspace_database(db)
45
-
46
-
47
- def test_experiment_and_run_models(tmp_path: Path):
48
- """Test creating experiments and runs"""
49
- db_path = tmp_path / "workspace.db"
50
- db, _ = initialize_workspace_database(db_path, read_only=False)
51
-
52
- with db.bind_ctx(ALL_MODELS):
53
- # Create an experiment
54
- ExperimentModel.create(experiment_id="test_exp")
55
-
56
- # Create a run for this experiment
57
- ExperimentRunModel.create(
58
- experiment_id="test_exp", run_id="run_001", status="active"
59
- )
60
-
61
- # Update experiment to point to this run
62
- ExperimentModel.update(current_run_id="run_001").where(
63
- ExperimentModel.experiment_id == "test_exp"
64
- ).execute()
65
-
66
- # Verify
67
- retrieved_exp = ExperimentModel.get(ExperimentModel.experiment_id == "test_exp")
68
- assert retrieved_exp.current_run_id == "run_001"
69
-
70
- retrieved_run = ExperimentRunModel.get(
71
- (ExperimentRunModel.experiment_id == "test_exp")
72
- & (ExperimentRunModel.run_id == "run_001")
73
- )
74
- assert retrieved_run.status == "active"
75
-
76
- close_workspace_database(db)
77
-
78
-
79
- def test_job_model_with_composite_key(tmp_path: Path):
80
- """Test job model with composite primary key (job_id, experiment_id, run_id)"""
81
- db_path = tmp_path / "workspace.db"
82
- db, _ = initialize_workspace_database(db_path, read_only=False)
83
-
84
- with db.bind_ctx(ALL_MODELS):
85
- # Create experiment and run first
86
- ExperimentModel.create(experiment_id="exp1", current_run_id="run1")
87
- ExperimentRunModel.create(experiment_id="exp1", run_id="run1")
88
-
89
- # Create a job
90
- JobModel.create(
91
- job_id="job_abc",
92
- experiment_id="exp1",
93
- run_id="run1",
94
- task_id="MyTask",
95
- locator="",
96
- state="running",
97
- submitted_time=1234567890.0,
98
- )
99
-
100
- # Same job in different run
101
- ExperimentRunModel.create(experiment_id="exp1", run_id="run2")
102
- JobModel.create(
103
- job_id="job_abc",
104
- experiment_id="exp1",
105
- run_id="run2",
106
- task_id="MyTask",
107
- locator="",
108
- state="done",
109
- submitted_time=1234567891.0,
110
- )
111
-
112
- # Both should exist independently
113
- jobs = list(JobModel.select().where(JobModel.job_id == "job_abc"))
114
- assert len(jobs) == 2
115
-
116
- # Can update one without affecting the other
117
- JobModel.update(state="done").where(
118
- (JobModel.job_id == "job_abc")
119
- & (JobModel.experiment_id == "exp1")
120
- & (JobModel.run_id == "run1")
121
- ).execute()
122
-
123
- job_run1 = JobModel.get(
124
- (JobModel.job_id == "job_abc")
125
- & (JobModel.experiment_id == "exp1")
126
- & (JobModel.run_id == "run1")
127
- )
128
- assert job_run1.state == "done"
129
-
130
- close_workspace_database(db)
131
-
132
-
133
- def test_job_tags_model(tmp_path: Path):
134
- """Test run-scoped job tags (fixes GH #128)"""
135
- db_path = tmp_path / "workspace.db"
136
- db, _ = initialize_workspace_database(db_path, read_only=False)
137
-
138
- with db.bind_ctx(ALL_MODELS):
139
- # Create experiment and runs
140
- ExperimentModel.create(experiment_id="exp1")
141
- ExperimentRunModel.create(experiment_id="exp1", run_id="run1")
142
- ExperimentRunModel.create(experiment_id="exp1", run_id="run2")
143
-
144
- # Create job in both runs
145
- JobModel.create(
146
- job_id="job1",
147
- experiment_id="exp1",
148
- run_id="run1",
149
- task_id="Task",
150
- locator="",
151
- state="done",
152
- )
153
- JobModel.create(
154
- job_id="job1",
155
- experiment_id="exp1",
156
- run_id="run2",
157
- task_id="Task",
158
- locator="",
159
- state="done",
160
- )
161
-
162
- # Add different tags to same job in different runs
163
- JobTagModel.create(
164
- job_id="job1",
165
- experiment_id="exp1",
166
- run_id="run1",
167
- tag_key="env",
168
- tag_value="production",
169
- )
170
-
171
- JobTagModel.create(
172
- job_id="job1",
173
- experiment_id="exp1",
174
- run_id="run2",
175
- tag_key="env",
176
- tag_value="testing",
177
- )
178
-
179
- # Verify tags are independent per run
180
- run1_tags = list(
181
- JobTagModel.select().where(
182
- (JobTagModel.job_id == "job1")
183
- & (JobTagModel.experiment_id == "exp1")
184
- & (JobTagModel.run_id == "run1")
185
- )
186
- )
187
- assert len(run1_tags) == 1
188
- assert run1_tags[0].tag_value == "production"
189
-
190
- run2_tags = list(
191
- JobTagModel.select().where(
192
- (JobTagModel.job_id == "job1")
193
- & (JobTagModel.experiment_id == "exp1")
194
- & (JobTagModel.run_id == "run2")
195
- )
196
- )
197
- assert len(run2_tags) == 1
198
- assert run2_tags[0].tag_value == "testing"
199
-
200
- close_workspace_database(db)
201
-
202
-
203
- def test_multiple_experiments_same_workspace(tmp_path: Path):
204
- """Test that multiple experiments can coexist in same workspace database"""
205
- db_path = tmp_path / "workspace.db"
206
- db, _ = initialize_workspace_database(db_path, read_only=False)
207
-
208
- with db.bind_ctx(ALL_MODELS):
209
- # Create two experiments
210
- ExperimentModel.create(experiment_id="exp1")
211
- ExperimentModel.create(experiment_id="exp2")
212
-
213
- # Create runs for each
214
- ExperimentRunModel.create(experiment_id="exp1", run_id="run1")
215
- ExperimentRunModel.create(experiment_id="exp2", run_id="run1")
216
-
217
- # Create jobs for each experiment
218
- JobModel.create(
219
- job_id="job1",
220
- experiment_id="exp1",
221
- run_id="run1",
222
- task_id="Task",
223
- locator="",
224
- state="done",
225
- )
226
- JobModel.create(
227
- job_id="job2",
228
- experiment_id="exp2",
229
- run_id="run1",
230
- task_id="Task",
231
- locator="",
232
- state="running",
233
- )
234
-
235
- # Query jobs for specific experiment
236
- exp1_jobs = list(JobModel.select().where(JobModel.experiment_id == "exp1"))
237
- assert len(exp1_jobs) == 1
238
- assert exp1_jobs[0].job_id == "job1"
239
-
240
- exp2_jobs = list(JobModel.select().where(JobModel.experiment_id == "exp2"))
241
- assert len(exp2_jobs) == 1
242
- assert exp2_jobs[0].job_id == "job2"
243
-
244
- close_workspace_database(db)
245
-
246
-
247
- def test_read_only_mode(tmp_path: Path):
248
- """Test that read-only mode prevents writes"""
249
- db_path = tmp_path / "workspace.db"
250
-
251
- # Create database with write mode
252
- db_write, _ = initialize_workspace_database(db_path, read_only=False)
253
- with db_write.bind_ctx(ALL_MODELS):
254
- ExperimentModel.create(experiment_id="exp1")
255
- close_workspace_database(db_write)
256
-
257
- # Open in read-only mode
258
- db_read, _ = initialize_workspace_database(db_path, read_only=True)
259
-
260
- with db_read.bind_ctx(ALL_MODELS):
261
- # Can read
262
- exp = ExperimentModel.get(ExperimentModel.experiment_id == "exp1")
263
- assert exp.experiment_id == "exp1"
264
-
265
- # Cannot write (SQLite will raise OperationalError)
266
- with pytest.raises(Exception): # Could be OperationalError or similar
267
- ExperimentModel.create(experiment_id="exp2", workdir_path="/tmp/exp2")
268
-
269
- close_workspace_database(db_read)
270
-
271
-
272
- def test_upsert_on_conflict(tmp_path: Path):
273
- """Test that on_conflict works for updating existing records"""
274
- db_path = tmp_path / "workspace.db"
275
- db, _ = initialize_workspace_database(db_path, read_only=False)
276
-
277
- with db.bind_ctx(ALL_MODELS):
278
- # Create experiment and run
279
- ExperimentModel.create(experiment_id="exp1")
280
- ExperimentRunModel.create(experiment_id="exp1", run_id="run1")
281
-
282
- # Create job
283
- JobModel.insert(
284
- job_id="job1",
285
- experiment_id="exp1",
286
- run_id="run1",
287
- task_id="Task",
288
- locator="",
289
- state="running",
290
- ).execute()
291
-
292
- # Upsert with different state (disk wins)
293
- JobModel.insert(
294
- job_id="job1",
295
- experiment_id="exp1",
296
- run_id="run1",
297
- task_id="Task",
298
- locator="",
299
- state="done",
300
- ).on_conflict(
301
- conflict_target=[JobModel.job_id, JobModel.experiment_id, JobModel.run_id],
302
- update={JobModel.state: "done"},
303
- ).execute()
304
-
305
- # Verify state was updated
306
- job = JobModel.get(
307
- (JobModel.job_id == "job1")
308
- & (JobModel.experiment_id == "exp1")
309
- & (JobModel.run_id == "run1")
310
- )
311
- assert job.state == "done"
312
-
313
- # Only one job should exist
314
- assert JobModel.select().where(JobModel.job_id == "job1").count() == 1
315
-
316
- close_workspace_database(db)
317
-
318
-
319
- # Define test task
320
- class SimpleTask(Task):
321
- value: Param[int]
322
-
323
- def execute(self):
324
- # Write a marker file to indicate completion
325
- (self.__taskdir__ / "output.txt").write_text(f"value={self.value}")
326
-
327
-
328
- def test_database_recovery_from_disk(tmp_path: Path):
329
- """Test recovering database from jobs.jsonl and disk state"""
330
-
331
- # Step 1: Run experiment with tasks and tags
332
- workdir = tmp_path / "workspace"
333
- workdir.mkdir()
334
-
335
- with TemporaryExperiment("recovery", maxwait=0, workdir=workdir):
336
- # Submit first task with tags
337
- task1 = SimpleTask.C(value=42).tag("priority", "high").tag("env", "test")
338
- task1.submit()
339
-
340
- # Submit second task with different tags
341
- task2 = SimpleTask.C(value=100).tag("priority", "low").tag("env", "prod")
342
- task2.submit()
343
-
344
- # Step 2: Verify jobs.jsonl was created
345
- jobs_jsonl_path = workdir / "xp" / "recovery" / "jobs.jsonl"
346
- assert jobs_jsonl_path.exists(), "jobs.jsonl should have been created"
347
-
348
- # Verify database exists
349
- workspace_db_path = workdir / ".experimaestro" / "workspace.db"
350
- assert workspace_db_path.exists()
351
-
352
- # Get workspace state provider and access database
353
- from experimaestro.scheduler.state_provider import WorkspaceStateProvider
354
-
355
- provider = WorkspaceStateProvider.get_instance(
356
- workdir, read_only=False, sync_on_start=False
357
- )
358
-
359
- with provider.workspace_db.bind_ctx(ALL_MODELS):
360
- # Get original state
361
- original_jobs = list(JobModel.select())
362
-
363
- # If no jobs in DB yet, sync from disk first
364
- if len(original_jobs) == 0:
365
- sync_workspace_from_disk(workdir, write_mode=True, force=True)
366
- original_jobs = list(JobModel.select())
367
-
368
- assert len(original_jobs) == 2
369
-
370
- original_job_ids = {job.job_id for job in original_jobs}
371
- assert len(original_job_ids) == 2
372
-
373
- # Get original tags
374
- original_tags = {}
375
- for job in original_jobs:
376
- job_tags = list(
377
- JobTagModel.select().where(
378
- (JobTagModel.job_id == job.job_id)
379
- & (JobTagModel.experiment_id == job.experiment_id)
380
- & (JobTagModel.run_id == job.run_id)
381
- )
382
- )
383
- original_tags[job.job_id] = {tag.tag_key: tag.tag_value for tag in job_tags}
384
-
385
- assert len(original_tags) == 2
386
- # Verify we have tags for both jobs
387
- for job_id, tags in original_tags.items():
388
- assert "priority" in tags
389
- assert "env" in tags
390
-
391
- # Close provider to cleanup
392
- provider.close()
393
-
394
- # Step 3: Delete the database
395
- workspace_db_path.unlink()
396
- assert not workspace_db_path.exists()
397
-
398
- # Step 4: Recover from disk by syncing - get new provider instance
399
- provider2 = WorkspaceStateProvider.get_instance(
400
- workdir, read_only=False, sync_on_start=False
401
- )
402
- sync_workspace_from_disk(
403
- workdir, write_mode=True, force=True, sync_interval_minutes=0
404
- )
405
-
406
- # Step 5: Verify recovered state matches original
407
- with provider2.workspace_db.bind_ctx(ALL_MODELS):
408
- # Check jobs were recovered
409
- recovered_jobs = list(JobModel.select())
410
- assert len(recovered_jobs) == 2
411
-
412
- recovered_job_ids = {job.job_id for job in recovered_jobs}
413
- assert recovered_job_ids == original_job_ids
414
-
415
- # Check tags were recovered
416
- recovered_tags = {}
417
- for job in recovered_jobs:
418
- job_tags = list(
419
- JobTagModel.select().where(
420
- (JobTagModel.job_id == job.job_id)
421
- & (JobTagModel.experiment_id == job.experiment_id)
422
- & (JobTagModel.run_id == job.run_id)
423
- )
424
- )
425
- recovered_tags[job.job_id] = {
426
- tag.tag_key: tag.tag_value for tag in job_tags
427
- }
428
-
429
- assert len(recovered_tags) == 2
430
-
431
- # Verify tags match
432
- for job_id in original_job_ids:
433
- assert job_id in recovered_tags
434
- assert recovered_tags[job_id] == original_tags[job_id]
@@ -1,187 +0,0 @@
1
- experimaestro/__init__.py,sha256=X8HN3hjYVAZk2g7ogRApBbAjMtQrE-HDpEeYLtcu0CU,1720
2
- experimaestro/__main__.py,sha256=Dv9lFl03yt1dswd0Xb9NIJRgHpA5_IwH4RfQPEHyFz0,158
3
- experimaestro/annotations.py,sha256=1gdi17YT7t1WteJCUz7SAis0J1ctQl2ABxlUv49mXog,8842
4
- experimaestro/checkers.py,sha256=ZCMbnE_GFC5compWjt-fuHhPImi9fCPjImF8Ow9NqK8,696
5
- experimaestro/click.py,sha256=6FQPLtD61C65lcOYy-dOIOukXIeJEanhAUQO1ax1jHI,1311
6
- experimaestro/commandline.py,sha256=7sID0zHdGlyUt6vBRCyfAXlgVWDSok1cE98ZexhGjB0,9689
7
- experimaestro/exceptions.py,sha256=dVdbYwbpJokjqu-m8go5Oh6TpvSMbT2ztv1P3aV9weQ,990
8
- experimaestro/generators.py,sha256=t26kqGDY2Q2JfwCfO1mV48cchEM2JltAUGetJ3dBGAU,2936
9
- experimaestro/huggingface.py,sha256=G8kTgFzhCRJJfz1DcbZsPD7NprDYVajW-rTBAjg6jX4,3000
10
- experimaestro/ipc.py,sha256=Xn3tYME83jLEB0nFak3DwEIhpL5IRZpCl3jirBF_jl4,1570
11
- experimaestro/locking.py,sha256=hPT-LuDGZTijpbme8O0kEoB9a3WjdVzI2h31OT44UxE,1477
12
- experimaestro/mypy.py,sha256=WyaZU01v8sSqXc7meiIY-e8cBKqKrMbK-ITlpUkIrgc,14217
13
- experimaestro/notifications.py,sha256=fk0G0xnpv4ps35Wp-4QN2N00i5wDAacGr_A24qOu1LM,11357
14
- experimaestro/progress.py,sha256=1766Kf5INOUKQE4HdTy90IYcu-Pxah1F3ScEa_X4uGU,14810
15
- experimaestro/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
- experimaestro/rpyc.py,sha256=0j-kZuBWvc2uZujodX7kcgz3QDJ44ZgnG7Is_bPeSDg,3591
17
- experimaestro/run.py,sha256=N2CFTB5eVNC40tE3vjQgXPZK9WD5alwPe4Fpieo_e8E,5989
18
- experimaestro/scriptbuilder.py,sha256=wJR20Az-YYWR0i_WLWb-VtgV3IIXYuC-LyutorfVF1I,5308
19
- experimaestro/settings.py,sha256=ymA-W2-cNOE1W8oc7lPPxOwEz2wXSX9Q5iftw0agKcY,4489
20
- experimaestro/taskglobals.py,sha256=A_P49RHu8FLOfoybfwcLzDcDZiUug4mLFKiAzsCof_k,1315
21
- experimaestro/tokens.py,sha256=IitlWi8CJprTXFTw0GJ3cf-vch-x5IyJztiik5FYC1M,18578
22
- experimaestro/typingutils.py,sha256=v7wS9xewF3cYOKvaBFxlTB-qplJ8olI1OaO3tAKiwIo,3678
23
- experimaestro/version.py,sha256=xb387tRebssohFiC2cBfY1gEG-Ur9UZkojiYpRcNRbA,712
24
- experimaestro/xpmutils.py,sha256=S21eMbDYsHfvmZ1HmKpq5Pz5O-1HnCLYxKbyTBbASyQ,638
25
- experimaestro/cli/__init__.py,sha256=-ps3-5_fnqH61oRbCYZ1h-bWoLazHjLXIJP2mMYSWFY,17989
26
- experimaestro/cli/filter.py,sha256=0Lq9B_ZNSjVU1N6sCv-YETjAPtRVwunlfGxtG6aeBpY,5024
27
- experimaestro/cli/jobs.py,sha256=lnxlISYjVzdOk3lkEhIuV0MRyCO1JprTgg56R5KJ1No,10049
28
- experimaestro/cli/progress.py,sha256=I6qhVe-vvqA1ym6XJE75q7Hb0jGeFwgodIqfhlTrPKY,8200
29
- experimaestro/cli/refactor.py,sha256=qKEMi1EfN-qUGCutpH4cy5co-E1XZyLm_FLDgQaOk3M,8297
30
- experimaestro/connectors/__init__.py,sha256=vQjUd2pDIKQr5P4sJPHsS3UfXraIizECP1sCZ9HAVmM,6768
31
- experimaestro/connectors/local.py,sha256=gvzydQeOeaHfckIiPa6K4lADjIFkU2LsGEaqLgroxb8,6614
32
- experimaestro/connectors/ssh.py,sha256=5giqvv1y0QQKF-GI0IFUzI_Z5H8Bj9EuL_Szpvk899Q,8600
33
- experimaestro/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
- experimaestro/core/arguments.py,sha256=PhhltA-j8f9bcp_be6vaKxPdXpimOARTQmYCGvIfaZI,13163
35
- experimaestro/core/callbacks.py,sha256=59JfeUgWcCCdIQ3pvh-xNnoRp9BX8f4iOAkgm16wBzE,1660
36
- experimaestro/core/context.py,sha256=1tLmX7WcgEKSbGw77vfziTzS8KNsoZJ02JBWMBCqqOk,2606
37
- experimaestro/core/identifier.py,sha256=zGalnUkSLfIs7TnuVaFXEr0tgb5RLdPiXrw1WHxrhqo,15401
38
- experimaestro/core/serialization.py,sha256=nwHqnSjplceGxFJs1CsVkHmlG6uK89G_nXq39B0FYrg,8365
39
- experimaestro/core/serializers.py,sha256=iOBuASEgD8dRKPnL16iOLBsM0GHChCJgjBd7LixFui4,919
40
- experimaestro/core/subparameters.py,sha256=bIF4bTkcSyjeNh_07QnfN_83fow7_tGdeeDCtnf0kb8,5833
41
- experimaestro/core/types.py,sha256=Yd4jgO6xt0LxvJl1jZek13WMXlw3MlZumxfGxQdaVJk,26843
42
- experimaestro/core/utils.py,sha256=JfC3qGUS9b6FUHc2VxIYUI9ysNpXSQ1LjOBkjfZ8n7o,495
43
- experimaestro/core/objects/__init__.py,sha256=-7FUbhIgZ1_eqi9RKwQZRPmxrtLgt2DqqOge7Blz5ZU,833
44
- experimaestro/core/objects/config.py,sha256=YXJ5_B8mmW_tVvjGGhCVQPic3iLbU1xFv6xKuXRthqs,74400
45
- experimaestro/core/objects/config_utils.py,sha256=ZLECGkeIWdzunm8vwWsQhvcSgV1e064BgXbLiZnxSEM,1288
46
- experimaestro/core/objects/config_walk.py,sha256=lMK7dXMjqfDaqc4NPxenYABozKYusmJ8xhDbDFP8z5U,4980
47
- experimaestro/experiments/__init__.py,sha256=GcpDUIbCvhnv6rxFdAp4wTffCVNTv-InY6fbQAlTy-o,159
48
- experimaestro/experiments/cli.py,sha256=WbeK4PNEy9cQoX_mJiLkMuu57lCLURg2I7dC3nECTmY,13345
49
- experimaestro/experiments/configuration.py,sha256=vVm40BJW5sZNgSDZ0oBzX15jTO9rmOewVYrm0k9iXXY,1466
50
- experimaestro/launcherfinder/__init__.py,sha256=qRUDyv3B9UsAM8Q31mRrZrTZox0AptwdmOY4f2K-TUo,279
51
- experimaestro/launcherfinder/base.py,sha256=q47SsF_cXdo5O6ZhFKn5385WVFcx8Wd-BcEpd6tRpbs,515
52
- experimaestro/launcherfinder/parser.py,sha256=2Z4lIX5drbZr5jWqL2vZy1qmPfFw_homxaXEb86fKTc,3489
53
- experimaestro/launcherfinder/registry.py,sha256=qP2Y9mfxn7XvIBr4ot2zkyKw6sWhmgBxDDKU5Ty04FE,6417
54
- experimaestro/launcherfinder/specs.py,sha256=eQC2pwAnvq7kF2xmAfHpg_Wx6_lH6YMf3ZCDwqatjKk,7898
55
- experimaestro/launchers/__init__.py,sha256=asoe6Bn7tjXEpZL7sfpV5V7k7YWFexZWaxtYtBY7Se8,3440
56
- experimaestro/launchers/direct.py,sha256=7Uec6dkssUzHOYcXz6ZwOr-NF-CuiXuQU3Uj11IHKz0,678
57
- experimaestro/launchers/oar.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
- experimaestro/launchers/slurm/__init__.py,sha256=R1Zwd4phZaXV8FwCYhzfB44n0V4cf-hBQzOc6NkFQ0s,41
59
- experimaestro/launchers/slurm/base.py,sha256=YTL-bCH0EKCkI9LJcbXPQWpraLF5UzD3b6vRoxDGrWA,20952
60
- experimaestro/mkdocs/__init__.py,sha256=L9UDM7vOrRZl41zXTBOaHKSINEEsbmxwjIMIGESmLfU,46
61
- experimaestro/mkdocs/annotations.py,sha256=qpDw8lzrxpsOShXcpcP_LAeR3UhiIXAybG8UvS64-OU,263
62
- experimaestro/mkdocs/base.py,sha256=qHDZZFdoNRsW6RcjRB1WCSp2sOtRiBk9zFO1acK05BQ,16706
63
- experimaestro/mkdocs/metaloader.py,sha256=ItchfE3emrzKUrT-8f8WsDHNHisYzs9XDCzhWcu6VaQ,1471
64
- experimaestro/mkdocs/style.css,sha256=42kJ6Ozq_n4Iw5UfJ4-nO1u-HN3ELvV7Vhvj1Xkn7rQ,66
65
- experimaestro/scheduler/__init__.py,sha256=HssbogPCuGpKGMPZQP07XCT2-uMFRPANuPM-duMIrq4,422
66
- experimaestro/scheduler/base.py,sha256=IMVwLUEm0hPJzfX0sb6efI1Ic1-o1Ya56mlxG8FXyqI,28269
67
- experimaestro/scheduler/dependencies.py,sha256=gQfmIEa8l9mMVMmBuoPfUM30eQzEozFkCQGXkbfXhaU,2406
68
- experimaestro/scheduler/dynamic_outputs.py,sha256=pKSm73D_XIgUHawf432JJXfQKISO34qEMf5w-nWTl-g,11187
69
- experimaestro/scheduler/experiment.py,sha256=N7-903ADgqlJumgldOdS4BAI2nIcKPFUCDXqW_mHLsQ,22334
70
- experimaestro/scheduler/interfaces.py,sha256=JG1Z6iGWosiM-TrEkxhsPz-dJ4lfPQL6dnaGjbCn-aA,16008
71
- experimaestro/scheduler/jobs.py,sha256=h04Vj595zxvpgvJOr-3wK_rFBvVmlYqO68gq1euI4vc,15634
72
- experimaestro/scheduler/services.py,sha256=CVZ7YDB71qQe86oCEQWPzgRTchEtYUZWx3KxqGykhnc,13053
73
- experimaestro/scheduler/signal_handler.py,sha256=B4ZeSVB8O41VDdFmV4n2cyBds7wKFG3kH2Fp7cpyxa4,872
74
- experimaestro/scheduler/state.py,sha256=1ICn1K5gNMCEUb85vwwXLIUF6Lxqa5mbTgMzEz2pnXw,2367
75
- experimaestro/scheduler/state_db.py,sha256=HmM0PCKZoGix_VR571M4ZATag7e52KeWaFhOzBtRgRE,15855
76
- experimaestro/scheduler/state_provider.py,sha256=X3sqdC8UnUlnveaFjMwjnEhCkHuiLpM9xp1WRpskAiE,94907
77
- experimaestro/scheduler/state_sync.py,sha256=yrwHdGqUck_QbVCHymP5mnJHN1Z_0dILleV_vDw16KQ,34678
78
- experimaestro/scheduler/workspace.py,sha256=hIASgxGQtrlN4oPFDqDYXTVnxDbngirGdDyAJxJq4vg,3815
79
- experimaestro/scheduler/remote/__init__.py,sha256=QBXrl4V09nPbwxKRtV7-uLdZCXtktWBeSAV7kB2ZWOM,1134
80
- experimaestro/scheduler/remote/client.py,sha256=FX9ZieKfz2s7SBt1KWGOLUqwuey2EAnzasKdAB8Ifsg,31501
81
- experimaestro/scheduler/remote/protocol.py,sha256=Rc2_nsln-xw9kMnDOMbMXSIIgIjMciYhLCg4caHZgFs,13831
82
- experimaestro/scheduler/remote/server.py,sha256=T61yaaU-tn3Pmh0wevrozyl20Oj_D5S5S-SpKGy_nQ0,15739
83
- experimaestro/scheduler/remote/sync.py,sha256=BgPK96EJY3AxjBmrwo53CN5fUmGED-a12ZTODkJ_mQk,4917
84
- experimaestro/server/__init__.py,sha256=BXLPcDRy7Bxx0xk24SF8OthvcE_rk7Afx7yVvgYvM2o,15920
85
- experimaestro/sphinx/__init__.py,sha256=DhFRj8MxA9XZH-TCnbl_5bYhGiF4ihiuFwQj74oPEp4,9466
86
- experimaestro/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
87
- experimaestro/tests/conftest.py,sha256=9LT2rPsMUZOejUzeazL6IQRJhoM3VbhG2_oOVhZ6Hto,3757
88
- experimaestro/tests/definitions_types.py,sha256=nMoQxZxhTJAYV87Ce9F2dAITxXGHf7Uw5j-MKsZ3LmQ,399
89
- experimaestro/tests/identifier_stability.json,sha256=ygb6p1e8RsjGoqvGoW02ftFCCZIXAZIBsDZjP0Zsdhg,3791
90
- experimaestro/tests/restart.py,sha256=aAizVLvw2DaNfIzuRB13iYXOoX1Q5NkgsngumERlo2s,4191
91
- experimaestro/tests/restart_main.py,sha256=iAFzw0H1q9Aq7t6TrSAj236QBnYU52qx0VF-2dz6tx4,295
92
- experimaestro/tests/task_tokens.py,sha256=vgqUa-S_YC2Id9pGOSv40qFTwq1WGZkFhr556Z5o678,477
93
- experimaestro/tests/test_checkers.py,sha256=e6Rv2TlePRY__VXs0vUb6a5Aw_KIq_cs4N86VhnYHtw,407
94
- experimaestro/tests/test_cli_jobs.py,sha256=hQimCKsgr44smvX7rxoOUS2knGBpcfvIhuwZWSSawic,19358
95
- experimaestro/tests/test_dependencies.py,sha256=LvpmMcfnRzQPzUIuFNCIQnJot8YBSxCA827xh9gYlq0,1890
96
- experimaestro/tests/test_deprecated.py,sha256=SWuc37o9E-9VsWnwNQBHWiWHdn4syeVTouMSPWyqhww,20061
97
- experimaestro/tests/test_environment.py,sha256=HEIV4OIBaPdGnqi8bdqkwucc2Ezr-VMnNUiA2qYVIHE,6923
98
- experimaestro/tests/test_experiment.py,sha256=Nfevu_aMyX4c5xTjDHMeKXZWs2HMOhy96tsQlnF-IVs,1693
99
- experimaestro/tests/test_file_progress.py,sha256=uNUUq-ptcnxu56zRvUUZ5EYM9ZIQbUmOU_LI0roMgSw,15119
100
- experimaestro/tests/test_file_progress_integration.py,sha256=IsRwhcNWgTRXD6pum19K0HXptxOu8Qm5zulKCZBtBPQ,16758
101
- experimaestro/tests/test_findlauncher.py,sha256=KPy8ow--NXS1KFCIpxrmEJFRvjo-v-PwlVHVyoVKLPg,3134
102
- experimaestro/tests/test_forward.py,sha256=UYYmFl3N4icoA024ubKmCq_vngrGK2aBthfFptIX66U,786
103
- experimaestro/tests/test_generators.py,sha256=R0UypTzxX0dPYvY4A_kozpLDHhGzQDNfLQyc0oRaSx8,2891
104
- experimaestro/tests/test_identifier.py,sha256=oPqCqAIXGsjkXF3-UNtltbFSHRJREUpo-hx2r4Oz5dg,26776
105
- experimaestro/tests/test_identifier_stability.py,sha256=GgfXC-DFIKrA9uTT0-Zm3B2SkbB1llNS2Ls6o4eKvQ4,12572
106
- experimaestro/tests/test_instance.py,sha256=CZ49fjEIvbiJCb-GdDRSt7kP48JnpZUk1GvSvXNb1Bc,1376
107
- experimaestro/tests/test_multitoken.py,sha256=md2egK58goaHmXNP030GECvTOSG-03LqyTZDyREOKkk,14446
108
- experimaestro/tests/test_mypy.py,sha256=wtcPd8vCn7mCyMo5-DCaOEYZS9IARw3IGa-C4ezGKxs,11900
109
- experimaestro/tests/test_objects.py,sha256=YVOfdWjAieFTWQFqm9Q6RFg8rBgNmP8_PXXmkX_RLMA,9988
110
- experimaestro/tests/test_outputs.py,sha256=wO53O6yWVT2sBlRXHTgsv_9i_Y8X5-JnOVfrExQSw2M,826
111
- experimaestro/tests/test_param.py,sha256=cmCvzpCGSNpcFAI2lfIQe2lTYBfxO8gr5I0SVXiNafQ,7346
112
- experimaestro/tests/test_partial_paths.py,sha256=XiYJsqP8IFW-gypvWBrXziMBBk3naXJp2-0OnEgKoUQ,9066
113
- experimaestro/tests/test_progress.py,sha256=Baz2z749CWmMauldMxfMr8A77w3lRNr8eDpsPn317sc,5968
114
- experimaestro/tests/test_remote_state.py,sha256=cILubH-dF1iFMmBYLQtVsbpmfJQgDEaK7xHKOe9edGg,23217
115
- experimaestro/tests/test_resumable_task.py,sha256=H5plRfuQ7bhWzP9TQgGAxm6-GlbtPOTLm9WMZhvRUZ0,17080
116
- experimaestro/tests/test_serializers.py,sha256=DWe3gbaQP16tQawDz8uSiDpQ_nyTuYjFMvoGEwIWfhU,5302
117
- experimaestro/tests/test_snippets.py,sha256=rojnyDjtmAMnSuDUj6Bv9XEgdP8oQf2nVc132JF8vsM,3081
118
- experimaestro/tests/test_ssh.py,sha256=KS1NWltiXrJBSStY9d4mwrexeqgNGWmhxuAU_WLQDAU,1449
119
- experimaestro/tests/test_state_db.py,sha256=4FfMXYCJyZCltnwKf6ITX08_xXozFJxkcCmrLVlTGzQ,14197
120
- experimaestro/tests/test_subparameters.py,sha256=mDDwPK-KlaZBf0uStxLOhxKElxhp_7mb1DYNJ02yfvg,5792
121
- experimaestro/tests/test_tags.py,sha256=VTjowJljm8sCGiEuOIDeoNO4NPJNY1pu4b7G8dWqBes,6596
122
- experimaestro/tests/test_tasks.py,sha256=E4LWKR_6N4bD0iONeGHQ24c4iNcXsp8l1f4jnwq0MH4,9104
123
- experimaestro/tests/test_token_locking.py,sha256=Le8dAlQEoiDHK2_c_rMGsUlCMpjuBsLUkN4qHzz_9wk,7009
124
- experimaestro/tests/test_tokens.py,sha256=KfpReZCC2MuxNiPPD8addl84arhN16OugrGs6tuuyPo,8075
125
- experimaestro/tests/test_types.py,sha256=AavpWOtwQTVp5IuzfwRskBU4khoeomXXizhZoeSVPp4,4724
126
- experimaestro/tests/test_validation.py,sha256=tinkXETcAGtgPIsmbioKSU00kGIV1YnniHTGDDcUOq8,4118
127
- experimaestro/tests/test_workspace_triggers.py,sha256=idXnS95CBNmTj3YajWS93ZCZfVzOffne2hcMIwmEd2w,4700
128
- experimaestro/tests/token_reschedule.py,sha256=CL3IrCyPfPRJXxC1kTbx8_QO0qUnesJd8u0gPfyCatA,1794
129
- experimaestro/tests/utils.py,sha256=nwG1FfXsceWxnhAwG6XWL4aDCTaH5FqxYcjG74mJOks,3805
130
- experimaestro/tests/connectors/test_local.py,sha256=hMX3maYYRABGXqRZFZbTWjf-jcvPkBq9nReLtDwLydk,1204
131
- experimaestro/tests/connectors/utils.py,sha256=9sM3Pwy2nRfSr7pwQoOoSCDhBrEcDsEElI08Fmrw_gU,702
132
- experimaestro/tests/connectors/bin/executable.py,sha256=RmCrH_MQiHuPRyeTP2jut0ASpfvHEH1QCxRnlvDZW2s,21
133
- experimaestro/tests/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
134
- experimaestro/tests/core/test_generics.py,sha256=oRKSmmofWBwnL2DgUtILSuzjgaTd7Y3EeN003Me9SQk,5214
135
- experimaestro/tests/launchers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
136
- experimaestro/tests/launchers/common.py,sha256=WqVcWX3g0XYJS0aJO7XWVvOmncRBbQmGvuNxH9AHUAE,2998
137
- experimaestro/tests/launchers/test_local.py,sha256=4oGgWH2YgkEm-Muu6s4cwlgriXtYr5xAd72DVoIw_Yk,717
138
- experimaestro/tests/launchers/test_slurm.py,sha256=IRg9B4lpbRmx5u1vkCA9FlSbqlXCyf74_VV6AAil4Xw,5968
139
- experimaestro/tests/launchers/bin/sacct,sha256=hSrYRbwQBB0vY-Bn_FWvuU1xEXAv5G3fTUGglRpyv74,788
140
- experimaestro/tests/launchers/bin/sbatch,sha256=iaek9dgAFeEs927QOQQcWkCIkXL-6PFsTSk4qjIx9ZQ,1780
141
- experimaestro/tests/launchers/bin/srun,sha256=3oE3qq0UFpVtTvXfR1kH3tovFYX74fp1Fk-o8zgsaJA,47
142
- experimaestro/tests/launchers/bin/test.py,sha256=MbxdAd2Sf7T-Hj3ldmrtngbQuBdNOkXjMcICJTf39wI,477
143
- experimaestro/tests/launchers/config_slurm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
144
- experimaestro/tests/launchers/config_slurm/launchers.py,sha256=DohwQVv1eXWfDpAYFg7KJekEm7q7G-lMou2lPg-PKOk,838
145
- experimaestro/tests/scripts/notifyandwait.py,sha256=3BLXLI5XgP3BnKf6sQ56oKoMVqR80VMHmploJ3JO6Ko,407
146
- experimaestro/tests/scripts/waitforfile.py,sha256=EDT-TuFi2fU_qt51K5EmAxjw_OnJKkBW7UCfhrtDbVw,120
147
- experimaestro/tests/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
148
- experimaestro/tests/tasks/all.py,sha256=2KF0D1CB2PBwM_aXX09Ug6vy0MUQgoTATdheNeNKXHg,2101
149
- experimaestro/tests/tasks/foreign.py,sha256=uhXDOcWozkcm26ybbeEU9RElJpbhjC-zdzmlSKfPcdY,122
150
- experimaestro/tests/tasks/test_dynamic.py,sha256=NNw6IgZ8-LTmjsTU7cekb1YvQxbU4oFBj-Bbyc2Ir98,7984
151
- experimaestro/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
152
- experimaestro/tools/diff.py,sha256=mrI9QlZAVgMOGfyz3ryQT9wu5JBn9ndAiVk_EpCh0m4,3711
153
- experimaestro/tools/documentation.py,sha256=O2UzjzodPqGot3YSe6NYlK7S42XpplakUdqxFpvjqHQ,9184
154
- experimaestro/tools/jobs.py,sha256=63bXhJ7RGdczLU_nxu2skGn-9dwgr4r5pD23qH4WeBA,3516
155
- experimaestro/tui/__init__.py,sha256=BTf7I5HtG7AA_vGTSG891Jjz4R3wf-cEnpaEwB6xBA4,197
156
- experimaestro/tui/app.py,sha256=YXysC-VZaa-PRUUKyBaVdM_4IeC1SPSM7SFgGoLl5eI,89788
157
- experimaestro/tui/log_viewer.py,sha256=TFybc1LsCjbaC5sUQ8WMAwP6Uzy92GknpEmYx1u0csI,6938
158
- experimaestro/utils/__init__.py,sha256=iuBQw4lZT9Z4BIfQg0Yl9JHdbPgkSvkTH24xREeGHiI,3113
159
- experimaestro/utils/asyncio.py,sha256=9r_vFQs6T6tqmymC_DbHVFhY9YVRO6X48uEuyL_ugP8,726
160
- experimaestro/utils/environment.py,sha256=G_sxSsFK1sZg-nfLwNxVTUT3uq_PnEm7wio8vk0rYpk,5051
161
- experimaestro/utils/git.py,sha256=l2jcqRIgSygg5ZtrlFE9w5hsS4gr2Zca4I5OGmAwMdo,3830
162
- experimaestro/utils/jobs.py,sha256=42FAdKcn_v_-M6hcQZPUBr9kbDt1eVsk3a4E8Gc4eu8,2394
163
- experimaestro/utils/jupyter.py,sha256=JcEo2yQK7x3Cr1tNl5FqGMZOICxCv9DwMvL5xsWdQPk,2183
164
- experimaestro/utils/multiprocessing.py,sha256=am3DkHP_kmWbpynbck2c9QystCUtPBoSAC0ViBVzndU,1275
165
- experimaestro/utils/resources.py,sha256=I0UPGMhQ_bttWt5JJLs1r-CmQsCHwtbmYjUN8JJLFKg,1317
166
- experimaestro/utils/settings.py,sha256=jpFMqF0DLL4_P1xGal0zVR5cOrdD8O0Y2IOYvnRgN3k,793
167
- experimaestro/server/data/1815e00441357e01619e.ttf,sha256=gIRDrmyCBDla3YVD2oqQpguTdvsPh-2OjqN9EJWW2AU,210792
168
- experimaestro/server/data/2463b90d9a316e4e5294.woff2,sha256=qnWZhiOjkeYcaQF5Ss6DLj7N0oi1bWCPIb6gQRrMC44,158220
169
- experimaestro/server/data/2582b0e4bcf85eceead0.ttf,sha256=0vBZNUCw4zum3iVaVPJy1GbjEUSAaVa-qM_b9-3_yb0,426112
170
- experimaestro/server/data/89999bdf5d835c012025.woff2,sha256=40VtEoO511M3p3Pf0Ue_kI_QLAG0v0hXbYYDppsTy-U,25472
171
- experimaestro/server/data/914997e1bdfc990d0897.ttf,sha256=VM9ghve7IfnQcq1JShm0aB-lFt0KFM7lLaAdNlGpE6M,68064
172
- experimaestro/server/data/c210719e60948b211a12.woff2,sha256=1yNqGb8jy7ICcoDo9R3JnWxFl2ou1g3nM4KwNLGKK2g,118684
173
- experimaestro/server/data/favicon.ico,sha256=PRD32mxgMXg0AIFmjErFs66XQ8qaJiqw_NMS-7n0i90,3870
174
- experimaestro/server/data/index.css,sha256=ZNllclp0hcPGTwVgQrGPBGwTPBIts67w6tv_sJmqmEI,389472
175
- experimaestro/server/data/index.css.map,sha256=Wn4xr1Z8udeDGmmPaPb8XKB9967i8n-Eio5jmATjljk,571740
176
- experimaestro/server/data/index.html,sha256=LcXSo2QU5jcmqgmFhVWWOG_CfGyrqdm3H8jwkdRgdGU,706
177
- experimaestro/server/data/index.js,sha256=pt168t9gDsG4cqaBryVyRABgaiUMf8xBQZGxivLqPcI,3717503
178
- experimaestro/server/data/index.js.map,sha256=B_YbANsrKUNXMQe3JH1Jhl5ZMxo6ynVm463TnMxlo4g,3911206
179
- experimaestro/server/data/login.html,sha256=4dvhSOn6DHp_tbmzqIKrqq2uAo0sAUbgLVD0lTnPp4s,511
180
- experimaestro/server/data/manifest.json,sha256=EpzHQZzrGh9c1Kf63nrqvI33H1cm0nLYfdh5lDm8ijI,318
181
- experimaestro/tui/app.tcss,sha256=KsNvixGexmGld19ztBm-Nt5IH0gbclykfYgblP38Wy4,4556
182
- experimaestro/sphinx/static/experimaestro.css,sha256=0rEgt1LoDdD-a_R5rVfWZ19zD1gR-1L7q3f4UibIB58,294
183
- experimaestro-2.0.0b8.dist-info/METADATA,sha256=6xzN8WQQpLaaaTIA4Ujw7Jv4Sa7GP7a-VBYqAxj1eL8,6980
184
- experimaestro-2.0.0b8.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
185
- experimaestro-2.0.0b8.dist-info/entry_points.txt,sha256=S6AkrX0dM7MWcV-6QN6bazCcL18QAb-uyvmhtlI5hFI,440
186
- experimaestro-2.0.0b8.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
187
- experimaestro-2.0.0b8.dist-info/RECORD,,
File without changes
File without changes
File without changes
File without changes