Skip to content

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:

For v0 the routes are stubs that document the contract.


Terminal window
cd apps/workers
cp .env.example .env.local # fill in real values
python -m venv .venv
source .venv/bin/activate
pip 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.

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.example

Every 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.1
X-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.

Terminal window
pytest -q
ruff check .
mypy src

This service ships as a Docker image (apps/workers/Dockerfile). Coolify builds and runs it alongside the NestJS backend. See infra/coolify/README.md.