Email Setup

Sending Transactional Email from Flask

30 分

Sending with an API

import os
import resend

resend.api_key = os.environ["RESEND_API_KEY"]

def send_email(to, subject, html, text):
    return resend.Emails.send({
        "from": "PandaDev <hello@mail.pandadevhub.com>",
        "to": [to],
        "subject": subject,
        "html": html,
        "text": text,
        "reply_to": "support@pandadevhub.com",
    })

Other providers have equivalent SDKs; wrap them behind one send_email function so you can switch providers without changing the rest of the app.

Templates

Render email bodies with Jinja like pages:

from flask import render_template

html = render_template("emails/verify.html", user=user, link=link)
text = render_template("emails/verify.txt", user=user, link=link)
send_email(user.email, "Verify your email", html, text)

Email HTML is old-fashioned: use simple layouts (tables or a framework such as MJML), inline styles, web-safe fonts, alt text on images and a maximum width around 600px. Always include a plain-text version: it helps deliverability and accessibility.

Links and tokens

  • Use absolute URLs: url_for("auth.verify", token=token, _external=True) with SERVER_NAME/PREFERRED_URL_SCHEME configured, or a BASE_URL setting.
  • Tokens must be random (secrets.token_urlsafe(32)), stored hashed, single-use and short-lived (password resets: about an hour).
  • Do not reveal whether an email exists: "If an account exists, we have sent a link" for password resets.

Send in the background

A slow provider should not slow down sign-up. Queue the email (RQ, Celery or a thread for simple cases) and return the response immediately. Retry transient failures, and log the provider's message ID for support.

Development and testing

  • Use the provider's test mode or a local catcher (Mailpit) so you never email real users by accident.
  • In tests, mock send_email and assert it was called with the right recipient and link.

Exercise

Implement email verification for sign-up: a hashed, single-use, 24-hour token; HTML and text templates; background sending; and tests that mock the send function.

Check yourself

  • Why include a plain-text version?
  • Why store email tokens hashed?
  • Why send emails outside the request?

進捗はこのブラウザーにのみ保存されます。

レビューに提出(10 ポイント)