SMTP Email Support
The Smarter framework includes built-in support for sending emails via SMTP, with the email
service of the infrastructure services,
SMTPEmailService. SMTP works with any SMTP
server, so email does not depend on the cloud provider.
Configuration
SMTP is optional, locally and in production. Without SMTP credentials the platform runs, but no
email is sent: each email that is not sent logs a console error that names it, its recipients, and
the settings below. smarter_settings.smtp_is_configured is True once the username, password,
host and port are all set, and none is a placeholder such as SET-ME-PLEASE.
Set the following environment variables to configure SMTP email sending. These will be consumed by Smarter Settings.
SMTP_SENDER=local.platform.smarter.sh
SMTP_PASSWORD=<YOUR_SMTP_PASSWORD (AWS_SES_SMTP_PASSWORD)>
SMTP_USERNAME=<YOUR_SMTP_USERNAME (AWS_SES_SMTP_USERNAME)>
SMTP_HOST=email-smtp.us-east-1.amazonaws.com
SMTP_PORT=587
SMTP_USE_TLS=True
SMTP_FROM_EMAIL=no-reply@platform.example.com
SMTP_HOST defaults to the AWS Simple Email Service endpoint of AWS_REGION,
email-smtp.<AWS_REGION>.amazonaws.com, and SMTP_FROM_EMAIL defaults to no-reply@ the
platform’s domain.
Also see Cloud infrastructure for configuring AWS Simple Email Service (SES) as your SMTP provider.
Basic Usage
from smarter.apps.infrastructure.services import infrastructure
infrastructure.email.send_email(
subject="Welcome!",
body="Hello and welcome to Smarter.",
to="user@example.com",
html=True,
from_email="support@smarter.com"
)
Each email is blind copied to the platform’s admin, SMARTER_EMAIL_ADMIN. The copy is added
to the SMTP envelope only, so recipients never see the admin’s address. Emails that carry a
secret, such as a password reset link, an account activation link, or a new user’s password,
pass bcc_admin=False, so that only their recipient receives them.
Delivery failures are logged, and sent as the email_failed signal, rather than raised, so
that email never breaks the request that sends it. In the unit tests, nothing is sent, so that
tests never email real people. Tests can replace the service with
InMemoryEmailService, whose outbox
holds what was sent.
Technical Reference
- class smarter.apps.infrastructure.services.email.EmailService(provider_name, *args, **kwargs)[source]
Bases:
InfrastructureServiceThe platform’s outgoing email.
- static admin_bcc(recipients)[source]
The blind copy to the platform’s admin,
smarter_settings.email_admin.
- error_class
alias of
EmailServiceError
- log_not_sent(subject, to)[source]
Log an email that was not sent because the service is not ready.
- message(subject, body, to, html=False, from_email=None)[source]
Return a message, from
smarter_settings.smtp_from_emailunlessfrom_emailis given.It has no
Bccheader: blind copies are added to the envelope by_deliver().- Return type:
- send_email(subject, body, to, html=False, from_email=None, quiet=False, bcc_admin=True)[source]
Send an email.
Failures are logged, and announced with
email_failed, rather than raised, so that email never breaks the request that sends it.- Parameters:
subject (
str) – The subject.body (
str) – The body, HTML ifhtmlis True.to (
str|List[str]) – The recipient, or recipients. Invalid addresses are dropped.html (
bool) – True if the body is HTML.from_email (
str|None) – The sender, by defaultsmarter_settings.smtp_from_email.quiet (
bool) – True to only log what would have been sent.bcc_admin (
bool) – Send a blind copy to the platform’s admin,smarter_settings.email_admin. Pass False for an email that carries a secret, e.g. a password reset link, which only its recipient may see.
- Return type:
- Returns:
True if the email was sent.
- service_name: str = 'email'
The name of the service in signals and logs, see
InfrastructureServiceNames.
- static validate_mail_list(emails, quiet=False)[source]
Return the valid email addresses of a list.
- class smarter.apps.infrastructure.services.email.SMTPEmailService(allow_in_tests=False, smtp_class=<class 'smtplib.SMTP'>, **kwargs)[source]
Bases:
EmailServiceEmail, with SMTP, configured by the
smtp_*settings ofsmarter_settings.In the unit tests, nothing is sent, unless
allow_in_testsis True, so that tests never email real people.- Parameters:
- __init__(allow_in_tests=False, smtp_class=<class 'smtplib.SMTP'>, **kwargs)[source]
- log_not_sent(subject, to)[source]
Log an email that was not sent, with instructions for configuring SMTP.
SMTP is optional, so this is logged for each email that is not sent, rather than raised. In the unit tests, where email is never sent, a one-line warning is logged instead.
- Return type:
- property ready: bool
Whether the service is authenticated and connected, i.e. it can be used.