labnotes 0.0.59__tar.gz → 0.0.60__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. {labnotes-0.0.59 → labnotes-0.0.60}/PKG-INFO +1 -1
  2. labnotes-0.0.60/src/labnotes/runner/new_param_run_id.py +18 -0
  3. labnotes-0.0.60/src/labnotes/runner/param_run_name.py +17 -0
  4. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/runner/run_experiment.py +7 -5
  5. {labnotes-0.0.59 → labnotes-0.0.60}/.gitignore +0 -0
  6. {labnotes-0.0.59 → labnotes-0.0.60}/CHANGELOG.md +0 -0
  7. {labnotes-0.0.59 → labnotes-0.0.60}/MIGRATIONS.md +0 -0
  8. {labnotes-0.0.59 → labnotes-0.0.60}/README.md +0 -0
  9. {labnotes-0.0.59 → labnotes-0.0.60}/pyproject.toml +0 -0
  10. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/__init__.py +0 -0
  11. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/asset_url.py +0 -0
  12. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/cell_progress.py +0 -0
  13. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/check_counts.py +0 -0
  14. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/cli.py +0 -0
  15. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/context.md +0 -0
  16. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/context_guide.py +0 -0
  17. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/count_runs.py +0 -0
  18. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/create_app.py +0 -0
  19. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/create_experiment.py +0 -0
  20. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/data_html.py +0 -0
  21. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/default_config_text.py +0 -0
  22. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/default_counts.py +0 -0
  23. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/drain_watch.py +0 -0
  24. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/experiment_notes.py +0 -0
  25. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/experiment_progress.py +0 -0
  26. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/experiment_runs.py +0 -0
  27. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/experiments.py +0 -0
  28. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/file_changes.py +0 -0
  29. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/format_duration.py +0 -0
  30. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/format_value.py +0 -0
  31. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/group_runs.py +0 -0
  32. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/init.py +0 -0
  33. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/invocation_started.py +0 -0
  34. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/is_positive_int.py +0 -0
  35. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/list_experiments.py +0 -0
  36. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/list_runs.py +0 -0
  37. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/load_config.py +0 -0
  38. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/load_experiment.py +0 -0
  39. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/models.py +0 -0
  40. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/modes.py +0 -0
  41. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/nests_runs.py +0 -0
  42. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/notebook_kernel.py +0 -0
  43. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/output_html.py +0 -0
  44. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/parse_run_view.py +0 -0
  45. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/print_rows.py +0 -0
  46. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/python_blocks.py +0 -0
  47. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/read_config.py +0 -0
  48. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/read_path.py +0 -0
  49. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/render_markdown.py +0 -0
  50. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/runner/__init__.py +0 -0
  51. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/runner/describe_event.py +0 -0
  52. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/runner/execute_run.py +0 -0
  53. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/runner/hold_folder.py +0 -0
  54. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/runner/new_run_id.py +0 -0
  55. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/runner/new_stamped_run_id.py +0 -0
  56. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/runner/param_args.py +0 -0
  57. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/runner/param_grid.py +0 -0
  58. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/runner/plan_runs.py +0 -0
  59. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/runner/read_experiment_config.py +0 -0
  60. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/runner/run_folder.py +0 -0
  61. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/runner/run_headless.py +0 -0
  62. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/runner/runs_parent.py +0 -0
  63. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/runner/shell_command.py +0 -0
  64. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/runner/start_experiment.py +0 -0
  65. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/runner/stop_then_kill.py +0 -0
  66. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/runner/wait_for_group.py +0 -0
  67. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/runner/write_run_json.py +0 -0
  68. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/save_note.py +0 -0
  69. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/saved_outputs.py +0 -0
  70. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/serve_app.py +0 -0
  71. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/server.py +0 -0
  72. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/sort_href.py +0 -0
  73. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/sql_quote.py +0 -0
  74. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/static/experiment.js +0 -0
  75. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/static/labnotes.css +0 -0
  76. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/static/note-edit.js +0 -0
  77. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/static/note-editor.js +0 -0
  78. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/static/row-link.js +0 -0
  79. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/static/run-cell.js +0 -0
  80. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/static/view-toggle.js +0 -0
  81. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/stop_idle_kernels.py +0 -0
  82. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/summarize_config.py +0 -0
  83. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/tables/__init__.py +0 -0
  84. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/tables/experiment_rows.py +0 -0
  85. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/tables/file_prefix.py +0 -0
  86. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/tables/iso_time.py +0 -0
  87. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/tables/list_experiment_runs.py +0 -0
  88. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/tables/open_tables.py +0 -0
  89. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/tables/path_glob.py +0 -0
  90. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/tables/path_pattern.py +0 -0
  91. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/tables/read_experiment.py +0 -0
  92. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/tables/read_file.py +0 -0
  93. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/tables/read_run.py +0 -0
  94. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/tables/summarize_experiments.py +0 -0
  95. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/templates/base.html +0 -0
  96. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/templates/editor_imports.html +0 -0
  97. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/templates/experiment.html +0 -0
  98. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/templates/index.html +0 -0
  99. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/templates/macros.html +0 -0
  100. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/tui/__init__.py +0 -0
  101. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/tui/dim.py +0 -0
  102. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/tui/format_elapsed.py +0 -0
  103. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/tui/run_app.py +0 -0
  104. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/tui/run_tui.py +0 -0
  105. {labnotes-0.0.59 → labnotes-0.0.60}/src/labnotes/tui/runs_table.py +0 -0
  106. {labnotes-0.0.59 → labnotes-0.0.60}/testing-conventions.toml +0 -0
  107. {labnotes-0.0.59 → labnotes-0.0.60}/tests/integration/conftest.py +0 -0
  108. {labnotes-0.0.59 → labnotes-0.0.60}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: labnotes
3
- Version: 0.0.59
3
+ Version: 0.0.60
4
4
  Summary: Browse experiment designs, notes, and run data from a folder.
5
5
  Project-URL: Repository, https://github.com/thekevinscott/labnotes
6
6
  Author-email: Kevin Scott <me@thekevinscott.com>
@@ -0,0 +1,18 @@
1
+ import secrets
2
+ from collections.abc import Callable
3
+
4
+ from labnotes.runner.new_run_id import new_run_id
5
+ from labnotes.runner.param_run_name import param_run_name
6
+
7
+
8
+ def new_param_run_id(
9
+ params: dict[str, object],
10
+ choices: dict[str, list[object]],
11
+ taken: Callable[[str], bool],
12
+ ) -> str:
13
+ name = param_run_name(params, choices)
14
+ if not name:
15
+ return new_run_id(taken)
16
+ while taken(candidate := f"{name}-{secrets.token_hex(2)}"):
17
+ pass
18
+ return candidate
@@ -0,0 +1,17 @@
1
+ import os
2
+ import re
3
+
4
+ UNSAFE = re.compile(r"[^A-Za-z0-9]+")
5
+ LIMIT = 60
6
+
7
+
8
+ def param_run_name(params: dict[str, object], choices: dict[str, list[object]]) -> str:
9
+ parts = []
10
+ for name, values in choices.items():
11
+ if len(values) < 2:
12
+ continue
13
+ shared = os.path.commonprefix([str(value) for value in values])
14
+ cut = re.match(r".*[^A-Za-z0-9]", shared)
15
+ value = str(params[name])[cut.end() if cut else 0 :]
16
+ parts.append(UNSAFE.sub("-", value).strip("-"))
17
+ return "-".join(part for part in parts if part)[:LIMIT].strip("-")
@@ -12,7 +12,7 @@ from labnotes.models import (
12
12
  Report,
13
13
  )
14
14
  from labnotes.runner.execute_run import execute_run
15
- from labnotes.runner.new_run_id import new_run_id
15
+ from labnotes.runner.new_param_run_id import new_param_run_id
16
16
  from labnotes.runner.new_stamped_run_id import new_stamped_run_id
17
17
  from labnotes.runner.param_grid import param_grid
18
18
  from labnotes.runner.plan_runs import plan_runs
@@ -46,16 +46,18 @@ async def run_experiment(
46
46
 
47
47
  group = new_stamped_run_id(taken) if experiment.mode == "adhoc" else None
48
48
 
49
- def new_id() -> str:
49
+ def new_id(params: dict[str, object]) -> str:
50
50
  if group is None:
51
51
  return new_stamped_run_id(taken)
52
- return f"{group}/" + new_run_id(lambda run: taken(f"{group}/{run}"))
52
+ return f"{group}/" + new_param_run_id(
53
+ params, experiment.params, lambda run: taken(f"{group}/{run}")
54
+ )
53
55
 
54
56
  plan: list[Entry] = []
55
57
  for params in plan_runs(
56
58
  param_grid(experiment.params), experiment.repeats, finished
57
59
  ):
58
- run = new_id()
60
+ run = new_id(params)
59
61
  planned.add(run)
60
62
  plan.append((run, params))
61
63
  runs = [{"run": run, "params": params} for run, params in plan]
@@ -137,7 +139,7 @@ async def run_experiment(
137
139
  def retry(run: str) -> None:
138
140
  if stopping.is_set() or run not in ended:
139
141
  return
140
- again = new_id()
142
+ again = new_id(ended[run])
141
143
  planned.add(again)
142
144
  plan.append((again, ended[run]))
143
145
  report({"event": "retried", "run": run, "retry": again, "params": ended[run]})
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes