Skip to main content

warpswarm (Python)

On-demand human judgment for AI evaluation and labeling. Submit items, get aggregated human answers back.

pip install warpswarm
export WARPSWARM_API_KEY=ws_live_...     # ws_test_... = free sandbox, no charges
import warpswarm as ws

client = ws.Client()

job = client.compare(
    "Summary A/B",
    "Which summary is more accurate?",
    [(summary_a[i], summary_b[i]) for i in range(100)],   # (a, b) pairs: text, Path, URL or asset id
    answers=5,                                           # answers per item
)                                                         # budget defaults to items × answers × the job's price
job.add_gold([(("Paris is in France.", "Paris is in Spain."), "a")])  # optional known-answer checks
job.start().wait(on_progress=print)

for r in job.results():
    print(r.external_id, r.aggregate.winner, r.aggregate.votes, r.confidence)
job.export("results.csv", format="csv")

Task types

helper items result.aggregate
compare(name, q, pairs, allow_tie=False) (a, b) CompareAggregate(winner, votes)
classify(name, q, items, labels, multi_select=False) text or media ClassifyAggregate(label, votes) / MultiClassifyAggregate(labels, share)
free_text(name, q, items, min_chars, max_chars) text or media FreeTextAggregate(texts)
locate(name, q, images) image LocateAggregate(point, points)
draw(name, q, images, max_boxes=20) image DrawAggregate(boxes)
select_words(name, q, texts) text, ≤ 40 words SelectWordsAggregate(words, tokens, share)
ranking(name, q, option_sets) lists of 2–5 options RankingAggregate(ranking, borda)

Coordinates are fractions of the image (0–1), x, y = top-left. Media can be a string (text), a pathlib.Path or bytes (uploaded once), an http(s) URL (imported), an ast_… id, or an Asset. Any item can also be a full dict with context (e.g. the prompt) and external_id (your own id, returned on every result).

Gold correct values: compare "a"|"b"|"tie" · classify "label" or [labels] · free_text "text" · locate a region (x, y, w, h) (any tap inside passes) · draw [(x, y, w, h), …] · select_words [index] or ["word", …] · ranking [index, best first].

Lifecycle and pricing

draft → start() → queued → running → completed. start() holds credit for the job's budget; unused credit is released at the end, and only accepted answers are charged.

  • Price per 1,000 answers. $10 base; $13 compare with images; $18 any job with video; $50 free_text. client.estimate(task_type, n, answers, media=["video"]) returns it; job.price_per_answer_micros shows it.

  • Phases. job.progress.phase is waiting_for_workers → in_review → collecting → done. wait() polls at most once a minute before workers start and every poll_interval s while collecting.

  • Minimum size. A job needs at least 25 items (ws.MIN_DATAPOINTS); smaller jobs raise JobTooSmallError.

  • Unsold tail. Workers answer 22 of your items per page, plus 3 check questions we add and pay for. If a small remainder can't fill a page at the end, it can't be staffed: the job completes, progress.answers_unsold says how many, and they are never charged.

Webhooks

Pass webhook_url="https://…" when creating a job to get job.started, job.progress, job.completed, job.cancelled and job.failed POSTs instead of polling. job.webhook_secret is returned once, at creation, so store it.

event = ws.verify_webhook(request.body, request.headers["Warpswarm-Signature"], secret)   # raw body bytes
if event.type == "job.completed":
    job = client.job(event.job_id)

verify_webhook checks the HMAC and rejects timestamps older than 5 minutes (ws.WebhookSignatureError). Retries reuse event.id, so dedupe on it. Any 2xx acknowledges; failures are retried for 24 h.

Errors

All errors subclass ws.WarpswarmError (.status, .code, .param): AuthenticationError, NotFoundError, InvalidRequestError, JobTooSmallError, InvalidStateError, InsufficientCreditError, RateLimitError, ServerError, plus WaitTimeout / JobFailed from wait(). Every POST carries an Idempotency-Key, so the SDK retries network errors, 429 and 5xx safely.

Other calls

client.account(), client.estimate(task_type, n, answers), client.upload(path), client.upload_url(url), client.jobs(status=), client.job(id), job.preview_url() (see the exact worker form), job.pause()/resume()/cancel(), job.results(include_answers=True) (each answer with a pseudonymous annotator), client.checkout_url(amount_usd).

Development

uv venv .venv && uv pip install -e . pytest pyyaml openapi-schema-validator
pytest tests/test_unit.py            # offline; every request body is validated against ../../api/openapi.yaml
# full loop, all 7 types (local wrangler dev + worker/tests/mock/mw_mock.py on :8799):
WS_BASE=http://localhost:8787 WS_ADMIN=… WS_SEED="npx wrangler d1 execute warpswarm --local --command" pytest tests/test_integration.py
# prod, read + draft lifecycle only (no workers, no charges):
WS_BASE=https://api.warpswarm.app WS_TEST_KEY=ws_test_… pytest tests/test_integration.py -k prod
uv build                             # dist/warpswarm-0.1.0-py3-none-any.whl

Release files for warpswarm 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for warpswarm 0.2.1
File Size Uploaded
warpswarm-0.2.1.tar.gz 23.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for warpswarm 0.2.1
File Interpreter ABI Platform
warpswarm-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 42.1 kB

Release files / warpswarm-0.2.1.tar.gz

Download URL warpswarm-0.2.1.tar.gz
Size 23.7 kB
Tags Source
SHA-256 checksum
How to use checksums
236898a85e7d15c56a3f212ef3b5e7c8c6957abeeb5c0e70b2f1a2083fa74430
BLAKE2b-256 checksum
How to use checksums
6db085383b1c4e6a26b38c38e298231a4afcd8b43688b7b86801586ad8d0865a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.18 {"installer":{"name":"uv","version":"0.12.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / warpswarm-0.2.1-py3-none-any.whl

Download URL warpswarm-0.2.1-py3-none-any.whl
Size 18.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e35a26ac2718f6cf2ff429af65967c4781074c5a918bfaa8acb79255504be110
BLAKE2b-256 checksum
How to use checksums
0830542632581ba2e4f561af4c890c3662c7ee091f65f1ec0bec791dd5fb14b4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.18 {"installer":{"name":"uv","version":"0.12.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files

0.2.0

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page