labnotes 0.0.123__tar.gz → 0.0.124__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.123 → labnotes-0.0.124}/PKG-INFO +1 -1
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/daemon/daemon_app.py +2 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/daemon/remote_start.py +2 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/experiments.py +24 -2
- labnotes-0.0.124/src/labnotes/runner/check_args.py +15 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/execute_run.py +5 -2
- labnotes-0.0.124/src/labnotes/runner/flag_name.py +4 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/prepare_experiment.py +4 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/run_experiment.py +2 -0
- labnotes-0.0.124/src/labnotes/runner/shell_command.py +12 -0
- labnotes-0.0.123/src/labnotes/runner/shell_command.py +0 -9
- {labnotes-0.0.123 → labnotes-0.0.124}/.gitignore +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/CHANGELOG.md +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/MIGRATIONS.md +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/README.md +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/pyproject.toml +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/__init__.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/__main__.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/asset_url.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/check_counts.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/cli.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/compose_experiment.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/context.md +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/context_guide.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/count_groups.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/count_runs.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/create_app.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/create_experiment.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/create_note.py +0 -0
- {labnotes-0.0.123/src/labnotes/utils → labnotes-0.0.124/src/labnotes/daemon}/__init__.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/daemon/control_run.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/daemon/daemon_client.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/daemon/daemon_running.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/daemon/daemon_server.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/daemon/describe_status.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/daemon/ensure_daemon.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/daemon/exit_when_idle.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/daemon/finalize_lost_runs.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/daemon/last_stderr.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/daemon/run_daemon.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/daemon/run_logs.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/daemon/serve_daemon.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/daemon/socket_path.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/daemon/stop_runs.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/daemon/watch_daemon.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/daemon/watch_status.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/daemon_command.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/data_html.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/default_config_text.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/default_counts.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/drain_watch.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/experiment_notes.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/experiment_runs.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/file_changes.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/format_duration.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/format_started.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/format_value.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/grid_cell.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/group_runs.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/init.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/invocation_started.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/is_non_negative_int.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/is_non_negative_number.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/is_positive_int.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/list_experiments.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/list_runs.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/load_config.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/load_experiment.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/load_run.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/log.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/log_path.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/memory_interval.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/models.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/modes.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/nests_runs.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/note_path.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/notebook_kernel.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/output_html.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/parse_run_view.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/parse_subset.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/pivot_runs.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/print_rows.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/python_blocks.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/read_config.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/read_path.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/render_markdown.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/retries.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/run_command.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/run_control.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/run_output.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/run_status.py +0 -0
- {labnotes-0.0.123/src/labnotes/tui → labnotes-0.0.124/src/labnotes/runner}/__init__.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/check_subset.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/describe_event.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/exit_signal.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/hold_folder.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/in_subset.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/invocation_meta.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/new_param_run_id.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/new_run_id.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/new_stamped_run_id.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/param_args.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/param_grid.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/param_run_name.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/plan_runs.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/read_experiment_config.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/record_memory.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/run_folder.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/run_headless.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/runs_parent.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/signal_tree.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/stop_then_kill.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/wait_for_tree.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runner/write_run_json.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/runs_view_command.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/save_conflict_copy.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/save_note.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/saved_outputs.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/serve_app.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/server.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/shared_params.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/sort_href.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/sql_quote.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/static/elapsed.js +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/static/experiment.js +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/static/labnotes.css +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/static/local-time.js +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/static/new-note.js +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/static/note-edit.js +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/static/note-editor.js +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/static/row-link.js +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/static/run-cell.js +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/static/run-output.js +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/static/view-toggle.js +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/summarize_config.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/__init__.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/experiment_rows.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/experiment_run_ids.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/experiment_toml.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/experiments_ddl.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/file_prefix.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/file_text.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/iso_time.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/list_experiment_runs.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/note_text.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/open_tables.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/path_glob.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/path_pattern.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/read_blocks.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/read_experiment.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/read_file.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/read_log.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/read_memory.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/read_run.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/read_run_file.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/runs_columns.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tables/summarize_experiments.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/templates/base.html +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/templates/editor_imports.html +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/templates/experiment.html +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/templates/index.html +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/templates/note.html +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/templates/run.html +0 -0
- {labnotes-0.0.123/src/labnotes/runner → labnotes-0.0.124/src/labnotes/tui}/__init__.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/browse_app.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/browse_tui.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/check_view_response.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/config.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/dim.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/experiment_screen.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/experiments_screen.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/fill_table.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/format_cell.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/format_elapsed.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/group_cells.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/invocation_columns.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/invocation_rows.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/leave_prompt.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/log_block.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/log_blocks.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/native_rows.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/reload_on_change.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/run_app.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/run_cells.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/run_output.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/run_screen.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/run_tui.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/runs_table.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/runs_view.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/stopped_title.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/view_column.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/tui/view_process.py +0 -0
- {labnotes-0.0.123/src/labnotes/daemon → labnotes-0.0.124/src/labnotes/utils}/__init__.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/utils/format_bytes.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/utils/process_alive.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/utils/run_usage.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/utils/tree_rss.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/utils/tree_usage.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/view/__init__.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/view/answer.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/view/build.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/view/respond.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/view/serve.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/wait_for_note.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/src/labnotes/watch_rows.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/testing-conventions.toml +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/tests/integration/conftest.py +0 -0
- {labnotes-0.0.123 → labnotes-0.0.124}/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.124
|
|
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>
|
|
@@ -79,6 +79,7 @@ def daemon_app(config: LabnotesConfig) -> Starlette:
|
|
|
79
79
|
None if path is None else Path(str(path)),
|
|
80
80
|
body.get("concurrency"), # type: ignore[arg-type]
|
|
81
81
|
body.get("only"), # type: ignore[arg-type]
|
|
82
|
+
body.get("args"), # type: ignore[arg-type]
|
|
82
83
|
)
|
|
83
84
|
except ValueError as error:
|
|
84
85
|
return refuse(400, str(error))
|
|
@@ -105,6 +106,7 @@ def daemon_app(config: LabnotesConfig) -> Starlette:
|
|
|
105
106
|
listen,
|
|
106
107
|
body.get("timeout"), # type: ignore[arg-type]
|
|
107
108
|
only=body.get("only"), # type: ignore[arg-type]
|
|
109
|
+
args=body.get("args"), # type: ignore[arg-type]
|
|
108
110
|
)
|
|
109
111
|
# Clients hear why the session ended; the daemon keeps serving.
|
|
110
112
|
except Exception as failure: # noqa: BLE001
|
|
@@ -17,6 +17,7 @@ def remote_start(
|
|
|
17
17
|
concurrency: int | None,
|
|
18
18
|
timeout: float | None = None,
|
|
19
19
|
only: dict[str, str] | None = None,
|
|
20
|
+
args: list[str] | None = None,
|
|
20
21
|
) -> Start:
|
|
21
22
|
async def start(report: Report, listen: Listen) -> list[dict[str, object]]:
|
|
22
23
|
try:
|
|
@@ -48,6 +49,7 @@ def remote_start(
|
|
|
48
49
|
"concurrency": concurrency,
|
|
49
50
|
"timeout": timeout,
|
|
50
51
|
"only": only,
|
|
52
|
+
"args": args,
|
|
51
53
|
},
|
|
52
54
|
)
|
|
53
55
|
if reply.status_code != 202:
|
|
@@ -17,12 +17,25 @@ from labnotes.tui.browse_tui import browse_tui
|
|
|
17
17
|
from labnotes.tui.run_tui import run_tui
|
|
18
18
|
|
|
19
19
|
BYTES = ("memory", "size")
|
|
20
|
+
PASSTHROUGH = "labnotes.passthrough"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class PassthroughCommand(click.Command):
|
|
24
|
+
def parse_args(self, ctx: click.Context, args: list[str]) -> list[str]:
|
|
25
|
+
if "--" in args:
|
|
26
|
+
at = args.index("--")
|
|
27
|
+
ctx.meta[PASSTHROUGH] = args[at + 1 :]
|
|
28
|
+
args = args[:at]
|
|
29
|
+
return super().parse_args(ctx, args)
|
|
20
30
|
|
|
21
31
|
|
|
22
32
|
@click.command(
|
|
33
|
+
cls=PassthroughCommand,
|
|
23
34
|
help="List experiments, show one, list its runs, or run it."
|
|
24
35
|
" `new [NAME]` creates one. With run, --PARAM=VALUE runs only the"
|
|
25
|
-
" matrix cells where that param has that value
|
|
36
|
+
" matrix cells where that param has that value, and anything after --"
|
|
37
|
+
" is appended to every run's command and recorded in run.json, so never"
|
|
38
|
+
" pass secrets there.",
|
|
26
39
|
context_settings={"ignore_unknown_options": True, "allow_extra_args": True},
|
|
27
40
|
)
|
|
28
41
|
@click.argument("name", required=False)
|
|
@@ -63,6 +76,7 @@ def experiments(
|
|
|
63
76
|
experiment_config: Path | None,
|
|
64
77
|
timeout: int | None,
|
|
65
78
|
) -> None:
|
|
79
|
+
passthrough: list[str] | None = ctx.meta.get(PASSTHROUGH)
|
|
66
80
|
config = load_config(ctx)
|
|
67
81
|
if config is None:
|
|
68
82
|
raise click.ClickException(
|
|
@@ -82,7 +96,13 @@ def experiments(
|
|
|
82
96
|
except ValueError as error:
|
|
83
97
|
raise click.UsageError(str(error)) from error
|
|
84
98
|
start = remote_start(
|
|
85
|
-
config,
|
|
99
|
+
config,
|
|
100
|
+
name,
|
|
101
|
+
experiment_config,
|
|
102
|
+
concurrency,
|
|
103
|
+
timeout,
|
|
104
|
+
only,
|
|
105
|
+
passthrough or None,
|
|
86
106
|
)
|
|
87
107
|
try:
|
|
88
108
|
if sys.stdout.isatty() and sys.stderr.isatty():
|
|
@@ -101,6 +121,8 @@ def experiments(
|
|
|
101
121
|
passed = len(results) - failed - retried
|
|
102
122
|
click.echo(f"{passed} passed, {failed} failed.{again}")
|
|
103
123
|
return
|
|
124
|
+
if passthrough is not None:
|
|
125
|
+
raise click.UsageError("-- ARGS needs run.")
|
|
104
126
|
if ctx.args:
|
|
105
127
|
raise click.UsageError(f"Unexpected {ctx.args[0]}. --PARAM=VALUE needs run.")
|
|
106
128
|
if action not in (None, "runs"):
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import shlex
|
|
2
|
+
|
|
3
|
+
from labnotes.runner.flag_name import flag_name
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def check_args(params: dict[str, list[object]], command: str, args: list[str]) -> None:
|
|
7
|
+
taken = {flag_name(token) for token in shlex.split(command)}
|
|
8
|
+
for arg in args:
|
|
9
|
+
name = flag_name(arg)
|
|
10
|
+
if name is None:
|
|
11
|
+
continue
|
|
12
|
+
if name in params:
|
|
13
|
+
raise ValueError(f"--{name} is a param. Pick it with --{name}=VALUE.")
|
|
14
|
+
if name in taken:
|
|
15
|
+
raise ValueError(f"--{name} is already in the command.")
|
|
@@ -2,7 +2,7 @@ import asyncio
|
|
|
2
2
|
import contextlib
|
|
3
3
|
import os
|
|
4
4
|
import time
|
|
5
|
-
from collections.abc import Callable
|
|
5
|
+
from collections.abc import Callable, Sequence
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
|
|
8
8
|
import psutil
|
|
@@ -31,10 +31,11 @@ async def execute_run(
|
|
|
31
31
|
stop: Callable[[], None] = lambda: None,
|
|
32
32
|
stopped: Callable[[], bool] = lambda: False,
|
|
33
33
|
meta: dict[str, object] | None = None,
|
|
34
|
+
args: Sequence[str] = (),
|
|
34
35
|
*,
|
|
35
36
|
memory_interval: float,
|
|
36
37
|
) -> dict[str, object]:
|
|
37
|
-
resolved = shell_command(command, folder, params)
|
|
38
|
+
resolved = shell_command(command, folder, params, args)
|
|
38
39
|
run: dict[str, object] = {
|
|
39
40
|
"params": params,
|
|
40
41
|
"command": resolved,
|
|
@@ -45,6 +46,8 @@ async def execute_run(
|
|
|
45
46
|
"ended_by": None,
|
|
46
47
|
"signal": None,
|
|
47
48
|
}
|
|
49
|
+
if args:
|
|
50
|
+
run["args"] = list(args)
|
|
48
51
|
if retry_of is not None:
|
|
49
52
|
run["retry_of"] = retry_of
|
|
50
53
|
if meta is not None:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
|
|
3
3
|
from labnotes.models import ExperimentConfig, LabnotesConfig
|
|
4
|
+
from labnotes.runner.check_args import check_args
|
|
4
5
|
from labnotes.runner.check_subset import check_subset
|
|
5
6
|
from labnotes.runner.read_experiment_config import read_experiment_config
|
|
6
7
|
from labnotes.tables.file_text import file_text
|
|
@@ -12,6 +13,7 @@ async def prepare_experiment(
|
|
|
12
13
|
experiment_config: Path | None,
|
|
13
14
|
concurrency: int | None,
|
|
14
15
|
only: dict[str, str] | None = None,
|
|
16
|
+
args: list[str] | None = None,
|
|
15
17
|
) -> tuple[ExperimentConfig, int]:
|
|
16
18
|
if config.experiment not in (None, name):
|
|
17
19
|
raise ValueError(
|
|
@@ -33,4 +35,6 @@ async def prepare_experiment(
|
|
|
33
35
|
)
|
|
34
36
|
if only:
|
|
35
37
|
check_subset(experiment.params, only)
|
|
38
|
+
if args:
|
|
39
|
+
check_args(experiment.params, experiment.command, args)
|
|
36
40
|
return experiment, experiment.concurrency if concurrency is None else concurrency
|
|
@@ -38,6 +38,7 @@ async def run_experiment(
|
|
|
38
38
|
timeout: float | None = None,
|
|
39
39
|
retry_seconds: float = RETRY_SECONDS,
|
|
40
40
|
only: dict[str, str] | None = None,
|
|
41
|
+
args: list[str] | None = None,
|
|
41
42
|
) -> list[dict[str, object]]:
|
|
42
43
|
meta = None
|
|
43
44
|
if experiment.meta is not None:
|
|
@@ -220,6 +221,7 @@ async def run_experiment(
|
|
|
220
221
|
stop=lambda: kill(run),
|
|
221
222
|
stopped=lambda: run in stopped,
|
|
222
223
|
meta=meta,
|
|
224
|
+
args=args or (),
|
|
223
225
|
memory_interval=experiment.memory_interval,
|
|
224
226
|
)
|
|
225
227
|
del running[run], trees[run]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import shlex
|
|
2
|
+
from collections.abc import Sequence
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from labnotes.runner.param_args import param_args
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def shell_command(
|
|
9
|
+
command: str, folder: Path, params: dict[str, object], args: Sequence[str] = ()
|
|
10
|
+
) -> str:
|
|
11
|
+
filled = command.replace("{run_dir}", shlex.quote(str(folder)))
|
|
12
|
+
return f"{filled} {shlex.join([*param_args(params), *args])}".rstrip()
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import shlex
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
|
|
4
|
-
from labnotes.runner.param_args import param_args
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def shell_command(command: str, folder: Path, params: dict[str, object]) -> str:
|
|
8
|
-
filled = command.replace("{run_dir}", shlex.quote(str(folder)))
|
|
9
|
-
return f"{filled} {shlex.join(param_args(params))}".rstrip()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|