Local setup¶
The Mac that this project was developed on uses Python 3.14 globally and port 8010 for the dev server (8000 was taken). Adjust as needed.
Prerequisites¶
- Python 3.14 (or 3.12+; 3.14 is what prod runs)
- Git
- A
.envfile (copy from.env.example)
Optional but recommended:
uv— used foruvxinvocations (e.g. running the docs site).prek— the pre-commit alternative we use; install withuvx prek install.flyctl— for deploying / SSHing into prod.gh— for working with GitHub from the terminal.
First-time setup¶
cd lifefile
cp .env.example .env
# Apply migrations against the local SQLite db.sqlite3.
python3 manage.py migrate
# Optional: create a superuser for /admin/.
python3 manage.py createsuperuser
Run the dev server¶
Then open http://127.0.0.1:8010/. The login screen will offer "Continue with Google" (requires GOOGLE_OAUTH_CLIENT_ID/SECRET in .env) or "Create one" for username + password. Drop a doc onto the upload screen to see the classifier work end-to-end.
Env vars¶
The full list is in config/settings.py. The ones you usually care about:
| Var | Default | Purpose |
|---|---|---|
SECRET_KEY |
dev-only fallback | Django secret. Generate fresh per environment. |
DEBUG |
True |
Off in prod. |
DATABASE_URL |
sqlite:///db.sqlite3 |
Postgres-friendly via dj-database-url. |
ANTHROPIC_API_KEY |
"" |
Required for CLASSIFIER_MODE=live. |
CLASSIFIER_MODE |
stub |
stub (keyword) / live (Claude). |
EMAIL_TOKEN_KEY |
"" |
Fernet key for encrypting Gmail OAuth tokens. Generate with python3 -c 'import secrets; print(secrets.token_urlsafe(32))'. |
GOOGLE_OAUTH_CLIENT_ID / _SECRET |
"" |
"Sign in with Google" + Gmail readonly. |
VEHICLE_LOOKUP_MODE |
mock |
mock (deterministic canned data) / live (DVLA + DVSA). |
DVLA_VES_API_KEY |
"" |
DVLA Vehicle Enquiry Service. See Vehicle lookup setup. |
DVSA_MOT_* |
"" |
DVSA MOT History (5 vars: client_id, client_secret, tenant_id, api_key, scope). |
Stub vs live classifier¶
Stub mode (default) recognises a handful of filename patterns:
boiler_service_certificate_2025.pdf→ Home → Boiler Service Certificatefensa_certificate.pdf→ Home → FENSA Certificateadmiral_insurance_policy.pdf→ Insurance → Buildings Insurance Policyv5c_vehicle_registration.pdf→ Vehicles → V5Cpassport_2024.jpg→ Identity → Passportinvoice_3421.pdf→ Home → Contractor Invoice- Anything else → Home → Other Property Document (awaiting user review)
Good enough for dev workflow and unit tests.
Live mode sends document bytes + email context to Claude Sonnet. ~£0.005 per document. Set CLASSIFIER_MODE=live and ANTHROPIC_API_KEY=sk-ant-… in .env.
Mock vs live vehicle lookup¶
Mock mode (default) returns deterministic data keyed off the plate hash. Set VEHICLE_LOOKUP_MODE=live plus all five DVSA_MOT_* vars + DVLA_VES_API_KEY to hit the real APIs.
See Vehicle lookup setup for registration steps.
Other URLs¶
- http://127.0.0.1:8010/admin/ — Django admin
- http://127.0.0.1:8010/api/health — Ninja liveness probe
- http://127.0.0.1:8010/api/docs — auto-generated OpenAPI docs
Common gotchas¶
- Port 8000 conflict — use a different port (
runserver 8010). - Missing migration — local SQLite gets out of sync occasionally;
python3 manage.py migratefixes it. - Encrypted token decode error — usually means
EMAIL_TOKEN_KEYchanged; reconnect Gmail to regenerate. DJANGO_SETTINGS_MODULE— set toconfig.settingsin.env; pytest reads it frompytest.ini.