1.8.2
βοΈ Patch 1.8.2 β Keepa token wait fix, Qogita webhook 401, catalog pending timeout¶
π Summary¶
- Keepa pipeline no longer stalls in
waiting_tokenswhen the token bucket is negative β Sync ASINs and Fetch Products wait only for the next stepβs token cost and refreshtokens_leftfrom Keepa after resume. - Qogita catalog webhook
POST /qogita/webhooks/incomingaccepts signed payloads again β request body is preserved for HMAC verification; signature parsing supports commonv1=/ hex / base64 formats. - Qogita catalog download no longer stays
pendingforever if the webhook never arrives β auto-fails after 30 minutes; UI allows retry after ~5 minutes (Qogita does not resend missed webhooks).
π Bug Fixes¶
Keepa pipeline β stuck at waiting_tokens¶
Symptom: Pipeline frozen (e.g. Sync ASINs at 2800/28999), tokens_left=-8, logs every 30 min:
resuming after token wait β immediately waiting for tokens (left=-8, resume in 3456s) with no API calls and no progress.
Cause:
- Wait time targeted a full 280-token bucket (~58 min) instead of tokens needed for the next page (1) or batch (100).
- On resume, stale
tokens_leftfrom DB was reused without calling Keepa β pre-check re-scheduled wait every cron tick.
Fix:
_seconds_until_tokens_available(tokens_left, needed)β wait only untilneededtokens exist (1 for sync,fetch_batch_sizefor fetch).- On resume after
wait_until, settokens_left = Noneso the next tick calls Keepa and reads freshtokensLeft. - Logs now include
need=e.g.waiting for tokens (left=-8, need=1, resume in 108s).
Unblock a stuck job after deploy (optional):
UPDATE cron_jobs
SET arguments = jsonb_set(arguments, '{pipeline,tokens_left}', 'null'::jsonb)
WHERE name = 'keepa_pipeline_tick';
Restart service-omni β next keepa_pipeline_tick should process pages again.
Qogita webhook β 401 Invalid signature¶
Symptom: POST /api/v1/omni/qogita/webhooks/incoming returned 401 even with correct Qogita signing secret; catalog download never imported; UI stuck on Latest download: pending.
Cause: log_requests middleware called await request.body() before the handler β body consumed, HMAC verified against empty bytes. Qogita does not retry failed webhooks.
Fix:
- Re-inject cached body via
request._receiveinlog_requestsso downstream handlers see raw bytes. - Webhook path on
PUBLIC_ENDPOINTS(no JWT). verify_webhook_signatureβ Qogita usesX-Qogita-Signature: t={unix},v={hmac}over{timestamp}.{webhook_url}.{raw_body}(not body alone); falls back to raw-body HMAC for older formats.- Setup webhook deletes any existing endpoint at the callback URL and re-registers to obtain a fresh
signingSecret(secret is only returned once on create). - Clearer failure logging in
qogita_webhooks.py(body_len, signature presence).
After deploy: restart service-omni, then Request catalog again (or Retry catalog request in the UI).
Qogita catalog β pending never cleared¶
Symptom: Waiting for Qogita webhook⦠indefinitely after a failed/missed callback; Request catalog button disabled.
Fix:
expire_stale_pending_catalog()β onGET /catalog/status(and before a new request), markpendingasfailedafter 30 minutes with a clear error message.- API adds
pending_timeout_minutesandpending_expires_aton catalog status. - Frontend: shows auto-fail time, failed error text, and enables Retry catalog request after ~5 minutes when webhook is overdue.
Reset a stuck pending download immediately (optional):
UPDATE qogita_webhook_settings
SET catalog_status = 'failed',
catalog_error_message = 'Webhook not received β reset manually',
catalog_completed_at = NOW()
WHERE catalog_status = 'pending';
Env override: QOGITA_CATALOG_PENDING_TIMEOUT_MINUTES (default 30).
β¨ Tests¶
test_keepa_pipeline.pyβ fetch batch wait math (-8+ batch 100 β 1296s, not 3456s); resume after token wait calls fetch (no stale re-wait).test_qogita_catalog_unit.pyβ webhook signature (v1=, invalid body); pending timeout expiry (@pytest.mark.db).
cd backend/service_omni
pytest app/tests/test_keepa_pipeline.py app/tests/test_qogita_catalog_unit.py -v
π Files changed¶
Backend (service_omni)
app/services/keepa/pipeline_runner.pyapp/main.pyapp/services/qogita/catalog.py,catalog_setup.py,constants.pyapp/crud/qogita_catalog.pyapp/api/v1/endpoints/qogita_webhooks.pyapp/models/qogita.pyapp/tests/test_keepa_pipeline.py,test_qogita_catalog_unit.py
Frontend
src/pages/Statistics/Tabs/QogitaWatchlistTab.jsx
π§ Deploy¶
No new migrations. Restart service-omni after deploy. Rebuild frontend for catalog pending/retry UI.
If a Keepa pipeline job was stuck overnight, clear stale tokens_left (SQL above) or wait for the next cron tick after restart.
Verify Qogita catalog
- Setup webhook β Request catalog.
- CSV usually arrives in 2β3 minutes via webhook; status becomes
completedandwholesale_shopping_listgains rows. - If still
pendingafter ~5 min, use Retry catalog request (only after 1.8.2 is deployed). - Check logs for
Qogita webhook received: type=catalog_download.completed.
Verify Keepa pipeline: Start Sync ASINs or Fetch Products β when tokens run low, wait ETA should be minutes (per step), not ~58 min loop; processed count should increase after each resume.