Batch warehouse order creator for Theseus (Hack Club's mail system). Reads a CSV of recipients with per-SKU quantities, creates a warehouse order on Theseus for each row, and writes detailed logs for every request/response.
- Python 3.10+
- No external dependencies (uses stdlib
urllib)
- Copy the example config and add your API key:
cp config.example.json config.json
- Edit
config.json:- Set
api_keyto your Theseus API key - Set
tagsto the tag(s) for this batch - Set
skusto the 12 SKU codes (order matters -- they map to CSV columns)
- Set
The CSV must have these columns in the header row:
first_name,last_name,email,line_1,line_2,city,state,postal_code,country,<SKU_1>,<SKU_2>,...,<SKU_12>
first_name,email,line_1,city,state,postal_code,countryare required.last_nameandline_2are optional.- Each SKU column header must exactly match a SKU string in
config.json. - SKU column values are integer quantities. Use
0to skip a SKU for that row. - Rows with an empty
emailfield are skipped (handles trailing blank/totals rows). - Extra columns (e.g.
attendee_count) are ignored.
See sample.csv for a working example.
Validate without sending anything:
python3 mail_cannon.py orders.csv --dry-run
Send all orders:
python3 mail_cannon.py orders.csv
Specify a different config file:
python3 mail_cannon.py orders.csv --config /path/to/config.json
All output goes to logs/:
mail_cannon_<timestamp>.log-- human-readable log with every request/response at DEBUG level, summaries at INFO level.mail_cannon_<timestamp>_results.json-- machine-readable JSON with per-order status, order IDs, and full API responses.
- Loads config and validates the API key and SKU list.
- Reads the CSV and validates every row (required fields, integer quantities, at least one SKU > 0).
- If any row fails validation, the entire batch is aborted before sending anything.
- Sends a
POST /api/v1/warehouse_ordersrequest to Theseus for each row. - Each order is automatically dispatched to Zenventory (the warehouse fulfillment backend).
- Logs success/failure for each row, then writes a summary.
- Endpoint:
POST /api/v1/warehouse_orders - Auth:
Bearer <api_key>header - Theseus normalizes country names and state abbreviations automatically.
- Blocked destinations: IR, PS, CU, KP, RU.
- A 0.5s delay is inserted between requests to avoid rate limiting.
- Request timeout is 120s (the server can be slow on large orders).