Skip to content

heybeaux/prizm-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

35 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PRIZM Code Lookup API

Small Flask API for looking up Canadian PRIZM segments by postal code. It is shaped for a Salesforce Flow that submits up to 10 Canadian postal codes per run.

What Changed

The current PRIZM site no longer needs browser scraping. The React frontend calls public JSON services:

  • Environics geocoder: resolves a postal code to PRIZM segmentation code
  • Supabase REST: returns PRIZM segment profile data

This app now uses those APIs directly instead of Selenium/Chromium, which makes Railway deployment much lighter and avoids the old long-running browser crash mode.

Endpoints

Health

GET /health

Single Lookup

GET /api/prizm?postal_code=V8A0A8

Batch Lookup

POST /api/prizm/batch
Content-Type: application/json

{
  "postal_codes": ["V8A0A8", "M5V3L9"]
}

The default batch limit is 10 postal codes. Override with MAX_BATCH_POSTAL_CODES.

All Segments

GET /api/segments

Useful if you want the full segment reference data without postal-code lookup.

Example Response

{
  "postal_code": "V8A 0A8",
  "prizm_code": "21",
  "segment_number": "21",
  "segment_name": "Scenic Retirement",
  "segment_description": "Older, middle-income suburbanites",
  "average_household_income": "$140,223",
  "education": "High School/College",
  "urbanity": "Suburban",
  "occupation": "Mix",
  "diversity": "Low",
  "family_life": "Couples/Families",
  "tenure": "Own",
  "home_type": "Single Detached/Row",
  "status": "success"
}

Local Development

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python app.py

Then open http://localhost:8080/health.

Railway Deployment

Railway can deploy this repo with either the Dockerfile or the Procfile.

Recommended Railway variables:

PRIZM_API_KEY=<set-this-and-send-it-from-salesforce>
MAX_BATCH_POSTAL_CODES=10
PRIZM_CACHE_DB_PATH=/data/prizm_cache_v2.db
PRIZM_SUCCESS_CACHE_DAYS=3650
PRIZM_INVALID_CACHE_DAYS=90
PRIZM_ERROR_CACHE_DAYS=30
WEB_CONCURRENCY=2
GUNICORN_THREADS=4
GUNICORN_TIMEOUT=60

If you set PRIZM_CACHE_DB_PATH=/data/..., add a Railway volume mounted at /data so cached lookups survive redeploys. The cache is optional; the API works without a persistent volume.

To preload Railway's persistent cache from the existing CSV export, run this in a Railway shell after the volume is mounted:

python cache_cli.py import-csv prizm_import_09112025.csv --replace
python cache_cli.py stats

Successful lookups default to a 10-year cache, invalid postal-code formats default to 90 days, and cacheable not-found/error results default to 30 days. Upstream quota/network failures are not cached.

When PRIZM_API_KEY is set, all /api/* routes require either:

X-API-Key: <key>

or:

Authorization: Bearer <key>

Optional override variables:

PRIZM_GEOCODER_API_URL=https://api.environicsanalytics.com/geocoder-openauth
PRIZM_GEOCODER_COUNTRY=ca
PRIZM_GEOCODER_VINTAGE=2026
PRIZM_SUPABASE_URL=https://rkfddhcgcubrelqdzajw.supabase.co
PRIZM_SUPABASE_KEY=<public publishable key>
PRIZM_UPSTREAM_TIMEOUT=12
CORS_ALLOW_ORIGIN=*

Tests

python3 -m unittest test_prizm_api.py

Notes

  • Selenium files are left in the repo for historical reference, but the Flask API no longer imports or uses Selenium.
  • Rural postal codes are resolved directly from the frontend's Supabase rural_postal_codes table.
  • Urban postal codes still depend on the Environics geocoder API. During triage on June 21, 2026, that endpoint returned 403 Quota Exceeded, so urban postal-code lookups may fail until the public quota replenishes or a licensed/geocoding credential is available.
  • prizm_cache_v2.db, CSV exports, debug screenshots, and node_modules are runtime/local artifacts and are ignored by Docker.
  • The old crash was most likely caused by a globally reused Selenium Chrome session combined with Flask debug mode and repeated screenshot/page-source capture. Removing the browser from request handling eliminates that failure path.

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors