Four v2 features — job control + observability. Fully backward compatible: the SQLite schema migrates in place on first start (existing jobs default to copies=1, carry no callback, and never re-fire webhooks).
Added
- Job copies —
POST /jobsacceptscopies(integer1–100, default1); the agent prints the job that many times, on every backend (win32print / SumatraPDF / CUPS / raw socket). - Job cancel —
DELETE /jobs/{id}cancels a still-queuedjob →cancelled(409once an agent has claimed it — no mid-print interrupt,404if unknown). Cancel button on queued rows in the dashboard. - Webhooks — set a per-job
callback_url; the server POSTs the outcome{job_id, state, error, title, printer_id}once the job reaches a terminal state (done/failed/cancelled). Best-effort with retries, at-least-once (make your handler idempotent — dedupe onjob_id+state), unsigned,http(s)-only. GET /metrics— Prometheus text:printpapi_jobs{state=…}(all five states),printpapi_agents_online/_total,printpapi_printers_total. Client-auth; scrape with a bearer token.
Notes
- 101 tests (was 67), green on Linux + Windows / Python 3.12.
- Each feature was adversarially reviewed; every confirmed finding fixed.
- Docker image built by this release:
ghcr.io/lukiprince/printpapi:1.1.0and:latest(amd64 + arm64).
Full changelog: v1.0.0...v1.1.0