# ── Phase 1 — core API / queue / data layer ────────────────── Flask==3.0.3 Flask-Cors==4.0.1 Jinja2==3.1.4 gunicorn==22.0.0 python-dotenv==1.0.1 requests==2.32.3 redis==5.0.7 rq==1.16.2 Flask-Limiter==3.5.0 PyJWT==2.9.0 # ── Billing / email ─────────────────────────────────────────── stripe==10.7.0 resend==2.4.0 # ── Phase 2 — scraping engine (moved from legacy app.py) ───── # playwright is unpinned to a minimum, not exact — 1.46.0's pinned # greenlet dependency has no prebuilt wheel on newer Python versions # and fails to build from source; newer playwright releases pull in a # newer greenlet that does ship prebuilt wheels. playwright>=1.55.0 # playwright-stealth is pinned to 1.0.6 (not the 2.x line) because # CLAUDE.md §10 documents the 1.x `stealth_async(page)` function API # verbatim; playwright-stealth 2.x replaced it with a class-based # `Stealth().apply_stealth_async(...)` API — a breaking change from # what's specified. 1.0.6 depends on pkg_resources, which setuptools # >=81 no longer ships — hence the setuptools pin below. playwright-stealth==1.0.6 setuptools<81 beautifulsoup4==4.12.3 lxml==5.3.0 nest_asyncio==1.6.0 openai==1.43.0 gspread==6.1.2 google-auth==2.34.0 # ── Phase 6 — embeddings / similarity ───────────────────────── # Unpinned to a minimum rather than exact — prebuilt wheels for very # new Python versions lag behind numpy point releases; pip will pick # the newest compatible wheel. numpy>=2.2.0 # ── Observability (initialised in Phase 7, dependency pinned now) ─ sentry-sdk[flask]==1.44.1 # ── Testing ──────────────────────────────────────────────────── pytest==8.3.2 pytest-cov==5.0.0 pytest-mock==3.14.0 fakeredis==2.24.1