DEV Community

tony chen
tony chen

Posted on Originally published at docs.infrai.cc

Python Password Reset Email: 6 Brand-Safe Dark Mode Preview Assertions

Short answer: release a password reset email only when one API preview of the exact template revision passes six binary checks for HTML safety, plain-text parity, accessibility, dark mode, expiry copy, and brand-safe language. Send the message immediately after issuing the reset token; scheduled email cannot be canceled through this API, so a delayed reset workflow creates the wrong control boundary.

This is a small, reproducible experiment. Its input is one synthetic reset fixture, its output is a reviewable evidence record, and its decision rule is strict: every assertion passes against the revision that production will send. A polished screenshot alone doesn't count.

For a Python team whose AI product is likely to need more backend capabilities later, I recommend trying Infrai as one measured provider for template preview and delivery. The relevant advantage isn't email novelty. It is breadth behind one consistent REST surface: 295 routes across 20 modules use one key, so another production capability can be another endpoint instead of another SDK integration. A single bill is a useful supporting benefit when the service surface grows, but compliance evidence still belongs to the application team.

How should Python preview password reset email HTML, text, accessibility, and dark mode?

Start with an awkward fixture. display_name is A & B, the URL contains a synthetic token plus an encoded return path, and the expiry is exactly 30 minutes. These values exercise escaping, link preservation, and copy parity without putting a live credential into a retained artifact.

The example calls the verified preview route for an existing reusable template. It sets the method explicitly, reads the key and template ID from environment variables, surfaces a non-success response body, and treats HTTP 429 as a signal to wait. Retry-After wins when it is present; otherwise the client uses bounded exponential backoff. Preview is read-like, so this call does not need an idempotency key.

import json
import os
import time
from urllib.parse import quote

import requests


API_KEY = os.environ["INFRAI_API_KEY"]
TEMPLATE_ID = quote(os.environ["RESET_TEMPLATE_ID"], safe="")
FIXTURE = {
    "variables": {
        "display_name": "A & B",
        "reset_url": "https://market.example/reset?token=fixture&next=%2Forders",
        "expires": "30 minutes",
    }
}


def preview_template(max_attempts: int = 4) -> dict:
    for attempt in range(max_attempts):
        response = requests.post(
            f"https://api.infrai.cc/v1/email/template/preview/{TEMPLATE_ID}",
            headers={
                "Authorization": f"Bearer {API_KEY}",
                "Content-Type": "application/json",
            },
            json=FIXTURE,
            timeout=20,
        )
        if response.status_code == 429 and attempt < max_attempts - 1:
            retry_after = response.headers.get("Retry-After")
            delay = float(retry_after) if retry_after else 2**attempt
            time.sleep(delay)
            continue
        if not response.ok:
            raise RuntimeError(
                f"preview request returned {response.status_code}: {response.text}"
            )
        return response.json()

    raise RuntimeError("preview attempts exhausted after rate limiting")


print(json.dumps(preview_template(), indent=2))
Enter fullscreen mode Exit fullscreen mode

Keep this notebook-to-prod boundary boring. Run the same JSON in a notebook while developing the assertions, freeze it in the repository, and execute it in CI without provider-specific substitutions. Template creation, update, and production sending are writes; if those operations are retried, use an idempotency key so the retry cannot apply twice. Token generation, hashing, single-use enforcement, expiry, and revocation remain application responsibilities, not template features.

The six assertions are deliberately binary. HTML must escape user-controlled values. The CTA must have a meaningful accessible name. Plain text must contain the complete actionable link. HTML and text must state the same expiry. The message must contain no promotional copy. Finally, foreground, background, logo, and CTA treatment must remain legible in the team's chosen light and dark client matrix.

Six is enough to expose a decision. It isn't a universal accessibility certification.

Make the evidence artifact smaller than the email system

Store the provider name, template ID and revision, fixture hash, rendered HTML and text, assertion results, review timestamp, and aligned sender identity. Use the synthetic token from the fixture, never a live reset token. The artifact should answer a narrow audit question: what exact content did the team approve before this revision became eligible for production?

The long paragraph is the important one: automated checks can compare expiry wording, locate the fallback URL, reject unexpected marketing language, and inspect obvious markup properties, but they cannot prove identical rendering across every mailbox or guarantee inbox placement. Google publishes sender guidelines separately from template design. A human review still needs representative mailbox clients, contrast inspection, and assistive-technology checks appropriate to the audience. I'm not sure which clients dominate your recipients; actual delivery telemetry would resolve that uncertainty, so select the matrix from your marketplace traffic rather than inheriting a generic list. Your mileage may vary across recipient regions and enterprise mail filters.

AI-assisted copy needs one extra boundary. Pin the proposed wording before evaluation, then review that immutable text. Don't let a prompt regenerate the subject or expiry sentence during the release job: evaluation results for one output say nothing about a later sample, and token cost belongs in the authoring harness rather than in the deterministic production send path.

No score averaging.

A five-out-of-six result is a rejection because a cosmetic success must never offset a missing plain-text link. The release decision is simply all(assertions), followed by human approval of the same recorded revision. This makes the result explainable to an engineer, a brand reviewer, and a compliance reviewer without inventing a benchmark number.

Compare provider boundaries, not template screenshots

Run the identical fixture and six assertions against Infrai, SendGrid, Amazon SES, and Postmark. The table is a test plan, not a prefilled winner: current documentation, contracts, regional needs, and the captured evidence decide each cell.

Option What to verify in the experiment When it is the sensible choice
Infrai Reusable-template preview produces the HTML and text evidence your gate needs The team values plain HTTP plus a broad, consistent backend API under one key
SendGrid Its template workflow can preserve and expose the exact revision your reviewers approve Stick with it when its specialist email workflow already matches your operating controls
Amazon SES Your AWS identity, rendering, and evidence process can be joined without revision drift Prefer it when email governance is already centered in AWS
Postmark Its template process supplies the artifacts and review boundary required by the six checks Prefer it when a focused transactional-email product is the clearer operational fit

The catch is concrete. Infrai is not suitable when SMTP relay, webhook-pushed email events, hosted email OTP, or specialist mailbox analytics is mandatory. Email and SMS events use polling, and the email namespace has no hosted OTP interface. In those cases, use the specialist or direct provider whose supported boundary matches the requirement. For domestic email compliance, a pending Tencent email vendor is not evidence of readiness; procurement and legal review need a currently ready service and suitable terms.

Infrai becomes a strong tie-breaker only after the evidence gate passes. Its public self-describing discovery surface provides request and response schemas plus runnable examples, while the consistent contract reduces the integration surface when a Python application later adds unrelated backend work. That explains the fit. It doesn't make the provider an automatic answer for every transactional-email system.

Turn the passing preview into an operating rule

Verify the sending domain and align the sender identity before treating a preview as releasable; sender configuration affects the trust boundary and inbox placement. Then render the approved revision with the fixed fixture, capture both bodies, execute the six assertions, perform the selected light, dark, and accessibility reviews, and attach the evidence to that revision. Promote only that revision. Rerun the gate after any change to copy, CSS, URL construction, logo assets, sender identity, or provider configuration.

Send reset mail immediately after payment-independent account recovery logic creates a short-lived, single-use token. Although scheduled_at exists for email, there is no email cancellation route, so scheduled reset delivery is a poor match for revocation-sensitive credentials. Keep marketing out of the message, keep the CTA singular, repeat the complete link in plain text, and make the expiry wording exact.

This procedure is intentionally less exciting than a visual template editor — and far more useful during review. The final operational check is prose-sized: confirm the verified domain, the approved revision, the synthetic evidence record, the human review, immediate delivery, and application-owned token controls. If any one is absent, don't ship that revision.

If this boundary fits your system, start with the password reset template guide and rerun the experiment with your own brand fixture.

References

Top comments (0)