Declare tenacity - undeclared import crashed the container on boot

app/services/enrichment/barcode/retry.py imports tenacity at module scope,
and that module is on app/main.py's import path (main -> store_catalog router
-> store_catalog_pipeline -> barcode enrichment -> sources -> retry). tenacity
was in no requirements file, so the deployed image exited 1 during startup:

    File "/app/app/main.py", line 33, in <module>
        from app.api.routers import store_catalog
    ...
    File "/app/app/services/enrichment/barcode/retry.py", line 16
        from tenacity import (
    ModuleNotFoundError: No module named 'tenacity'

This surfaced as "100% CPU", not as a crash, which is why it was mis-read.
uvicorn never bound a socket, Swarm restarted the task, and each restart
re-ran the ~21s of eager pandas/scipy/sklearn imports that the analytics,
recommendations and nutrition routers pull in at module scope. On this
1-vCPU host that loop pins the only core indefinitely.

retry.py's own docstring asserted tenacity was "already a project dependency
(see requirements.txt)". It never was - corrected to say the opposite, and to
record that it is a hard startup dependency rather than an optional extra.

Verified on the deployed image, not just locally: with tenacity present the
container reaches health=healthy with restarts=0, and /, /api/health,
/api/brands, /api/system/status and /docs all return 200. Idle cost is
0.16% CPU / 168MiB. An AST scan of every import in app/, cli/, scripts/ and
serve.py against the image finds no other missing module (playwright is the
one remaining absence and is deliberate - commented out in requirements.txt
and imported lazily inside a function).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7bVBpxH4AbJtK7Kp3MzDR
This commit is contained in:
Suriyakumarvijayanayagam
2026-08-25 15:23:06 +05:30
parent 1b347f91db
commit a9ab1fcf71
2 changed files with 14 additions and 2 deletions

View File

@@ -1,8 +1,10 @@
"""
Configurable retry-with-exponential-backoff for barcode source calls.
Built on `tenacity`, already a project dependency (see requirements.txt -
used elsewhere for httpx-based retries). Only retries on genuinely
Built on `tenacity`, declared in requirements.txt. The import below is at
module scope and this module sits on app/main.py's import path, so tenacity
is a hard startup dependency, not an optional extra - without it the
container exits 1 before uvicorn binds. Only retries on genuinely
transient failures (network/timeout errors); a malformed response or a
"no results" outcome is not retried, since retrying those wastes the
source's rate-limit budget for no benefit (relevant for UPCItemDB's