CLI
Run and save notebooks with the CLI
Insert and run live notebook cells, inspect outputs, and recover detached runs.
Work with a live notebook
The project Jupyter commands inspect and edit the live notebook without requiring
an open browser tab. Use them instead of rewriting .ipynb JSON while CoCalc
is editing the document. This recipe inserts one cell in an existing scratch
notebook, runs it, inspects its output, and saves it.
Step 1: Select the notebook and confirm its kernel
In Bash, use the profile from the quickstart, the full project ID, and an existing scratch notebook with a Python kernel:
export CLI_PROFILE=cocalc-ai
export PROJECT_ID='REPLACE_WITH_FULL_PROJECT_ID'
export NOTEBOOK_PATH='/home/user/scratch/cli-demo.ipynb'
cocalc --profile "$CLI_PROFILE" project get --project "$PROJECT_ID"
cocalc --profile "$CLI_PROFILE" --json project jupyter kernel \
--project "$PROJECT_ID" --path "$NOTEBOOK_PATH"
cocalc --profile "$CLI_PROFILE" --json project jupyter cells \
--project "$PROJECT_ID" --path "$NOTEBOOK_PATH"
Use the absolute remote notebook path, adjusting /home/user if needed;
relative notebook paths resolve against the CLI computer's home directory.
Confirm the project, path, kernel, and existing cells. cells includes each
cell's full input. Use project jupyter --help to inspect your version's commands.
Step 2: Insert and run one cell
Run this insertion once:
cocalc --profile "$CLI_PROFILE" --json project jupyter insert \
--project "$PROJECT_ID" --path "$NOTEBOOK_PATH" \
--at-end --type code --input 'print(2 + 3)'
Copy data.cell.id into CELL_ID, then run that cell:
export CELL_ID='REPLACE_WITH_RETURNED_CELL_ID'
cocalc --profile "$CLI_PROFILE" --json project jupyter run \
--project "$PROJECT_ID" --path "$NOTEBOOK_PATH" \
--cell-id "$CELL_ID"
Require successful command completion, ok:true, and data.error_count:0.
This command follows execution by default. --jsonl is a different, streaming
output format; do not parse it as one JSON result.
For a noisy cell, add --limit 40 to that same run command to limit output
initially streamed by the backend. The limit must be a positive integer; it is
not a row count, a calculation limit, or a bound on the saved result file.
In a followed JSON run, data.more_output_count counts additional-output
notifications, not omitted rows. Inspect the retained cell output and independently
validate complete files as described in
Keep complete results when output is limited.
A zero error count alone does not establish scientific correctness or completeness.
Step 3: Inspect output and save
cocalc --profile "$CLI_PROFILE" --json project jupyter outputs \
--project "$PROJECT_ID" --path "$NOTEBOOK_PATH" \
--cell-id "$CELL_ID"
cocalc --profile "$CLI_PROFILE" --json project jupyter save \
--project "$PROJECT_ID" --path "$NOTEBOOK_PATH"
The selected cell's output should contain 5; saving should report
data.saved:true. outputs --cell-id returns that cell's input, output, and
metadata. Inspect this read-back rather than inferring notebook contents from
successful command submission alone.
Prefer cell IDs when retaining selections across commands. Cell indexes are zero-based and can shift when collaborators insert or move cells. IDs identify cells but do not lock their contents.
Follow a long run after disconnecting
For long-running code, replace the run command in step 2 with a detached
submission; do not execute both unless you intend to run the cell twice:
cocalc --profile "$CLI_PROFILE" --json project jupyter run \
--project "$PROJECT_ID" --path "$NOTEBOOK_PATH" \
--cell-id "$CELL_ID" --detach
Retain data.run_id as RUN_ID. Detach waits for a backend acknowledgment,
not completion. Follow that exact run:
export RUN_ID='REPLACE_WITH_RETURNED_RUN_ID'
cocalc --profile "$CLI_PROFILE" --json project jupyter live \
--project "$PROJECT_ID" --path "$NOTEBOOK_PATH" \
--run-id "$RUN_ID" --timeout 20m
Require the matching data.run_id, data.follow:true, successful command
completion, and data.error_count:0; then inspect outputs and save. The live
command can return cell errors without setting a failing process exit code.
--no-follow only retrieves the available snapshot and cannot establish completion.
If following times out or disconnects, inspect the retained run before submitting another one. Without an explicit ID, selection prefers a currently running run, then the most recently updated retained run; it may not be the run you started.
--allow-errors relaxes the following run command's error-exit rule. It does
not make erroneous output successful or guarantee that later cells execute.
Detached or noninteractive code should not depend on answering kernel input prompts.
For JavaScript notebook scripts, inspect project jupyter exec --help. Consume
the run's output iterator, check errors, and release its client handle with
run.close() in finally. Closing a handle does not interrupt the kernel.
Use project jupyter interrupt deliberately to interrupt work; it affects the
notebook kernel, not just one local CLI waiter.