Enviando e-mails com Python

Envie e-mail em Python usando email.message.EmailMessage e smtplib.SMTP_SSL da biblioteca padrão, ou chame uma API de e-mail HTTP com o pacote messagebird-sdk para entregas em produção.

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.

Construa na mesma rede.

Uma chave de API de teste é sua imediatamente. A produção é desbloqueada quando adicionar um método de pagamento e verificar um remetente.

Start building with Bird in minutes.