Polling long-running jobs
Mapping jobs, test runs, and load tests run asynchronously on the server. Because API-key callers can't subscribe to WebSocket events, each resource that supports long-running work exposes a blocking helper that polls the GET endpoint until the job reaches a terminal state.
Basic usage - mapping job
from nopaque import Nopaque
client = Nopaque()
job = client.mapping.create(
name="Main IVR",
phone_number="+441234567890",
mapping_mode="dtmf",
)
client.mapping.start(job.id)
final = client.mapping.wait_for_complete(job.id)
print(final.status)Basic usage - test run
Test runs use wait_for_run / waitForRun (same name as batches and sweeps). Mapping and load testing use wait_for_complete / waitForComplete. The helper returns the final run document.
# Run a test directly from a config and wait for it.
run = client.testing.runs.create(test_config_id="cfg_abc123")
final = client.testing.runs.wait_for_run(run.id)
print(final.status) # "completed" | "failed" | "cancelled"Options
timeout- overall deadline (default 10 min).poll_interval/pollInterval- initial delay (default 5s). The SDK softens this exponentially up to 15s during long jobs to avoid hammering the API.on_update/onUpdate- callback invoked on every poll with the current job document (useful for progress logging).
final = client.mapping.wait_for_complete(
job.id,
timeout=900.0, # seconds, raises NopaqueTimeoutError if exceeded
poll_interval=5.0, # initial seconds between polls
on_update=lambda j: print(j.status),
)Showing progress
Because the server returns the full job document on every poll, you can do more than log "still running" - show a heartbeat dot each poll, and surface a label whenever the status transitions (e.g. idle → queued → running → completed). The SDK itself stays silent by default so that scripts with redirected output stay clean; opt in with on_update / onUpdate when you want to show something.
# Emit a dot per poll, plus a label when the status transitions.
last_status = [None]
def progress(j):
if j.status != last_status[0]:
print(f"\n[{j.status}]", end="", flush=True)
last_status[0] = j.status
print(".", end="", flush=True)
final = client.mapping.wait_for_complete(job.id, on_update=progress)
print(f"\ndone: {final.status}")The job document's stats field (where present) also lets you display counts - e.g. j.stats.completed_calls - for richer progress reporting.
Supported resources
| Resource | Method | Terminal statuses |
|---|---|---|
| Mapping job | client.mapping.wait_for_complete | completed, failed, limited |
| Test run | client.testing.runs.wait_for_run | completed, failed, cancelled |
| Batch run | client.batches.wait_for_run | completed, failed, cancelled |
| Sweep run | client.sweeps.wait_for_run | completed, failed, cancelled |
| Load test | client.load_testing.wait_for_complete | completed, aborted, failed |
Timeout behavior
If the deadline is exceeded, the helper raises NopaqueTimeoutError. The job itself is not cancelled - the SDK has no way to know what you want to do. If you need to abandon the job, call the resource's explicit cancel (mapping) or abort (load testing) method in your except/catch block.