FastAPI-Mail
fastapi-mail is a simple, lightweight library for sending emails in FastAPI applications. It integrates seamlessly with FastAPI's asynchronous nature and background tasks to prevent blocking the event loop. The current version is 1.6.2, and it maintains an active development pace with frequent minor updates and bug fixes addressing community needs.
Warnings
- gotcha Sending emails is a blocking I/O operation. To prevent your FastAPI application from freezing, always use `FastMail.send_message` with `BackgroundTasks` for non-blocking execution, or ensure it's `await`ed within an `async` function.
- gotcha Incorrect SMTP configuration (e.g., `MAIL_PORT`, `MAIL_SERVER`, `MAIL_STARTTLS`, `MAIL_SSL_TLS`, `USE_CREDENTIALS`) is a common cause of connection failures. These settings must precisely match your email provider's requirements.
- gotcha When attaching files, ensure the file pointer for the attachment is reset to the beginning (e.g., using `file_object.seek(0)`) before passing it to `MessageSchema`. Failure to do so might result in empty or malformed attachments.
- gotcha The `redis` dependency is optional. If you intend to use `DefaultChecker` for features like email rate limiting or connection pooling, you must explicitly install `redis` (`pip install redis`) and configure it alongside `fastapi-mail`.
Install
-
pip install fastapi-mail
Imports
- FastMail
from fastapi_mail import FastMail
- MessageSchema
from fastapi_mail import MessageSchema
- ConnectionConfig
from fastapi_mail import ConnectionConfig
Quickstart
from fastapi import FastAPI, BackgroundTasks
from fastapi_mail import FastMail, MessageSchema, ConnectionConfig
from pydantic import EmailStr
import os
app = FastAPI()
# Configure email connection settings
# It's recommended to use environment variables for sensitive data
conf = ConnectionConfig(
MAIL_USERNAME=os.environ.get("MAIL_USERNAME", "your_email@example.com"),
MAIL_PASSWORD=os.environ.get("MAIL_PASSWORD", "your_password"),
MAIL_FROM=EmailStr(os.environ.get("MAIL_FROM", "your_email@example.com")),
MAIL_PORT=int(os.environ.get("MAIL_PORT", 587)),
MAIL_SERVER=os.environ.get("MAIL_SERVER", "smtp.gmail.com"),
MAIL_FROM_NAME=os.environ.get("MAIL_FROM_NAME", "My FastAPI App"),
MAIL_STARTTLS=bool(os.environ.get("MAIL_STARTTLS", True)),
MAIL_SSL_TLS=bool(os.environ.get("MAIL_SSL_TLS", False)),
USE_CREDENTIALS=bool(os.environ.get("USE_CREDENTIALS", True)),
VALIDATE_CERTS=bool(os.environ.get("VALIDATE_CERTS", True)),
TEMPLATE_FOLDER=None # Path to your Jinja2 templates, e.g., './templates'
)
@app.post("/send-email")
async def send_test_email(email_to: EmailStr, background_tasks: BackgroundTasks):
# Create a message schema
message = MessageSchema(
subject="FastAPI Mail Test",
recipients=[email_to], # List of recipients
body="<p>This is a test email sent from <strong>FastAPI-Mail</strong>!</p>",
subtype="html" # Can be "plain" or "html"
)
# Instantiate FastMail with the configuration
fm = FastMail(conf)
# Send the email using background tasks to avoid blocking the API response
background_tasks.add_task(fm.send_message, message)
return {"message": "Email has been scheduled for sending"}