.local() calls do not create tasks.
Live progress
lazycloud run and .remote() called from your machine show the same live
display: image build, source upload, task status, and the cloud container’s
stdout and stderr, followed by a summary. A failed step keeps its recent logs on screen.
When output is redirected, build logs print without live redraws.
Progress and logs go to stderr. The CLI prints the result to stdout, and Python
returns it to the caller. output(enabled=False) silences the display in
Python:
with output():. Silencing output leaves exceptions and stored logs intact.
Lifecycle
A task isqueued until a container picks it up, then running. If an
attempt fails and retries remain, the same task is queued again until its
retry delay passes. It ends as succeeded, failed, or cancelled; a task
that ran past its timeout is failed with a timeout failure.
Why a task is pending
After five seconds pending, the CLI and dashboard show the reason: compute is starting, the container is starting, every container is busy, the workspace is at its compute limit, an input call has not finished, or a retry delay is running. If “every container is busy” lasts longer than a container start, the workload is at itsmax_containers. See Scaling.
Your own code receives the same reason through lazycloud.progress():
None when the reason clears. For a call submitted with
.spawn(), read call.task.pending_progress.
Look up a task from Python
handle.get(timeout_seconds=120) returns the value or raises on failure, and
handle.logs() reads stored logs. From another process, reconnect by ID:
task.cancel() cancels pending work.
Look up a task from the CLI
flush=True makes lines appear
as they happen. The task and logs reference lists every
command, and the dashboard’s Tasks page shows the same history.
Callbacks
Functions, endpoints, ASGI apps, and realtime handlers acceptcallback_url.
LazyCloud calls that webhook with execution events as the task changes state,
so another system can react without polling. Endpoints and ASGI apps call it
once per request after the response ends, with the request’s status code and
response size; task_id is the request’s X-Request-Id.
Each callback is a JSON POST with the task’s status, attempt_number,
max_attempts, error and finished_at. data carries the result up to
256 KiB: a call made with JSON arguments, such as lazycloud --json run, gets
{"encoding": "json", "value": ...}, and a call from Python’s .remote() or
.spawn() gets the pickled bytes with their encoding. Larger results set
data_omitted instead.
A delivery gets 5 seconds and three tries, 250 ms and 750 ms apart, and
retries on network errors, 408, 425, 429 and any 5xx. Idempotency-Key stays
the same across tries of one event, so a receiver can drop repeats. A receiver
that scales to zero may miss the first event while it starts.
Verify a callback
X-Task-Signature is a hex HMAC-SHA256, keyed by the workspace secret
LAZYCLOUD_CALLBACK_SIGNING_KEY, of the base64-encoded body, a colon and the
X-Task-Timestamp header in Unix seconds. LazyCloud creates the secret with
the first delivery. A receiver that lists it in secrets= needs it to exist
before deploying, so create it yourself with a random whsec_ value first.
