Treeper — Workers (Python / FastAPI)
AI ingest and scrapers for Treeper. Only the NestJS backend
(apps/backend) talks to this service, authenticated by a
shared X-Workers-Token header.
For the why, see ADR 0003 Python workers.
The endpoints exposed here are the Python side of features:
- 0002 — AI ingest (planned)
- 0003 — prompt-to-itinerary (planned)
- 0006 — verified marketplace scrapers (planned)
- 0007 — deals / price-watch (planned)
For v0 the routes are stubs that document the contract.
cd apps/workers
cp .env.example .env.local # fill in real valuespython -m venv .venvsource .venv/bin/activatepip install -e ".[dev]"
uvicorn treeper_workers.main:app --reload --port 8000# http://localhost:8000/health# http://localhost:8000/docs (OpenAPI / Swagger UI)WORKERS_SHARED_SECRET is required. The service will fail to start
without it.
Layout
Section titled “Layout”apps/workers/├── src/treeper_workers/│ ├── __init__.py│ ├── main.py FastAPI entrypoint, /health, mounts ai + scrape│ ├── config.py pydantic-settings; loads from env / .env│ ├── auth.py X-Workers-Token verification│ ├── ai/│ │ └── router.py /ai/ingest, /ai/prompt-to-itinerary (stubs)│ └── scrape/│ └── router.py /scrape/guides/refresh, /scrape/deals/watch (stubs)├── tests/│ └── test_health.py├── pyproject.toml├── Dockerfile└── .env.exampleEvery authenticated route depends on require_workers_token, which
constant-time compares the incoming X-Workers-Token header against
WORKERS_SHARED_SECRET.
POST /ai/ingest HTTP/1.1X-Workers-Token: <shared secret>Content-Type: application/json
{"url": "https://www.instagram.com/reel/...", "user_hint": "veg, mid budget"}End users never reach this service directly — the mobile app talks to
apps/backend, which fans out here.
Testing
Section titled “Testing”pytest -qruff check .mypy srcDeploy
Section titled “Deploy”This service ships as a Docker image (apps/workers/Dockerfile). Coolify
builds and runs it alongside the NestJS backend. See
infra/coolify/README.md.