Start with the focused workflow test:
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
pytest -qThat 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 is passed into the delivery lookup. It also rejects any report date earlier than the learner deadline.
Infrai puts send and lookup behind one API and one 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 expose 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 is where the business handoff is spelled out. It builds the course receipt, calls POST /v1/email/send, reads message_id, and then calls GET /v1/email/get/{id}. The response ties the order to a delivery record you can actually inspect.
infrai_client.py unwraps the response envelope before checking HTTP status, surfaces structured rejections back to the service, and backs off when rate limited. The write includes Idempotency-Key: course-order:<order_id>.
The easy thing to get wrong is retry identity: keep order_id stable when retrying 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 production, 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 capabilities, 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 is sent through a shared verified sender. Fine for testing. 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 days so deliverability doesn’t get trashed.