labnotes 0.0.41__tar.gz → 0.0.43__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {labnotes-0.0.41 → labnotes-0.0.43}/PKG-INFO +1 -1
- {labnotes-0.0.41 → labnotes-0.0.43}/pyproject.toml +1 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/context.md +1 -1
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/tui/run_app.py +10 -2
- {labnotes-0.0.41 → labnotes-0.0.43}/uv.lock +27 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/.gitignore +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/CHANGELOG.md +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/MIGRATIONS.md +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/README.md +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/__init__.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/asset_url.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/cell_progress.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/check_counts.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/cli.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/context_guide.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/count_runs.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/create_app.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/create_experiment.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/data_html.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/default_config_text.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/default_counts.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/drain_watch.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/experiment_notes.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/experiment_progress.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/experiment_runs.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/experiments.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/format_value.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/init.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/list_experiments.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/list_runs.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/load_config.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/load_experiment.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/models.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/notebook_kernel.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/output_html.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/parse_run_view.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/pivot_cells.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/print_rows.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/python_blocks.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/read_config.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/read_path.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/render_markdown.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/runner/__init__.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/runner/describe_event.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/runner/execute_run.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/runner/hold_folder.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/runner/new_invocation_id.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/runner/new_run_id.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/runner/new_stamped_run_id.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/runner/param_args.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/runner/param_grid.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/runner/plan_runs.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/runner/read_experiment_config.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/runner/run_experiment.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/runner/run_folder.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/runner/run_headless.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/runner/runs_parent.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/runner/shell_command.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/runner/start_experiment.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/runner/stop_then_kill.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/runner/wait_for_group.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/runner/write_run_json.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/saved_outputs.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/serve_app.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/server.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/sort_href.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/sql_quote.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/static/labnotes.css +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/static/row-link.js +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/static/run-cell.js +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/static/view-toggle.js +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/stop_idle_kernels.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/summarize_config.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/tables/__init__.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/tables/experiment_rows.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/tables/file_prefix.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/tables/iso_time.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/tables/list_experiment_runs.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/tables/open_tables.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/tables/path_glob.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/tables/path_pattern.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/tables/read_experiment.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/tables/read_file.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/tables/read_run.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/tables/summarize_experiments.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/templates/base.html +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/templates/experiment.html +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/templates/index.html +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/templates/macros.html +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/tui/__init__.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/tui/dim.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/tui/format_elapsed.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/src/labnotes/tui/run_tui.py +0 -0
- {labnotes-0.0.41 → labnotes-0.0.43}/testing-conventions.toml +0 -0
|
@@ -56,7 +56,7 @@ effort = ["low", "high"]
|
|
|
56
56
|
`name` is optional: a display name for the experiment, shown in the live view
|
|
57
57
|
and as `display_name` in `experiments`. The folder name stays the key, so
|
|
58
58
|
renaming the experiment means editing `name`.
|
|
59
|
-
Each combination of `[params]` runs `repeats` times, round-robin, on every
|
|
59
|
+
Each combination of `[params]` runs `repeats` times (1 if omitted), round-robin, on every
|
|
60
60
|
`run`, whatever is already on disk. That is `mode = "adhoc"`, the default.
|
|
61
61
|
`mode = "fill"` counts what is there: only runs that count fill a combination,
|
|
62
62
|
so running again fills in what failed or never ran.
|
|
@@ -17,7 +17,8 @@ from labnotes.tui.format_elapsed import format_elapsed
|
|
|
17
17
|
|
|
18
18
|
COLUMNS = ("run", "params", "status", "time")
|
|
19
19
|
OTHER_STREAM = {"stdout": "stderr", "stderr": "stdout"}
|
|
20
|
-
PENDING,
|
|
20
|
+
PENDING, PASSED, FAILED = "○", "✓", "✗"
|
|
21
|
+
SPINNER = "|/-\\"
|
|
21
22
|
SKIPPED, DESELECTED = "–", "⊘"
|
|
22
23
|
|
|
23
24
|
|
|
@@ -56,6 +57,7 @@ class RunApp(App[None]):
|
|
|
56
57
|
self.idle = False
|
|
57
58
|
self.next_run: str | None = None
|
|
58
59
|
self.ended: set[str] = set()
|
|
60
|
+
self.frame = 0
|
|
59
61
|
self.started: dict[str, float] = {}
|
|
60
62
|
self.pending: set[str] = set()
|
|
61
63
|
self.cells: dict[str, list[object]] = {}
|
|
@@ -82,6 +84,7 @@ class RunApp(App[None]):
|
|
|
82
84
|
table.add_column(column, key=column)
|
|
83
85
|
self.query_one(Input).display = False
|
|
84
86
|
self.query_one(Log).display = False
|
|
87
|
+
table.set_interval(0.1, self.spin)
|
|
85
88
|
|
|
86
89
|
def on_ready(self) -> None:
|
|
87
90
|
self.set_interval(1, self.tick)
|
|
@@ -120,7 +123,7 @@ class RunApp(App[None]):
|
|
|
120
123
|
if run == self.next_run:
|
|
121
124
|
self.show("")
|
|
122
125
|
args = " ".join(param_args(event["params"])) # type: ignore[arg-type]
|
|
123
|
-
cells = (run, args,
|
|
126
|
+
cells = (run, args, SPINNER[self.frame], format_elapsed(0))
|
|
124
127
|
for column, cell in zip(COLUMNS, cells):
|
|
125
128
|
self.set_cell(run, column, cell)
|
|
126
129
|
case "ended":
|
|
@@ -205,6 +208,11 @@ class RunApp(App[None]):
|
|
|
205
208
|
for run, began in self.started.items():
|
|
206
209
|
self.set_cell(run, "time", format_elapsed(time.monotonic() - began))
|
|
207
210
|
|
|
211
|
+
def spin(self) -> None:
|
|
212
|
+
self.frame = (self.frame + 1) % len(SPINNER)
|
|
213
|
+
for run in self.started:
|
|
214
|
+
self.set_cell(run, "status", SPINNER[self.frame])
|
|
215
|
+
|
|
208
216
|
def show(self, text: str) -> None:
|
|
209
217
|
self.next_run = None
|
|
210
218
|
self.query_one("#status", Static).update(text)
|
|
@@ -223,6 +223,19 @@ wheels = [
|
|
|
223
223
|
{ url = "https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417", size = 7294, upload-time = "2025-07-25T14:02:02.896Z" },
|
|
224
224
|
]
|
|
225
225
|
|
|
226
|
+
[[package]]
|
|
227
|
+
name = "curtaincall"
|
|
228
|
+
version = "0.3.0"
|
|
229
|
+
source = { registry = "https://pypi.org/simple" }
|
|
230
|
+
dependencies = [
|
|
231
|
+
{ name = "pexpect" },
|
|
232
|
+
{ name = "pyte" },
|
|
233
|
+
]
|
|
234
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ca/12/056a3c89fcbc135b15a7cef872472a73bdad3594ddfccbe11b9a028b2f5f/curtaincall-0.3.0.tar.gz", hash = "sha256:afc9e9ce00a256982d69a737976527d38217082ca79fcafcf381fa2cd2bba041", size = 68784, upload-time = "2026-02-16T01:44:39.874Z" }
|
|
235
|
+
wheels = [
|
|
236
|
+
{ url = "https://files.pythonhosted.org/packages/f8/52/1092ca83246b88a880f2fe35e38919b9e069c0ce97708880c4234ab72c32/curtaincall-0.3.0-py3-none-any.whl", hash = "sha256:4a754fa4a8ad726a00ec24ebb545f8f5a34a0f8d159936845d125bfeb2dfb652", size = 21504, upload-time = "2026-02-16T01:44:38.567Z" },
|
|
237
|
+
]
|
|
238
|
+
|
|
226
239
|
[[package]]
|
|
227
240
|
name = "debugpy"
|
|
228
241
|
version = "1.8.22"
|
|
@@ -477,6 +490,7 @@ dependencies = [
|
|
|
477
490
|
|
|
478
491
|
[package.dev-dependencies]
|
|
479
492
|
dev = [
|
|
493
|
+
{ name = "curtaincall" },
|
|
480
494
|
{ name = "httpx2" },
|
|
481
495
|
{ name = "mypy" },
|
|
482
496
|
{ name = "pytest" },
|
|
@@ -500,6 +514,7 @@ requires-dist = [
|
|
|
500
514
|
|
|
501
515
|
[package.metadata.requires-dev]
|
|
502
516
|
dev = [
|
|
517
|
+
{ name = "curtaincall", specifier = ">=0.3.0" },
|
|
503
518
|
{ name = "httpx2", specifier = ">=2.13.1" },
|
|
504
519
|
{ name = "mypy", specifier = ">=2.4.0" },
|
|
505
520
|
{ name = "pytest", specifier = ">=8.0" },
|
|
@@ -984,6 +999,18 @@ wheels = [
|
|
|
984
999
|
{ url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf20a04a028a21ec746d942f8d2af30fa0f124fa0e6a684/pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9", size = 1250147, upload-time = "2026-08-17T08:02:44.912Z" },
|
|
985
1000
|
]
|
|
986
1001
|
|
|
1002
|
+
[[package]]
|
|
1003
|
+
name = "pyte"
|
|
1004
|
+
version = "0.8.2"
|
|
1005
|
+
source = { registry = "https://pypi.org/simple" }
|
|
1006
|
+
dependencies = [
|
|
1007
|
+
{ name = "wcwidth" },
|
|
1008
|
+
]
|
|
1009
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ab/ab/b599762933eba04de7dc5b31ae083112a6c9a9db15b01d3109ad797559d9/pyte-0.8.2.tar.gz", hash = "sha256:5af970e843fa96a97149d64e170c984721f20e52227a2f57f0a54207f08f083f", size = 92301, upload-time = "2023-11-12T09:33:43.217Z" }
|
|
1010
|
+
wheels = [
|
|
1011
|
+
{ url = "https://files.pythonhosted.org/packages/59/d0/bb522283b90853afbf506cd5b71c650cf708829914efd0003d615cf426cd/pyte-0.8.2-py3-none-any.whl", hash = "sha256:85db42a35798a5aafa96ac4d8da78b090b2c933248819157fc0e6f78876a0135", size = 31627, upload-time = "2023-11-12T09:33:41.096Z" },
|
|
1012
|
+
]
|
|
1013
|
+
|
|
987
1014
|
[[package]]
|
|
988
1015
|
name = "pytest"
|
|
989
1016
|
version = "9.1.1"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|