Cancel an Agent Completion at a deadline: Python poll loop
A Python loop that starts a Sume Agent Completion, polls status_url until next_action stops saying poll_status, and cancels at a deadline.

Start the run, store its status_url and cancel_url, poll until next_action stops being poll_status, and if your deadline passes first, POST the cancel URL and report the run as canceled. The loop below does that with the standard library. Cancel stops a run that is still in flight, so pair the deadline with a generation_spend_cap_usd you would accept spending in full.
The loop
From the Agent Completions docs: create with POST /v1/agent/completions and a required cap, poll the receipt's status_url, and cancel with a POST to the cancel URL. Set SUME_API_KEY in your environment; the key needs agent_completions:write.
import json, os, time, urllib.request
H = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"],
"Content-Type": "application/json"}
def call(url, body=None, method="GET"):
data = json.dumps(body).encode() if body is not None else None
req = urllib.request.Request(url, data=data, method=method, headers=H)
with urllib.request.urlopen(req, timeout=30) as r:
return json.load(r)["data"]
def run_with_deadline(instruction, cap_usd, deadline_s=600):
run = call("https://api.sume.com/v1/agent/completions",
{"instruction": instruction,
"generation_spend_cap_usd": cap_usd}, "POST")
stop = time.monotonic() + deadline_s
delay = 3
while time.monotonic() < stop:
st = call(run["status_url"])
if st.get("next_action") != "poll_status":
return call("https://api.sume.com/v1/agent-runs/" + run["id"])
time.sleep(delay)
delay = min(delay * 1.5, 20)
call(run["cancel_url"], {}, "POST")
return {"id": run["id"], "status": "canceled_by_caller"}Why it is shaped this way
- The docs say to follow the receipt's URLs rather than building them, so the loop uses
status_urlandcancel_urlas returned. - Backoff grows to 20 seconds so a long run does not hammer the status route.
- On a terminal status the final read is the full receipt, where
output,artifactsandusagelive. - No
Idempotency-Keyis sent here for brevity. In production add one so a network retry of the create call returns the same receipt.
What a deadline can and cannot do
A cancel request is a request. A run that has already reached a terminal status has nothing left to cancel. After cancelling, read the run once more and trust the status it reports, not the one your loop assumed.
Also set the deadline above the typical duration of the work. A video task that normally needs ten minutes will always be cut by a 60 second deadline, and the cut run may already have spent part of its cap. Pick the cap first, then a deadline that leaves headroom.
| Status | Meaning | Loop action |
|---|---|---|
queued, processing | Still running | Keep polling with backoff |
completed | Output available | Read output and usage |
failed | Run ended in error | Read error, do not blindly retry |
canceled | Stopped by cancel | Record it and move on |
Where this fits
If you would rather not poll at all, pass a public HTTPS communication.webhook_url and treat polling as the backup; see Run webhooks. Jobs that Sume agents start internally are separate from your run id, and the jobs page covers reading those. Keep keys and signed URLs out of logs, per Safe automation.
Sources
Related posts
More in Developers
- Lazy-load placeholder for an AI image: average color from Sume
Compute the average color of a generated image with Pillow, use it as the background of the image box and avoid a white flash while the real file loads.
- Prompt length limits across Firefly and Sume
Adobe Firefly now takes longer prompts for Image and Video on the web. Sume documents a 5000-character cap for music and no stated cap elsewhere.
- AI image prompt regression test: check size, ratio and alpha in CI
Before you swap or upgrade an image model, run a fixed prompt set through Sume and assert pixel size, aspect ratio and alpha with Pillow. Python test included.
- Responsive srcset widths from one Sume master image with Pillow
Generate one high-resolution image, then resize it into several widths and print the srcset and sizes attributes. Python script for a Sume image result.
Written by Sume