experimaestro 2.0.0b4__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 (154) hide show
  1. experimaestro/__init__.py +12 -5
  2. experimaestro/cli/__init__.py +393 -134
  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 +223 -52
  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 +650 -53
  34. experimaestro/scheduler/dependencies.py +20 -16
  35. experimaestro/scheduler/experiment.py +764 -169
  36. experimaestro/scheduler/interfaces.py +338 -96
  37. experimaestro/scheduler/jobs.py +58 -20
  38. experimaestro/scheduler/remote/__init__.py +31 -0
  39. experimaestro/scheduler/remote/adaptive_sync.py +265 -0
  40. experimaestro/scheduler/remote/client.py +928 -0
  41. experimaestro/scheduler/remote/protocol.py +282 -0
  42. experimaestro/scheduler/remote/server.py +447 -0
  43. experimaestro/scheduler/remote/sync.py +144 -0
  44. experimaestro/scheduler/services.py +186 -35
  45. experimaestro/scheduler/state_provider.py +811 -2157
  46. experimaestro/scheduler/state_status.py +1247 -0
  47. experimaestro/scheduler/transient.py +31 -0
  48. experimaestro/scheduler/workspace.py +1 -1
  49. experimaestro/scheduler/workspace_state_provider.py +1273 -0
  50. experimaestro/scriptbuilder.py +4 -4
  51. experimaestro/settings.py +36 -0
  52. experimaestro/tests/conftest.py +33 -5
  53. experimaestro/tests/connectors/bin/executable.py +1 -1
  54. experimaestro/tests/fixtures/pre_experiment/experiment_check_env.py +16 -0
  55. experimaestro/tests/fixtures/pre_experiment/experiment_check_mock.py +14 -0
  56. experimaestro/tests/fixtures/pre_experiment/experiment_simple.py +12 -0
  57. experimaestro/tests/fixtures/pre_experiment/pre_setup_env.py +5 -0
  58. experimaestro/tests/fixtures/pre_experiment/pre_setup_error.py +3 -0
  59. experimaestro/tests/fixtures/pre_experiment/pre_setup_mock.py +8 -0
  60. experimaestro/tests/launchers/bin/test.py +1 -0
  61. experimaestro/tests/launchers/test_slurm.py +9 -9
  62. experimaestro/tests/partial_reschedule.py +46 -0
  63. experimaestro/tests/restart.py +3 -3
  64. experimaestro/tests/restart_main.py +1 -0
  65. experimaestro/tests/scripts/notifyandwait.py +1 -0
  66. experimaestro/tests/task_partial.py +38 -0
  67. experimaestro/tests/task_tokens.py +2 -2
  68. experimaestro/tests/tasks/test_dynamic.py +6 -6
  69. experimaestro/tests/test_dependencies.py +3 -3
  70. experimaestro/tests/test_deprecated.py +15 -15
  71. experimaestro/tests/test_dynamic_locking.py +317 -0
  72. experimaestro/tests/test_environment.py +24 -14
  73. experimaestro/tests/test_experiment.py +171 -36
  74. experimaestro/tests/test_identifier.py +25 -25
  75. experimaestro/tests/test_identifier_stability.py +3 -5
  76. experimaestro/tests/test_multitoken.py +2 -4
  77. experimaestro/tests/{test_subparameters.py → test_partial.py} +25 -25
  78. experimaestro/tests/test_partial_paths.py +81 -138
  79. experimaestro/tests/test_pre_experiment.py +219 -0
  80. experimaestro/tests/test_progress.py +2 -8
  81. experimaestro/tests/test_remote_state.py +1132 -0
  82. experimaestro/tests/test_stray_jobs.py +261 -0
  83. experimaestro/tests/test_tasks.py +1 -2
  84. experimaestro/tests/test_token_locking.py +52 -67
  85. experimaestro/tests/test_tokens.py +5 -6
  86. experimaestro/tests/test_transient.py +225 -0
  87. experimaestro/tests/test_workspace_state_provider.py +768 -0
  88. experimaestro/tests/token_reschedule.py +1 -3
  89. experimaestro/tests/utils.py +2 -7
  90. experimaestro/tokens.py +227 -372
  91. experimaestro/tools/diff.py +1 -0
  92. experimaestro/tools/documentation.py +4 -5
  93. experimaestro/tools/jobs.py +1 -2
  94. experimaestro/tui/app.py +459 -1895
  95. experimaestro/tui/app.tcss +162 -0
  96. experimaestro/tui/dialogs.py +172 -0
  97. experimaestro/tui/log_viewer.py +253 -3
  98. experimaestro/tui/messages.py +137 -0
  99. experimaestro/tui/utils.py +54 -0
  100. experimaestro/tui/widgets/__init__.py +23 -0
  101. experimaestro/tui/widgets/experiments.py +468 -0
  102. experimaestro/tui/widgets/global_services.py +238 -0
  103. experimaestro/tui/widgets/jobs.py +972 -0
  104. experimaestro/tui/widgets/log.py +156 -0
  105. experimaestro/tui/widgets/orphans.py +363 -0
  106. experimaestro/tui/widgets/runs.py +185 -0
  107. experimaestro/tui/widgets/services.py +314 -0
  108. experimaestro/tui/widgets/stray_jobs.py +528 -0
  109. experimaestro/utils/__init__.py +1 -1
  110. experimaestro/utils/environment.py +105 -22
  111. experimaestro/utils/fswatcher.py +124 -0
  112. experimaestro/utils/jobs.py +1 -2
  113. experimaestro/utils/jupyter.py +1 -2
  114. experimaestro/utils/logging.py +72 -0
  115. experimaestro/version.py +2 -2
  116. experimaestro/webui/__init__.py +9 -0
  117. experimaestro/webui/app.py +117 -0
  118. experimaestro/{server → webui}/data/index.css +66 -11
  119. experimaestro/webui/data/index.css.map +1 -0
  120. experimaestro/{server → webui}/data/index.js +82763 -87217
  121. experimaestro/webui/data/index.js.map +1 -0
  122. experimaestro/webui/routes/__init__.py +5 -0
  123. experimaestro/webui/routes/auth.py +53 -0
  124. experimaestro/webui/routes/proxy.py +117 -0
  125. experimaestro/webui/server.py +200 -0
  126. experimaestro/webui/state_bridge.py +152 -0
  127. experimaestro/webui/websocket.py +413 -0
  128. {experimaestro-2.0.0b4.dist-info → experimaestro-2.0.0b17.dist-info}/METADATA +8 -9
  129. experimaestro-2.0.0b17.dist-info/RECORD +219 -0
  130. experimaestro/cli/progress.py +0 -269
  131. experimaestro/scheduler/state.py +0 -75
  132. experimaestro/scheduler/state_db.py +0 -388
  133. experimaestro/scheduler/state_sync.py +0 -834
  134. experimaestro/server/__init__.py +0 -467
  135. experimaestro/server/data/index.css.map +0 -1
  136. experimaestro/server/data/index.js.map +0 -1
  137. experimaestro/tests/test_cli_jobs.py +0 -615
  138. experimaestro/tests/test_file_progress.py +0 -425
  139. experimaestro/tests/test_file_progress_integration.py +0 -477
  140. experimaestro/tests/test_state_db.py +0 -434
  141. experimaestro-2.0.0b4.dist-info/RECORD +0 -181
  142. /experimaestro/{server → webui}/data/1815e00441357e01619e.ttf +0 -0
  143. /experimaestro/{server → webui}/data/2463b90d9a316e4e5294.woff2 +0 -0
  144. /experimaestro/{server → webui}/data/2582b0e4bcf85eceead0.ttf +0 -0
  145. /experimaestro/{server → webui}/data/89999bdf5d835c012025.woff2 +0 -0
  146. /experimaestro/{server → webui}/data/914997e1bdfc990d0897.ttf +0 -0
  147. /experimaestro/{server → webui}/data/c210719e60948b211a12.woff2 +0 -0
  148. /experimaestro/{server → webui}/data/favicon.ico +0 -0
  149. /experimaestro/{server → webui}/data/index.html +0 -0
  150. /experimaestro/{server → webui}/data/login.html +0 -0
  151. /experimaestro/{server → webui}/data/manifest.json +0 -0
  152. {experimaestro-2.0.0b4.dist-info → experimaestro-2.0.0b17.dist-info}/WHEEL +0 -0
  153. {experimaestro-2.0.0b4.dist-info → experimaestro-2.0.0b17.dist-info}/entry_points.txt +0 -0
  154. {experimaestro-2.0.0b4.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,181 +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=HyWx2o7EdD14LPtqK_PB12S5bv01Ve1GDVbJadPGzCY,712
24
- experimaestro/xpmutils.py,sha256=S21eMbDYsHfvmZ1HmKpq5Pz5O-1HnCLYxKbyTBbASyQ,638
25
- experimaestro/cli/__init__.py,sha256=ZtU5lBsB9MwLFHvEMFipRTpCv-lOYx0JOEUWqbiG-E8,13595
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=5_cNzQk6FotHeHUIl7b1zS5JRyGcoQ58gB8BCEbbvcE,13169
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=3s47to-rd4QxlcSbPHAoSkJEo7DgQ1HJGX9dwTE1JG8,27456
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=44cjCFvyW0C6bwhuNOoKPR5HUzYCv6m0t7xPTjBRMxM,20803
70
- experimaestro/scheduler/interfaces.py,sha256=z5EzL_ghMyuvAKCSaYwPAZB_hpX6OCe95L1I7sD7Bp0,15262
71
- experimaestro/scheduler/jobs.py,sha256=h04Vj595zxvpgvJOr-3wK_rFBvVmlYqO68gq1euI4vc,15634
72
- experimaestro/scheduler/services.py,sha256=B0JYKD3FW6SMeMOA9i46vogz-gT_p3Jr_2c8wKcPv8c,8246
73
- experimaestro/scheduler/signal_handler.py,sha256=B4ZeSVB8O41VDdFmV4n2cyBds7wKFG3kH2Fp7cpyxa4,872
74
- experimaestro/scheduler/state.py,sha256=1ICn1K5gNMCEUb85vwwXLIUF6Lxqa5mbTgMzEz2pnXw,2367
75
- experimaestro/scheduler/state_db.py,sha256=x9x1Z5qgOGrz8TzzDIVMG2IBV_FK6i-oTY_z73yBT6U,13768
76
- experimaestro/scheduler/state_provider.py,sha256=fus4F5Jrxrpg7rABqciyAGc5cf6JzpWTxFPCwXsVClI,80730
77
- experimaestro/scheduler/state_sync.py,sha256=4X0WRqSXhyFNn57eSxvGZByioNw9U-vNdlsn132zGRk,32375
78
- experimaestro/scheduler/workspace.py,sha256=hIASgxGQtrlN4oPFDqDYXTVnxDbngirGdDyAJxJq4vg,3815
79
- experimaestro/server/__init__.py,sha256=BXLPcDRy7Bxx0xk24SF8OthvcE_rk7Afx7yVvgYvM2o,15920
80
- experimaestro/sphinx/__init__.py,sha256=DhFRj8MxA9XZH-TCnbl_5bYhGiF4ihiuFwQj74oPEp4,9466
81
- experimaestro/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
- experimaestro/tests/conftest.py,sha256=9LT2rPsMUZOejUzeazL6IQRJhoM3VbhG2_oOVhZ6Hto,3757
83
- experimaestro/tests/definitions_types.py,sha256=nMoQxZxhTJAYV87Ce9F2dAITxXGHf7Uw5j-MKsZ3LmQ,399
84
- experimaestro/tests/identifier_stability.json,sha256=ygb6p1e8RsjGoqvGoW02ftFCCZIXAZIBsDZjP0Zsdhg,3791
85
- experimaestro/tests/restart.py,sha256=aAizVLvw2DaNfIzuRB13iYXOoX1Q5NkgsngumERlo2s,4191
86
- experimaestro/tests/restart_main.py,sha256=iAFzw0H1q9Aq7t6TrSAj236QBnYU52qx0VF-2dz6tx4,295
87
- experimaestro/tests/task_tokens.py,sha256=vgqUa-S_YC2Id9pGOSv40qFTwq1WGZkFhr556Z5o678,477
88
- experimaestro/tests/test_checkers.py,sha256=e6Rv2TlePRY__VXs0vUb6a5Aw_KIq_cs4N86VhnYHtw,407
89
- experimaestro/tests/test_cli_jobs.py,sha256=pz9X6oaYaZD4aczbOJEKpEpA9UU8KfJrROFN1MU1K7I,19349
90
- experimaestro/tests/test_dependencies.py,sha256=LvpmMcfnRzQPzUIuFNCIQnJot8YBSxCA827xh9gYlq0,1890
91
- experimaestro/tests/test_deprecated.py,sha256=SWuc37o9E-9VsWnwNQBHWiWHdn4syeVTouMSPWyqhww,20061
92
- experimaestro/tests/test_environment.py,sha256=HEIV4OIBaPdGnqi8bdqkwucc2Ezr-VMnNUiA2qYVIHE,6923
93
- experimaestro/tests/test_experiment.py,sha256=Nfevu_aMyX4c5xTjDHMeKXZWs2HMOhy96tsQlnF-IVs,1693
94
- experimaestro/tests/test_file_progress.py,sha256=uNUUq-ptcnxu56zRvUUZ5EYM9ZIQbUmOU_LI0roMgSw,15119
95
- experimaestro/tests/test_file_progress_integration.py,sha256=IsRwhcNWgTRXD6pum19K0HXptxOu8Qm5zulKCZBtBPQ,16758
96
- experimaestro/tests/test_findlauncher.py,sha256=KPy8ow--NXS1KFCIpxrmEJFRvjo-v-PwlVHVyoVKLPg,3134
97
- experimaestro/tests/test_forward.py,sha256=UYYmFl3N4icoA024ubKmCq_vngrGK2aBthfFptIX66U,786
98
- experimaestro/tests/test_generators.py,sha256=R0UypTzxX0dPYvY4A_kozpLDHhGzQDNfLQyc0oRaSx8,2891
99
- experimaestro/tests/test_identifier.py,sha256=oPqCqAIXGsjkXF3-UNtltbFSHRJREUpo-hx2r4Oz5dg,26776
100
- experimaestro/tests/test_identifier_stability.py,sha256=GgfXC-DFIKrA9uTT0-Zm3B2SkbB1llNS2Ls6o4eKvQ4,12572
101
- experimaestro/tests/test_instance.py,sha256=CZ49fjEIvbiJCb-GdDRSt7kP48JnpZUk1GvSvXNb1Bc,1376
102
- experimaestro/tests/test_multitoken.py,sha256=md2egK58goaHmXNP030GECvTOSG-03LqyTZDyREOKkk,14446
103
- experimaestro/tests/test_mypy.py,sha256=wtcPd8vCn7mCyMo5-DCaOEYZS9IARw3IGa-C4ezGKxs,11900
104
- experimaestro/tests/test_objects.py,sha256=YVOfdWjAieFTWQFqm9Q6RFg8rBgNmP8_PXXmkX_RLMA,9988
105
- experimaestro/tests/test_outputs.py,sha256=wO53O6yWVT2sBlRXHTgsv_9i_Y8X5-JnOVfrExQSw2M,826
106
- experimaestro/tests/test_param.py,sha256=cmCvzpCGSNpcFAI2lfIQe2lTYBfxO8gr5I0SVXiNafQ,7346
107
- experimaestro/tests/test_partial_paths.py,sha256=XiYJsqP8IFW-gypvWBrXziMBBk3naXJp2-0OnEgKoUQ,9066
108
- experimaestro/tests/test_progress.py,sha256=Baz2z749CWmMauldMxfMr8A77w3lRNr8eDpsPn317sc,5968
109
- experimaestro/tests/test_resumable_task.py,sha256=H5plRfuQ7bhWzP9TQgGAxm6-GlbtPOTLm9WMZhvRUZ0,17080
110
- experimaestro/tests/test_serializers.py,sha256=DWe3gbaQP16tQawDz8uSiDpQ_nyTuYjFMvoGEwIWfhU,5302
111
- experimaestro/tests/test_snippets.py,sha256=rojnyDjtmAMnSuDUj6Bv9XEgdP8oQf2nVc132JF8vsM,3081
112
- experimaestro/tests/test_ssh.py,sha256=KS1NWltiXrJBSStY9d4mwrexeqgNGWmhxuAU_WLQDAU,1449
113
- experimaestro/tests/test_state_db.py,sha256=tnvyTkzttV3CQ0xAeWaj9F_jthxkb4-QQ94ky3eA-xk,14173
114
- experimaestro/tests/test_subparameters.py,sha256=mDDwPK-KlaZBf0uStxLOhxKElxhp_7mb1DYNJ02yfvg,5792
115
- experimaestro/tests/test_tags.py,sha256=VTjowJljm8sCGiEuOIDeoNO4NPJNY1pu4b7G8dWqBes,6596
116
- experimaestro/tests/test_tasks.py,sha256=E4LWKR_6N4bD0iONeGHQ24c4iNcXsp8l1f4jnwq0MH4,9104
117
- experimaestro/tests/test_token_locking.py,sha256=Le8dAlQEoiDHK2_c_rMGsUlCMpjuBsLUkN4qHzz_9wk,7009
118
- experimaestro/tests/test_tokens.py,sha256=KfpReZCC2MuxNiPPD8addl84arhN16OugrGs6tuuyPo,8075
119
- experimaestro/tests/test_types.py,sha256=AavpWOtwQTVp5IuzfwRskBU4khoeomXXizhZoeSVPp4,4724
120
- experimaestro/tests/test_validation.py,sha256=tinkXETcAGtgPIsmbioKSU00kGIV1YnniHTGDDcUOq8,4118
121
- experimaestro/tests/test_workspace_triggers.py,sha256=idXnS95CBNmTj3YajWS93ZCZfVzOffne2hcMIwmEd2w,4700
122
- experimaestro/tests/token_reschedule.py,sha256=CL3IrCyPfPRJXxC1kTbx8_QO0qUnesJd8u0gPfyCatA,1794
123
- experimaestro/tests/utils.py,sha256=nwG1FfXsceWxnhAwG6XWL4aDCTaH5FqxYcjG74mJOks,3805
124
- experimaestro/tests/connectors/test_local.py,sha256=hMX3maYYRABGXqRZFZbTWjf-jcvPkBq9nReLtDwLydk,1204
125
- experimaestro/tests/connectors/utils.py,sha256=9sM3Pwy2nRfSr7pwQoOoSCDhBrEcDsEElI08Fmrw_gU,702
126
- experimaestro/tests/connectors/bin/executable.py,sha256=RmCrH_MQiHuPRyeTP2jut0ASpfvHEH1QCxRnlvDZW2s,21
127
- experimaestro/tests/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
128
- experimaestro/tests/core/test_generics.py,sha256=oRKSmmofWBwnL2DgUtILSuzjgaTd7Y3EeN003Me9SQk,5214
129
- experimaestro/tests/launchers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
130
- experimaestro/tests/launchers/common.py,sha256=WqVcWX3g0XYJS0aJO7XWVvOmncRBbQmGvuNxH9AHUAE,2998
131
- experimaestro/tests/launchers/test_local.py,sha256=4oGgWH2YgkEm-Muu6s4cwlgriXtYr5xAd72DVoIw_Yk,717
132
- experimaestro/tests/launchers/test_slurm.py,sha256=IRg9B4lpbRmx5u1vkCA9FlSbqlXCyf74_VV6AAil4Xw,5968
133
- experimaestro/tests/launchers/bin/sacct,sha256=hSrYRbwQBB0vY-Bn_FWvuU1xEXAv5G3fTUGglRpyv74,788
134
- experimaestro/tests/launchers/bin/sbatch,sha256=iaek9dgAFeEs927QOQQcWkCIkXL-6PFsTSk4qjIx9ZQ,1780
135
- experimaestro/tests/launchers/bin/srun,sha256=3oE3qq0UFpVtTvXfR1kH3tovFYX74fp1Fk-o8zgsaJA,47
136
- experimaestro/tests/launchers/bin/test.py,sha256=MbxdAd2Sf7T-Hj3ldmrtngbQuBdNOkXjMcICJTf39wI,477
137
- experimaestro/tests/launchers/config_slurm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
138
- experimaestro/tests/launchers/config_slurm/launchers.py,sha256=DohwQVv1eXWfDpAYFg7KJekEm7q7G-lMou2lPg-PKOk,838
139
- experimaestro/tests/scripts/notifyandwait.py,sha256=3BLXLI5XgP3BnKf6sQ56oKoMVqR80VMHmploJ3JO6Ko,407
140
- experimaestro/tests/scripts/waitforfile.py,sha256=EDT-TuFi2fU_qt51K5EmAxjw_OnJKkBW7UCfhrtDbVw,120
141
- experimaestro/tests/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
142
- experimaestro/tests/tasks/all.py,sha256=2KF0D1CB2PBwM_aXX09Ug6vy0MUQgoTATdheNeNKXHg,2101
143
- experimaestro/tests/tasks/foreign.py,sha256=uhXDOcWozkcm26ybbeEU9RElJpbhjC-zdzmlSKfPcdY,122
144
- experimaestro/tests/tasks/test_dynamic.py,sha256=NNw6IgZ8-LTmjsTU7cekb1YvQxbU4oFBj-Bbyc2Ir98,7984
145
- experimaestro/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
146
- experimaestro/tools/diff.py,sha256=mrI9QlZAVgMOGfyz3ryQT9wu5JBn9ndAiVk_EpCh0m4,3711
147
- experimaestro/tools/documentation.py,sha256=O2UzjzodPqGot3YSe6NYlK7S42XpplakUdqxFpvjqHQ,9184
148
- experimaestro/tools/jobs.py,sha256=63bXhJ7RGdczLU_nxu2skGn-9dwgr4r5pD23qH4WeBA,3516
149
- experimaestro/tui/__init__.py,sha256=BTf7I5HtG7AA_vGTSG891Jjz4R3wf-cEnpaEwB6xBA4,197
150
- experimaestro/tui/app.py,sha256=isheCcyJXn_HsHwJ66o-SPs-A--xpqWRQQ90Kcvqr3U,86349
151
- experimaestro/tui/log_viewer.py,sha256=TFybc1LsCjbaC5sUQ8WMAwP6Uzy92GknpEmYx1u0csI,6938
152
- experimaestro/utils/__init__.py,sha256=iuBQw4lZT9Z4BIfQg0Yl9JHdbPgkSvkTH24xREeGHiI,3113
153
- experimaestro/utils/asyncio.py,sha256=9r_vFQs6T6tqmymC_DbHVFhY9YVRO6X48uEuyL_ugP8,726
154
- experimaestro/utils/environment.py,sha256=G_sxSsFK1sZg-nfLwNxVTUT3uq_PnEm7wio8vk0rYpk,5051
155
- experimaestro/utils/git.py,sha256=l2jcqRIgSygg5ZtrlFE9w5hsS4gr2Zca4I5OGmAwMdo,3830
156
- experimaestro/utils/jobs.py,sha256=42FAdKcn_v_-M6hcQZPUBr9kbDt1eVsk3a4E8Gc4eu8,2394
157
- experimaestro/utils/jupyter.py,sha256=JcEo2yQK7x3Cr1tNl5FqGMZOICxCv9DwMvL5xsWdQPk,2183
158
- experimaestro/utils/multiprocessing.py,sha256=am3DkHP_kmWbpynbck2c9QystCUtPBoSAC0ViBVzndU,1275
159
- experimaestro/utils/resources.py,sha256=I0UPGMhQ_bttWt5JJLs1r-CmQsCHwtbmYjUN8JJLFKg,1317
160
- experimaestro/utils/settings.py,sha256=jpFMqF0DLL4_P1xGal0zVR5cOrdD8O0Y2IOYvnRgN3k,793
161
- experimaestro/server/data/1815e00441357e01619e.ttf,sha256=gIRDrmyCBDla3YVD2oqQpguTdvsPh-2OjqN9EJWW2AU,210792
162
- experimaestro/server/data/2463b90d9a316e4e5294.woff2,sha256=qnWZhiOjkeYcaQF5Ss6DLj7N0oi1bWCPIb6gQRrMC44,158220
163
- experimaestro/server/data/2582b0e4bcf85eceead0.ttf,sha256=0vBZNUCw4zum3iVaVPJy1GbjEUSAaVa-qM_b9-3_yb0,426112
164
- experimaestro/server/data/89999bdf5d835c012025.woff2,sha256=40VtEoO511M3p3Pf0Ue_kI_QLAG0v0hXbYYDppsTy-U,25472
165
- experimaestro/server/data/914997e1bdfc990d0897.ttf,sha256=VM9ghve7IfnQcq1JShm0aB-lFt0KFM7lLaAdNlGpE6M,68064
166
- experimaestro/server/data/c210719e60948b211a12.woff2,sha256=1yNqGb8jy7ICcoDo9R3JnWxFl2ou1g3nM4KwNLGKK2g,118684
167
- experimaestro/server/data/favicon.ico,sha256=PRD32mxgMXg0AIFmjErFs66XQ8qaJiqw_NMS-7n0i90,3870
168
- experimaestro/server/data/index.css,sha256=ZNllclp0hcPGTwVgQrGPBGwTPBIts67w6tv_sJmqmEI,389472
169
- experimaestro/server/data/index.css.map,sha256=Wn4xr1Z8udeDGmmPaPb8XKB9967i8n-Eio5jmATjljk,571740
170
- experimaestro/server/data/index.html,sha256=LcXSo2QU5jcmqgmFhVWWOG_CfGyrqdm3H8jwkdRgdGU,706
171
- experimaestro/server/data/index.js,sha256=pt168t9gDsG4cqaBryVyRABgaiUMf8xBQZGxivLqPcI,3717503
172
- experimaestro/server/data/index.js.map,sha256=B_YbANsrKUNXMQe3JH1Jhl5ZMxo6ynVm463TnMxlo4g,3911206
173
- experimaestro/server/data/login.html,sha256=4dvhSOn6DHp_tbmzqIKrqq2uAo0sAUbgLVD0lTnPp4s,511
174
- experimaestro/server/data/manifest.json,sha256=EpzHQZzrGh9c1Kf63nrqvI33H1cm0nLYfdh5lDm8ijI,318
175
- experimaestro/tui/app.tcss,sha256=KsNvixGexmGld19ztBm-Nt5IH0gbclykfYgblP38Wy4,4556
176
- experimaestro/sphinx/static/experimaestro.css,sha256=0rEgt1LoDdD-a_R5rVfWZ19zD1gR-1L7q3f4UibIB58,294
177
- experimaestro-2.0.0b4.dist-info/METADATA,sha256=AO2Y5aUTbMtg2R4iIbhmDRBibqP5KdWFug_LDrYPZXA,6959
178
- experimaestro-2.0.0b4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
179
- experimaestro-2.0.0b4.dist-info/entry_points.txt,sha256=S6AkrX0dM7MWcV-6QN6bazCcL18QAb-uyvmhtlI5hFI,440
180
- experimaestro-2.0.0b4.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
181
- experimaestro-2.0.0b4.dist-info/RECORD,,
File without changes
File without changes
File without changes
File without changes