A biblioteca padrão do Python inclui smtplib para a conexão SMTP e email.message.EmailMessage para montar a mensagem, então um envio básico via SMTP não exige pacotes de terceiros. Para entregas em produção, uma API de e-mail HTTP gerencia o aquecimento de IP, as novas tentativas e os eventos de bounce sem que você precise manter um servidor de e-mail.
Como enviar e-mail com a biblioteca padrão?
EmailMessage monta a mensagem e define os cabeçalhos para você. smtplib.SMTP_SSL abre uma conexão criptografada na porta 465:
import smtplib
from email.message import EmailMessage
msg = EmailMessage()
msg["From"] = "you@yourdomain.com"
msg["To"] = "recipient@example.org"
msg["Subject"] = "Your receipt"
msg.set_content("Thanks for your order. This is the plain-text version.")
msg.add_alternative("<p>Thanks for your order.</p>", subtype="html")
with smtplib.SMTP_SSL("smtp.example.com", 465) as server:
server.login("smtp-user", "smtp-password")
server.send_message(msg)
set_content escreve o corpo em texto simples e add_alternative anexa a versão HTML, para que os clientes escolham o que conseguem renderizar. Enviar ambas as partes é boa prática e ajuda na entregabilidade.
SSL ou STARTTLS?
Existem dois caminhos de criptografia e eles usam portas diferentes. SMTP_SSL na porta 465 negocia TLS desde o primeiro byte. A alternativa é SMTP simples na porta 587 seguido de starttls(), que eleva uma conexão em texto claro:
with smtplib.SMTP("smtp.example.com", 587) as server:
server.starttls()
server.login("smtp-user", "smtp-password")
server.send_message(msg)
Escolha com base no que o seu servidor de e-mail suporta. Não envie credenciais por uma conexão não criptografada. Mantenha o usuário e a senha em variáveis de ambiente, lidas com os.environ, e não no código-fonte.
Como adicionar um anexo?
add_attachment recebe os bytes e um tipo MIME. Leia o arquivo em modo binário:
with open("invoice.pdf", "rb") as f:
msg.add_attachment(
f.read(),
maintype="application",
subtype="pdf",
filename="invoice-1042.pdf",
)
Por que abandonar o SMTP puro em produção?
O envio em produção traz requisitos que a biblioteca padrão não atende. Você precisa de um servidor de e-mail com reputação de IP limpa, registros SPF, DKIM e DMARC, lógica para tentar novamente em falhas transitórias e uma forma de acompanhar bounces e reclamações. Uma API HTTP cuida dessa camada: você se autentica com uma chave API, envia JSON e lê respostas estruturadas em vez de interpretar códigos de status SMTP.
Envie com Bird
Instale o SDK Python do Bird (pip install messagebird-sdk) para enviar via HTTPS sem gerenciar uma conexão SMTP:
from bird import APIError, Bird
client = Bird()
try:
message = client.email.send(
from_="onboarding@messagebird.dev",
to=["delivered@messagebird.dev"],
subject="Hello from Python",
text="It works.",
html="<p>It works.</p>",
)
print(message.id, message.status)
except APIError as err:
print("send failed:", err)
Bird() lê BIRD_API_KEY do ambiente automaticamente. Enviar de onboarding@messagebird.dev para o endereço sandbox delivered@messagebird.dev valida sua chave e seu payload antes de você configurar um domínio personalizado. Se a solicitação falhar na validação, APIError informa o código de status HTTP e o código de erro.