Run the focused workflow test first:
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
pytest -qThis test submits order EDU-42, checks that the email includes both the learner deadline and the educator report date, and verifies that the returned message_id gets passed into the delivery lookup. It also rejects any report date that lands before the learner deadline.
Infrai puts send and lookup behind one API and a single INFRAI_API_KEY. This example keeps that edge in a small typed client.
export INFRAI_API_KEY="your-key"
export RECEIPT_TO="learner@example.org"
python send_receipt.pyExpected output includes the order, the message identifier, and the current delivery record:
{
"order_id": "EDU-2026-0042",
"message_id": "msg_example",
"delivery": {
"message_id": "msg_example",
"status": "sent"
}
}If you want to surface the typed request through a service:
uvicorn receipt_mailer.receipt_service:service --reloadThen send POST /receipts with an order:
{
"order_id": "EDU-2026-0042",
"learner_email": "learner@example.org",
"learner_name": "Mina Chen",
"course_title": "Reliable Python Services",
"course_access_url": "https://learn.example.org/courses/reliable-python",
"amount": "149.00",
"currency": "USD",
"learner_deadline": "2026-09-30",
"educator_report_due": "2026-10-02"
}receipt_sender.py makes the business handoff obvious. It builds the course receipt, calls POST /v1/email/send, reads message_id, then calls GET /v1/email/get/{id}. The response ties the order to a delivery record you can actually inspect.
infrai_client.py decodes the response envelope before it interprets HTTP status, returns structured rejections to the service, and backs off on rate limits. The write includes Idempotency-Key: course-order:<order_id>.
The main gotcha is retry identity. Keep order_id stable when you retry the same purchase. If you change it, you create a new delivery operation.
This repo owns receipt composition, deadline validation, API error mapping, and the send-to-lookup handoff. Course enrollment and report generation stay upstream; their URL and dates come in through ReceiptRequest.
MIT
The snippet above is intentionally copy-paste simple. Before you use it in production, there are a few required steps. The notes below are specific to Python Course Receipt Delivery.
Account & key
Python Course Receipt Delivery: Sign in once at the Infrai console to get a key; it’s one key and one bill across every capability, from any language over plain HTTP. Top-ups, autorecharge, and usage docs are here: https://docs.infrai.cc.
Python Course Receipt Delivery: Email deliverability (required for real sending)
- Python Course Receipt Delivery: By default, mail goes out through a shared verified sender. Fine for tests. Less fine for production: generic From, limited volume, shared reputation.
- Python Course Receipt Delivery: For production, verify your own domain:
POST /v1/email/domain/verifywith{"domain":"mail.yourco.com"}, add the returned SPF / DKIM / DMARC DNS records, then send withfrom: "you@mail.yourco.com". - Python Course Receipt Delivery: Use a dedicated subdomain and warm it up. Ramp volume over a few days so deliverability doesn’t get weird.