What are Hooks?
The Werk24 API is asynchronous: lightweight results (like Page Thumbnails) are ready very quickly (≈ 300–500 ms), while heavy analyses (e.g., AskInsights) may take longer (up to \~50 s for complex drawings).
To keep your integration simple, Werk24 provides Hooks. A Hook ties a specific Ask (the what you want) to a function (the what to do when it’s ready). When the requested data becomes available, your function is called with the result—no polling loops needed on your side.
Key Concepts
-
Ask A declarative request for a specific artifact (e.g.,
W24AskPageThumbnail,W24AskVariantMeasures). You may register many Asks per file. -
Hook A (ask, function) pair. The function runs once per matching result. Hooks are evaluated independently—fast results arrive first.
-
Asynchrony Results are produced and delivered as they’re ready. There’s no guaranteed order between different Asks.
-
Idempotency Your functions should tolerate duplicates (e.g., on client restarts). Write hooks so re-execution doesn’t break anything.
Typical Latencies (Guidance)
- Page Thumbnail: 0.3–0.5 s
- Metadata: \~4–10 s
- Features: \~6–15 s (complexity-dependent)
- Insights: \~6–25 s (complexity-dependent)
These are not SLAs, just planning numbers to design UX and timeouts.
Delivery & Ordering Guarantees
- Each Hook fires as soon as its Ask is ready.
- Hooks for different Asks are independent and may fire in any order.
- If a failure occurs for a given Ask, you’ll receive an error (see below).
- Avoid shared mutable state between hook functions unless you protect it.
Example: Using Hooks in Python
Suppose you want to (i) save a page thumbnail and (ii) print extracted measures.
This setup triggers save_file as soon as the thumbnail is available, and print_measures when measures arrive.
End-to-End Sketch (Upload + Hooks + Run)
Tip: Keep hook functions fast. If you do I/O or heavy post-processing, hand off to a worker queue so you don’t block other callbacks.
Designing Good Hooks
-
Idempotent Safe to call more than once (e.g., check if file exists before writing; use upserts).
-
Stateless or isolated state Keep per-file state keyed by a stable ID to avoid cross-talk.
-
Non-blocking Offload long work. Hooks should act like interrupt handlers: quick, reliable, minimal.
-
Defensive Validate payload shape; tolerate missing optional fields.
Backpressure & Concurrency
- If you register many Hooks across many files, your own callback work can become the bottleneck.
-
Use a thread pool or async queue to keep callbacks snappy:
-
CPU-bound →
concurrent.futures.ThreadPoolExecutororProcessPoolExecutor - I/O-bound →
asyncio.create_task+ boundedasyncio.Semaphore
FAQs
Do Hooks guarantee order? No. Each Hook fires when its Ask is ready. Don’t rely on ordering.
Can I run multiple Hooks for the same Ask? Yes—register multiple Hooks targeting the same Ask if you need to fan out actions (e.g., save + notify).
How do I limit callback fan-out? Wrap heavy logic in a queue/worker with bounded concurrency; keep the Hook handler tiny.
What if I only want the first page thumbnail? Scope your Ask accordingly (e.g., page index parameters if available). Otherwise, discard in the callback.
Can I correlate results back to my upload? Yes. Use stable identifiers (upload ID, filename, or a client-side UUID) passed along in your closure or captured in your hook function.
Best-Practice Checklist
- [ ] Separate Asks (what you need) from Hooks (what to do).
- [ ] Keep Hook functions idempotent and fast.
- [ ] Expect out-of-order arrivals; don’t share mutable state.
- [ ] Handle errors explicitly; log and retry where it’s safe.
- [ ] Use queues/executors for heavy post-processing.
- [ ] Provide great UX: show the thumbnail first, stream progress, reveal heavy results when ready.