labnotes 0.0.131__tar.gz → 0.0.133__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.131 → labnotes-0.0.133}/PKG-INFO +1 -1
- labnotes-0.0.133/src/labnotes/__init__.py +6 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/context.md +12 -0
- labnotes-0.0.133/src/labnotes/get_state.py +15 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/execute_run.py +10 -1
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/run_experiment.py +32 -19
- labnotes-0.0.133/src/labnotes/set_state.py +11 -0
- labnotes-0.0.133/src/labnotes/state_path.py +18 -0
- labnotes-0.0.131/src/labnotes/__init__.py +0 -4
- {labnotes-0.0.131 → labnotes-0.0.133}/.gitignore +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/CHANGELOG.md +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/MIGRATIONS.md +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/README.md +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/pyproject.toml +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/__main__.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/asset_url.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/check_counts.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/cli.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/compose_experiment.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/context_guide.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/count_groups.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/count_runs.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/create_app.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/create_experiment.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/create_note.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/daemon/__init__.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/daemon/control_run.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/daemon/daemon_app.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/daemon/daemon_client.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/daemon/daemon_running.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/daemon/daemon_server.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/daemon/describe_status.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/daemon/ensure_daemon.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/daemon/exit_when_idle.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/daemon/finalize_lost_runs.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/daemon/last_stderr.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/daemon/remote_start.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/daemon/run_daemon.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/daemon/run_logs.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/daemon/serve_daemon.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/daemon/socket_path.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/daemon/stop_runs.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/daemon/watch_daemon.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/daemon/watch_status.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/daemon_command.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/data_html.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/default_config_text.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/default_counts.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/drain_watch.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/experiment_notes.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/experiment_runs.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/experiments.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/file_changes.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/format_duration.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/format_started.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/format_value.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/grid_cell.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/group_runs.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/init.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/invocation_started.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/is_non_negative_int.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/is_non_negative_number.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/is_positive_int.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/list_experiments.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/list_runs.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/load_config.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/load_experiment.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/load_run.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/log.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/log_path.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/memory_interval.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/models.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/modes.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/nests_runs.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/note_path.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/notebook_kernel.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/output_html.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/parse_run_view.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/parse_subset.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/pivot_runs.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/print_rows.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/python_blocks.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/read_config.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/read_path.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/render_markdown.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/retries.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/run_command.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/run_control.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/run_output.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/run_status.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/__init__.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/cgroup_memory.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/check_args.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/check_subset.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/container_cgroup.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/container_memory.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/describe_event.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/docker_output.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/exit_signal.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/fill_dirs.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/fill_experiment_env.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/flag_name.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/hold_folder.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/hook_dirs.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/in_subset.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/invocation_hook.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/invocation_meta.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/new_param_run_id.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/new_run_id.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/new_stamped_run_id.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/param_args.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/param_grid.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/param_run_name.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/plan_runs.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/prepare_experiment.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/read_experiment_config.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/record_memory.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/run_folder.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/run_headless.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/runs_parent.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/shell_command.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/signal_tree.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/stop_then_kill.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/wait_for_tree.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runner/write_run_json.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/runs_view_command.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/save_conflict_copy.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/save_note.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/saved_outputs.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/serve_app.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/server.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/shared_params.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/sort_href.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/sql_quote.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/static/elapsed.js +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/static/experiment.js +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/static/labnotes.css +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/static/local-time.js +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/static/new-note.js +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/static/note-edit.js +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/static/note-editor.js +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/static/row-link.js +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/static/run-cell.js +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/static/run-output.js +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/static/view-toggle.js +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/summarize_config.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/__init__.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/experiment_rows.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/experiment_run_ids.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/experiment_toml.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/experiments_ddl.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/file_prefix.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/file_text.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/iso_time.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/list_experiment_runs.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/note_text.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/open_tables.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/path_glob.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/path_pattern.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/read_blocks.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/read_experiment.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/read_file.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/read_log.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/read_memory.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/read_run.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/read_run_file.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/runs_columns.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tables/summarize_experiments.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/templates/base.html +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/templates/editor_imports.html +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/templates/experiment.html +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/templates/index.html +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/templates/note.html +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/templates/run.html +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/__init__.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/browse_app.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/browse_tui.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/check_view_response.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/config.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/dim.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/experiment_screen.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/experiments_screen.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/fill_table.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/format_cell.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/format_elapsed.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/group_cells.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/invocation_columns.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/invocation_rows.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/leave_prompt.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/log_block.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/log_blocks.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/native_rows.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/reload_on_change.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/run_app.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/run_cells.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/run_output.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/run_screen.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/run_tui.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/runs_table.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/runs_view.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/stopped_title.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/view_column.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/tui/view_process.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/utils/__init__.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/utils/format_bytes.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/utils/process_alive.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/utils/run_usage.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/utils/tree_rss.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/utils/tree_usage.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/view/__init__.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/view/answer.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/view/build.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/view/respond.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/view/serve.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/wait_for_note.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/src/labnotes/watch_rows.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/testing-conventions.toml +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/tests/integration/conftest.py +0 -0
- {labnotes-0.0.131 → labnotes-0.0.133}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: labnotes
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.133
|
|
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>
|
|
@@ -103,6 +103,18 @@ run is planned. That folder exists before setup starts. In matrix mode with
|
|
|
103
103
|
several runs there is no shared folder, so `{invocation_dir}` in a hook fails.
|
|
104
104
|
`{run_dir}` is never filled in hooks; use `{invocation_dir}` instead. An
|
|
105
105
|
unavailable placeholder fails before anything starts.
|
|
106
|
+
Setup can call `labnotes.set_state({"container": "abc"})`; runs and teardown read the
|
|
107
|
+
dict with `labnotes.get_state()`. Writes merge by top-level key, replacing an
|
|
108
|
+
existing value without dropping other keys. Values must be JSON serializable;
|
|
109
|
+
reading before any write returns `{}`. Runs can only read: `set_state` raises
|
|
110
|
+
`RuntimeError` there. Both functions raise outside an invocation and in `meta`.
|
|
111
|
+
Labnotes gives setup/teardown `LABNOTES_STATE` and runs `LABNOTES_RUN_STATE`,
|
|
112
|
+
pointing to `{invocation_dir}/state.json` or, without a shared folder, a temp
|
|
113
|
+
file kept through all runs and teardown and then removed. Queued runs and retries
|
|
114
|
+
read the same file after setup finishes. `meta` receives neither state variable;
|
|
115
|
+
state is never copied into `run.json`.
|
|
116
|
+
Nested labnotes invocations clear inherited `LABNOTES_*` context for their
|
|
117
|
+
children and set their own hook and run variables.
|
|
106
118
|
`[env]` in `experiment.toml` sets string environment values for `command`,
|
|
107
119
|
`meta`, `setup`, and `teardown`. `[experiment.env]` in `.labnotes.toml`
|
|
108
120
|
provides shared values; experiment values replace them by name. Variables in
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
from labnotes.state_path import state_path
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def get_state() -> dict[str, object]:
|
|
7
|
+
"""Read setup's invocation state from a hook or run command."""
|
|
8
|
+
path = state_path()
|
|
9
|
+
try:
|
|
10
|
+
state = json.loads(path.read_text(encoding="utf-8"))
|
|
11
|
+
except FileNotFoundError:
|
|
12
|
+
return {}
|
|
13
|
+
if not isinstance(state, dict):
|
|
14
|
+
raise ValueError("Invocation state must be a JSON object")
|
|
15
|
+
return state
|
|
@@ -14,6 +14,7 @@ from labnotes.runner.shell_command import shell_command
|
|
|
14
14
|
from labnotes.runner.stop_then_kill import GRACE_SECONDS
|
|
15
15
|
from labnotes.runner.wait_for_tree import wait_for_tree
|
|
16
16
|
from labnotes.runner.write_run_json import write_run_json
|
|
17
|
+
from labnotes.state_path import RUN_STATE_ENV
|
|
17
18
|
from labnotes.tables.iso_time import iso_time
|
|
18
19
|
from labnotes.tui.format_elapsed import format_elapsed
|
|
19
20
|
|
|
@@ -33,6 +34,7 @@ async def execute_run(
|
|
|
33
34
|
meta: dict[str, object] | None = None,
|
|
34
35
|
args: Sequence[str] = (),
|
|
35
36
|
*,
|
|
37
|
+
state_file: Path,
|
|
36
38
|
memory_interval: float,
|
|
37
39
|
environment: dict[str, str] | None = None,
|
|
38
40
|
) -> dict[str, object]:
|
|
@@ -65,9 +67,16 @@ async def execute_run(
|
|
|
65
67
|
env={
|
|
66
68
|
"FORCE_COLOR": "1",
|
|
67
69
|
"CLICOLOR_FORCE": "1",
|
|
68
|
-
**
|
|
70
|
+
**{
|
|
71
|
+
key: value
|
|
72
|
+
for key, value in (
|
|
73
|
+
os.environ if environment is None else environment
|
|
74
|
+
).items()
|
|
75
|
+
if not key.startswith("LABNOTES_")
|
|
76
|
+
},
|
|
69
77
|
LOG_ENV: str(folder / "log.jsonl"),
|
|
70
78
|
RUN_ENV: str(folder.resolve()),
|
|
79
|
+
RUN_STATE_ENV: str(state_file),
|
|
71
80
|
},
|
|
72
81
|
stdout=stdout,
|
|
73
82
|
stderr=stderr,
|
|
@@ -2,7 +2,9 @@ import asyncio
|
|
|
2
2
|
import json
|
|
3
3
|
import os
|
|
4
4
|
import signal
|
|
5
|
+
from contextlib import nullcontext
|
|
5
6
|
from pathlib import Path
|
|
7
|
+
from tempfile import TemporaryDirectory
|
|
6
8
|
|
|
7
9
|
import psutil
|
|
8
10
|
|
|
@@ -27,6 +29,7 @@ from labnotes.runner.param_grid import param_grid
|
|
|
27
29
|
from labnotes.runner.plan_runs import plan_runs
|
|
28
30
|
from labnotes.runner.run_folder import run_folder
|
|
29
31
|
from labnotes.runner.signal_tree import signal_tree
|
|
32
|
+
from labnotes.state_path import STATE_ENV
|
|
30
33
|
from labnotes.tables.experiment_run_ids import experiment_run_ids
|
|
31
34
|
from labnotes.tables.list_experiment_runs import list_experiment_runs
|
|
32
35
|
from labnotes.tables.open_tables import open_tables
|
|
@@ -263,6 +266,7 @@ async def run_experiment(
|
|
|
263
266
|
stopped=lambda: run in stopped,
|
|
264
267
|
meta=meta,
|
|
265
268
|
args=args or (),
|
|
269
|
+
state_file=state_file,
|
|
266
270
|
memory_interval=experiment.memory_interval,
|
|
267
271
|
environment=fill_experiment_env(
|
|
268
272
|
experiment.env,
|
|
@@ -293,24 +297,33 @@ async def run_experiment(
|
|
|
293
297
|
)
|
|
294
298
|
|
|
295
299
|
listen(Controls(interrupt, set_concurrency, kill, finish))
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
if
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
hook_env[
|
|
305
|
-
|
|
306
|
-
fill()
|
|
307
|
-
await done.wait()
|
|
308
|
-
await asyncio.gather(*started)
|
|
309
|
-
except BaseException:
|
|
300
|
+
with (
|
|
301
|
+
nullcontext(dirs["invocation_dir"])
|
|
302
|
+
if dirs
|
|
303
|
+
else TemporaryDirectory(prefix="labnotes-state-")
|
|
304
|
+
) as state_dir:
|
|
305
|
+
state_file = Path(state_dir) / "state.json"
|
|
306
|
+
for hook in ("setup", "teardown"):
|
|
307
|
+
if hook in hook_env:
|
|
308
|
+
hook_env[hook][STATE_ENV] = str(state_file)
|
|
309
|
+
# Like vitest's globalSetup: a failed setup still gets its teardown.
|
|
310
310
|
try:
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
311
|
+
if experiment.setup is not None:
|
|
312
|
+
report({"event": "setting up"})
|
|
313
|
+
await invocation_hook(
|
|
314
|
+
config.root,
|
|
315
|
+
"setup",
|
|
316
|
+
fill_dirs(experiment.setup, dirs),
|
|
317
|
+
hook_env["setup"],
|
|
318
|
+
)
|
|
319
|
+
fill()
|
|
320
|
+
await done.wait()
|
|
321
|
+
await asyncio.gather(*started)
|
|
322
|
+
except BaseException:
|
|
323
|
+
try:
|
|
324
|
+
await teardown()
|
|
325
|
+
except Exception as failure: # noqa: BLE001
|
|
326
|
+
report({"event": "teardown failed", "error": str(failure)})
|
|
327
|
+
raise
|
|
328
|
+
await teardown()
|
|
316
329
|
return results
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
from labnotes.get_state import get_state
|
|
4
|
+
from labnotes.state_path import state_path
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def set_state(values: dict[str, object]) -> None:
|
|
8
|
+
"""Merge setup's JSON state by key for this invocation's teardown."""
|
|
9
|
+
path = state_path(writable=True)
|
|
10
|
+
content = json.dumps({**get_state(), **values})
|
|
11
|
+
path.write_text(content, encoding="utf-8")
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
STATE_ENV = "LABNOTES_STATE"
|
|
5
|
+
RUN_STATE_ENV = "LABNOTES_RUN_STATE"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def state_path(*, writable: bool = False) -> Path:
|
|
9
|
+
value = os.environ.get(STATE_ENV)
|
|
10
|
+
if not value and not writable:
|
|
11
|
+
value = os.environ.get(RUN_STATE_ENV)
|
|
12
|
+
if not value:
|
|
13
|
+
raise RuntimeError(
|
|
14
|
+
"State is only writable in setup and teardown hooks"
|
|
15
|
+
if writable
|
|
16
|
+
else "State is only available in setup, runs, and teardown"
|
|
17
|
+
)
|
|
18
|
+
return Path(value)
|
|
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
|
|
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
|
|
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
|