Como Enviar E-mail via API em Python (Tutorial Rápido)

Índice
Índice 11 seções
Primeiros Passos
Enviando e-mails
Produção
Referência
Tutorial de Python

Como Enviar E-mail via API em Python (Tutorial Rápido)

Pule o texto padrão do SMTP. Este guia mostra como usar o API unificada de e-mail Unipile para enviar e-mail em Python - com exemplos de copiar e colar para Gmail, Outlook e IMAP usando o solicitações biblioteca.

api de email python api para enviar email python Gmail / Outlook / IMAP requests / aiohttp Flask / Django / FastAPI
send_email.py
import requisições, os CHAVE_API = os.environ'UNIPILE_API_KEY'] DSN = os.environ'UNIPILE_DSN'] ID_DA_CONTA = os.environ'ID_DA_CONTA_UNIPILE'] response = requests.postagem( f'{DSN}/api/v1/emails', cabeçalhos={'X-API-KEY': CHAVE_API}, dados={ 'id_da_conta': ID_DA_CONTA, 'a': '[{"display_name":"Alice","identifier":"alice@acme.com"}]', 'assunto': 'Olá do Python', 'corpo': '

Enviado via Unipile!

'
} ) print(resposta.json())
Email entregue - 202 Aceito
Funciona com: Gmail Perspectivas IMAP
Resumo

Exemplo de Python de 5 linhas

Se você já sabe o que é uma API de Envio de E-mail e quero apenas o código Python para a API de e-mail que realmente funciona, aqui está. O tutorial completo segue abaixo.

1
Instalar requests
pip install requests python-dotenv
2
Definir variáveis de ambiente
Adicionar UNIPILE_DSN, UNIPILE_API_KEYe ID_DA_CONTA_UNIPILE para você .env arquivo.
3
Vincular uma conta de e-mail
OAuth para Gmail/Outlook ou credenciais SMTP para qualquer servidor IMAP. Uma chamada de API - você faz isso apenas uma vez por conta.
4
POST para /api/v1/emails
Passar account_id, para, assuntoe corpo. Feito.
O mesmo código Python funciona para Gmail, Outlook e qualquer servidor IMAP - sem necessidade de lógica específica do provedor. Verifique o Guia da API de E-mail para a visão geral completa do conceito.
send_email.py
import requisições, os from dotenv import carregar_dotenv carregar_dotenv() CHAVE_API = os.environ'UNIPILE_API_KEY'] DSN = os.environ'UNIPILE_DSN'] ID_DA_CONTA = os.environ'ID_DA_CONTA_UNIPILE'] resp = requests.postagem( f'{DSN}/api/v1/emails', cabeçalhos={'X-API-KEY': CHAVE_API}, dados={ 'id_da_conta': ID_DA_CONTA, 'a': '[{"display_name":"Alice","identifier":"alice@acme.com"}]', 'assunto': 'Olá do Python', 'corpo': '

Enviado via Unipile!

'
} ) print(resp.json()) # {'tracking_id': 'msg_...'}
Configuração

Pré-requisitos e Configuração

Antes de poder usar o fluxo de trabalho do Python da API de e-mail em produção, você precisa de quatro coisas: Python 3.9+, o solicitações biblioteca, uma chave de API com DSN e uma conta de e-mail vinculada.

Python 3.9+ (3.11 recomendado)
Todos os exemplos usam f-strings, | Tipos de união e recursos da biblioteca padrão do Python 3.9+. O Python 3.11 LTS é recomendado para produção. Verifique sua versão com python --version.
Chave de API e DSN da Unipile
Cadastre-se no painel Unipile para obter seu token de acesso e DSN (um endpoint HTTPS pessoal como api4.unipile.com:13444Ambos são obrigatórios em cada cabeçalho de requisição.
Ambiente virtual
Sempre use um venv para isolar dependências: python -m venv .venv && source .venv/bin/activate. Nunca instale pacotes no Python do sistema - isto é especialmente importante para o manuseio de credenciais.
Uma conta de e-mail vinculada
Você envia email através Uma conta vinculada (Gmail, Outlook ou IMAP). A próxima seção o guiará pelo fluxo OAuth para vincular uma. Você só faz isso uma vez por conta.
Instalando dependências
pip
pipenv
poesia
pip install requests python-dotenv # Opcional: suporte a async pip install aiohttp httpx # Opcional: lógica de retentativa pip install tenacity
pipenv install requests python-dotenv tenacity
poetry adicionar requests python-dotenv tenacity
.env
# Credenciais Unipile - nunca comite este arquivo UNIPILE_DSN=https://api4.unipile.com:13444 UNIPILE_API_KEY=seu_token_de_acesso_aqui # O ID da conta de e-mail vinculada ID_DA_CONTA_UNIPILE=acc_xxxxxxxxxxxxxxxx

Adicionar .env para você .gitignore. Carregar com python-dotenv via load_dotenv() no topo do seu script. Em produção, prefira variáveis de ambiente reais injetadas pela sua plataforma de implantação (Heroku, Railway, Docker Compose).

Pronto para enviar seu primeiro e-mail?
Obtenha uma chave de API gratuita - leva 30 segundos, sem necessidade de cartão de crédito.
Obtenha sua chave de API gratuita
Vinculação de Conta

Conectando Sua Primeira Conta de E-mail

Antes de enviar, você precisa vincular uma conta de e-mail ao Unipile. Este é um passo único por conta. Veja o completo guia de integração de API de e-mail unificada para mais informações sobre fluxos de múltiplas contas.

Unipile usa um assistente de autenticação hospedado - seu script Python gera um link de autenticação, o usuário clica nele e completa o OAuth no navegador, então Unipile chama seu webhook com o novo account_id. Nenhuma credencial SMTP é armazenada em seu código para Gmail ou Outlook.

GmailGmail OAuth
PerspectivasOutlook OAuth
IMAPIMAP / SMTP
connect_gmail.py
import requisições, os from dotenv import carregar_dotenv carregar_dotenv() CHAVE_API = os.environ'UNIPILE_API_KEY'] DSN = os.environ'UNIPILE_DSN'] # Passo 1: crie um link de autenticação hospedado para o OAuth do Gmail resp = requests.postagem( f'{DSN}/api/v1/hosted/contas/vincular', cabeçalhos={'X-API-KEY': CHAVE_API}, dados={ 'tipo': 'Google', 'nome': 'Alice Gmail', 'url_de_sucesso': 'https://seusite.com/oauth/success', 'url_de_falha': 'https://seuarquivo.com/oauth/failure' } ) # Passo 2: envie esta URL para o seu usuário auth_url = resp.json()['url'] print(Redirecione o usuário para: {auth_url}') # Etapa 3: Unipile POSTs {account_id} para o seu webhook após o OAuth # Veja /gmail-api-send-email-a-comprehensive-guide-for-developers/ para detalhes do Gmail
import requisições, os from dotenv import carregar_dotenv carregar_dotenv() # Outlook OAuth - abrange Outlook pessoal + Microsoft 365 # Veja /microsoft-graph-api-email-integration-guide/ resp = requests.postagem( f'{os.environ["UNIPILE_DSN"]}/api/v1/hosted/accounts/link', cabeçalhos={'X-API-KEY': os.environ['UNIPILE_API_KEY']}, dados={ 'tipo': 'MICROSOFT', 'nome': 'Bob Outlook', 'url_de_sucesso': 'https://seusite.com/oauth/success', 'url_de_falha': 'https://seuarquivo.com/oauth/failure' } ) print(resp.json()['url'])
import requests, os, json # IMAP: passe as credenciais SMTP/IMAP diretamente (sem necessidade de redirecionamento OAuth) # Veja /the-developers-guide-to-imap-api-solution/ para detalhes completos sobre a API IMAP resp = requests.postagem( f'{os.environ["UNIPILE_DSN"]}/api/v1/accounts', cabeçalhos={'X-API-KEY': os.environ['UNIPILE_API_KEY']}, json={ 'provedor': 'IMAP', 'nome de usuário': 'alice@company.com', 'senha': 'senha_aplicativo_aqui', 'imap_host': 'imap.company.com', 'smtp_host': 'smtp.company.com' } ) account_id = resp.json()['id_da_conta'] print(Conta vinculada: {account_id}')
Gmail
Gmail
Usa Google OAuth 2.0. Nenhuma senha armazenada. Atualização de token automática. Veja o Guia de envio de e-mail da API do Gmail para detalhes do escopo.
Perspectivas
Outlook / Microsoft 365
Usa OAuth do Microsoft Graph. Abrange Outlook pessoal e Microsoft 365 / Exchange Online. Veja o Guia de email do Microsoft Graph para fluxos de consentimento de administrador.
IMAP
IMAP / SMTP
Passe as credenciais diretamente. Funciona com qualquer servidor IMAP: Zoho, Yahoo, FastMail, Exchange personalizado. Veja o Guia da solução de API IMAP para configuração de porta.
API principal

Enviando seu primeiro e-mail em Python

O endpoint de envio aceita multipart/form-data. Usar dados= não json=) em requests.post(). O para, cce Cópia oculta os campos são strings codificadas em JSON dentro dos dados do formulário.

1
Email de texto simples
Básico
import requests, os, json pedidos.postagem( f'{os.environ["UNIPILE_DSN"]}/api/v1/emails', cabeçalhos={'X-API-KEY': os.environ['UNIPILE_API_KEY']}, dados={ 'id_da_conta': os.environ['ID_DA_CONTA_UNIPILE'], 'a': json.despejos([{'Nome de exibição': 'Alice', 'identificador': 'alice@acme.com'}]), 'assunto': 'Atualização rápida', 'corpo': 'Oi Alice, só de passagem.' } )
Observação: O corpo campo aceita texto puro e HTML. Use

tags de formatação HTML.

2
E-mail HTML com CC e Cco
Comum
import requests, os, json response = requests.postagem( f'{os.environ["UNIPILE_DSN"]}/api/v1/emails', cabeçalhos={'X-API-KEY': os.environ['UNIPILE_API_KEY']}, dados={ 'id_da_conta': os.environ['ID_DA_CONTA_UNIPILE'], 'a'json.despejos([{'identificador': 'alice@acme.com'}]), 'cc'json.despejos([{'identificador': 'manager@acme.com'}]), 'cópia oculta': json.despejos([{'identificador': 'crm@yourapp.com'}]), 'assunto': 'Seu boleto está pronto', 'corpo': '

Fatura #1042

Por favor, encontre sua fatura em anexo.

'
} ) # 202 Aceito = em fila para entrega print(response.status_code, response.json())
3
Tratamento de respostas
Produção
import requests, os, json def enviar_email(para_email: str, assunto: str, corpo: str) -> dicionário: "Enviar e-mail via wrapper Python da API de e-mail Unipile." response = requests.postagem( f'{os.environ["UNIPILE_DSN"]}/api/v1/emails', cabeçalhos={'X-API-KEY': os.environ['UNIPILE_API_KEY']}, dados={ 'id_da_conta': os.environ['ID_DA_CONTA_UNIPILE'], 'a'json.despejos([{'identificador': to_email}]), 'assunto': assunto, 'corpo'corpo, }, tempo_limite=30 ) resposta.raise_for_status() # levanta HTTPError em 4xx/5xx return resposta.json() # {'tracking_id': 'msg_...'}
Dica: Sempre passe tempo_limite=30 para evitar que trave para sempre em problemas de rede. Use raise_for_status() para propagar erros HTTP como exceções Python.
Grátis para começar
Experimente agora - chave de API grátis em 30 segundos

Obtenha sua chave de API, vincule uma conta do Gmail ou Outlook em minutos e execute os exemplos Python deste guia contra caixas de correio reais.

Anexos

Enviando Anexos em Python

Anexos são enviados como parte dos dados do formulário multipart usando Python's arquivos= parâmetro. Abra o arquivo em modo binário ('rb') - bytes, não strings.

anexar.py
import requests, os, json # Anexo de arquivo único com abra('nota fiscal.pdf', 'rb') como f: resp = requests.postagem( f'{os.environ["UNIPILE_DSN"]}/api/v1/emails', cabeçalhos={'X-API-KEY': os.environ['UNIPILE_API_KEY']}, dados={ 'id_da_conta': os.environ['ID_DA_CONTA_UNIPILE'], 'a': json.despejos([{'identificador': 'client@example.com'}]), 'assunto': 'Fatura em anexo', 'corpo': '

Por favor, veja a fatura em anexo.

'
}, arquivos={'anexos': ('nota fiscal.pdf', f, 'application/pdf')} ) # Múltiplos anexos: passe uma lista de tuplas # arquivos=[('anexos', ('a.pdf', f1, 'application/pdf')), # ('anexos', ('b.png', f2, 'image/png'))]
Sempre abra em modo binário
Uso open('arquivo.pdf', 'rb'), não 'r'. Passando um objeto de arquivo de texto para arquivos= levanta um TypeError. Isso é uma armadilha comum específica do Python ao migrar de smtplib.
Múltiplos anexos
Passe uma lista de tuplas para arquivos=: cada tupla é ('anexos', (nome_arquivo, objeto_arquivo, tipo_conteudo)). O Requests lida com o limite multipart automaticamente.
Arquivos em memória (BytesIO)
Para PDFs gerados dinamicamente ou exportações CSV, passe um BytesIO objeto direto: de io importe BytesIO; buf = BytesIO(pdf_bytes) então ('report.pdf', buf, 'application/pdf').
Limites do provedor: O Gmail permite até 25 MB no total por envio. O Outlook permite até 20 MB. Os limites do IMAP dependem da configuração do seu servidor. Para arquivos acima desses limites, envie um link para download em vez disso.
Precisa de anexos maiores ou limites de envio mais altos?
Os planos da Unipile escalam de protótipos a cargas de trabalho de produção. Compare as cotas na página de preços.
Unipile - API Python Avançada
Avançado

Respostas, Tópicos e Rastreamento

Para enviar email em nome de um usuário, encadeamento e rastreamento de entrega baseado em webhook, aqui estão os padrões Python que você precisa.

01
Encadeamento com in_reply_to

Para responder dentro de um tópico existente, passe o em_resposta_a campo com o id_rastreamento do email ao qual você deseja responder. A Unipile cuida do Referências e Em-Resposta-A cabeçalhos automaticamente.

reply.py
pedidos.postagem( f'{DSN}/api/v1/emails', cabeçalhos={'X-API-KEY': CHAVE_API}, dados={ 'id_da_conta': ID_DA_CONTA, 'a': json.despejos([{'identificador': 'alice@acme.com'}]), 'assunto': 'Re: Sua pergunta', 'corpo': '

Em seguimento à sua mensagem.

'
, 'em_resposta_a': 'id_rastreamento_original' } )
02
Webhooks em Python (exemplo com Flask)

Registre um URL de webhook em seu painel Unipile para receber eventos de entrega (enviado, falhado, aberto). Aqui está um receptor Flask mínimo:

webhook_flask.py
from garrafa import Flask, request, jsonify import registro aplicativo = Frasco(__nome__) registro.basicConfig(nível=logging.INFORMAÇÃO) @app.rota('/webhook/email', métodos=['POST']) def email_webhook(): evento = solicitação.obter_json() tipo_evento = evento.obter('tipo') tracking_id = evento.obter('id_de_rastreamento') registro.informações(f'Email do evento: {event_type} para {tracking_id}') return jsonifyOk=Verdadeiro), 200
03
Chaves de idempotência

Para evitar reenvios duplicados na tentativa de rede, passe um único Chave-Idempotente cabeçalho. Se a mesma chave for enviada duas vezes, a Unipile retorna a resposta original sem enviar um segundo e-mail.

idempotencia.py
import uuid, requisições, os, json chave = str(uuid.uuid4()) # gerar uma vez, armazenar no banco de dados pedidos.postagem( f'{os.environ["UNIPILE_DSN"]}/api/v1/emails', cabeçalhos={ 'X-API-KEY'os.environ['UNIPILE_API_KEY'], 'Chave de Idempotência'chave }, dados={'id_da_conta': os.environ['ID_DA_CONTA_UNIPILE'], 'a': json.despejos([{'identificador': 'alice@acme.com'}]), 'assunto': 'Bem-vindo!', 'corpo': 'Olá!'} )
Produção

Tratamento de Erros e Tentativas

O código Python de produção para a API de e-mail precisa de tratamento de exceções adequado, logging estruturado e retentativas automáticas com backoff exponencial usando o tenacidade biblioteca.

Código HTTPSignificadoAção
202Aceito - em fila para entregaArmazenar rastreamento_id
400Requisição inválida (campos inválidos)Corrigir carga útil, não tentar novamente
401Chave de API inválidaVerificar UNIPILE_API_KEY
403Conta não autorizadaReconectar conta
404ID da conta não encontradoVerificar UNIPILE_ACCOUNT_ID
429Taxa limitadaBackoff + nova tentativa (ver código)
500Erro do servidorTentar novamente após 5s de atraso
retry.py
import requests, os, json, logging from tenacidade import ( tentar novamente, parar_após_tentativa, wait_exponential, retry_if_exception_type ) registro.basicConfig(nível=logging.INFORMAÇÃO) logger = logging.getLogger(__nome__) aula Erro de Limite de Taxa(Exceção): passar @tentar novamente( parar=parar_após_tentativa(4), esperar=espera_exponencial(multiplicador=1, min=2, max=30), tentar novamente=tentar_novamente_se_tipo_exceção(Erro de Limite de Taxa) ) def enviar_com_nova_tentativaPara: str, assunto: str, corpo: str) -> dicionário: resp = requests.postagem( f'{os.environ["UNIPILE_DSN"]}/api/v1/emails', cabeçalhos={'X-API-KEY': os.environ['UNIPILE_API_KEY']}, dados={ 'id_da_conta': os.environ['ID_DA_CONTA_UNIPILE'], 'a'json.despejos([{'identificador': para}]), 'assunto': assunto, 'corpo'corpo }, tempo_limite=30 ) se resp.status_code == 429: registrador.Aviso('Limite de taxa atingido, recuando...') levantar Erro de Limite de Taxa() resp.raise_for_status() return resp.json()
Segurança

Melhores Práticas de Segurança em Python

Para um guia completo sobre como proteger sua integração de API de e-mail, consulte o Guia de segurança de API de e-mail. Aqui estão os essenciais específicos do Python.

Nunca codifique chaves diretamente no código
Uso os.environ ou python-dotenv. Nunca coloque UNIPILE_API_KEY como uma string literal em seu código-fonte. Se acidentalmente enviado para o Git, roteie a chave imediatamente em seu painel.
Ambientes virtuais
Sempre isole as dependências com venv ou conda. Isso impede ataques de confusão de dependência e torna sua requirements.txt auditable. Fixar versões em produção.
Renovação de token OAuth
Unipile lida com a atualização automática de tokens OAuth para Gmail e Outlook. Você nunca armazena ou rotaciona tokens do provedor por conta própria - apenas mantenha seu UNIPILE_API_KEY válido.
Somente do lado do servidor
Nunca chame a API da Unipile de código do lado do cliente (navegador ou aplicativo móvel). Em Flask/Django/FastAPI, sempre mantenha as chamadas de API em visualizações do lado do servidor ou em tarefas em segundo plano (Celery).
Validar cargas úteis de webhook
Ao receber webhooks da Unipile em Flask ou FastAPI, valide a origem da requisição via cabeçalho secreto ou assinatura HMAC antes de processar o evento. Nunca confie cegamente em payloads brutos recebidos.
Auditoria e registro em log
Registro id_rastreamento para cada email enviado para habilitar auditorias de entrega. Use o padrão Python registro módulo - nunca imprimir() em produção. Enviar logs para um SIEM para casos de uso com forte conformidade.
DKIM e SPF: Estas são configurações de nível de DNS, não código Python. Configure registros SPF e DKIM para seu domínio remetente. Leia o completo Guia de segurança de API de e-mail para configuração de DNS passo a passo.
Armadilhas

Armadilhas Comuns Específicas do Python

Estes são os erros mais comuns que desenvolvedores Python cometem ao integrar a API de e-mail. Se você estiver usando Node.js, veja nossa Tutorial de API de envio de e-mail com JavaScript.

Usando json= em vez de dados=
O endpoint de envio do Unipile requer multipart/form-data, não JSON. Use sempre requests.post(..., dados={...}). Usando json={...} retornará um erro 400. O para, cce Cópia oculta os campos são strings JSON dentro dos dados do formulário - use json.dumps() para codificar a matriz do destinatário.
Corrigir: usar data= com json.dumps() para arrays de destinatários
Abrindo arquivos em anexo no modo de texto
Sempre abrir anexos de arquivo com open('arquivo.pdf', 'rb') - modo binário. Modo texto ('r') levanta um TypeError quando passado para o arquivos= parâmetro. Para conteúdo em memória, use io.BytesIO.
Corrigir: sempre abrir arquivos como 'rb'
Misturando sincronia e assincronia (asyncio)
O solicitações a biblioteca é síncrona. Chamá-la dentro de um async def bloqueia o loop de eventos. Use httpx.AsyncClient ou aiohttp.ClientSession para contextos assíncronos do Python (FastAPI, views assíncronas do Django, scripts asyncio).
Corrigir: usar httpx.AsyncClient para contextos async/await
Tempo limite ausente em requisições
Por padrão, requests.post() espera para sempre. Uma conexão travada bloqueará sua thread (ou worker do Celery) indefinidamente. Sempre passe tempo_limite=30 (tempo limite de conexão, tempo limite de leitura em segundos).
Corrigir: sempre passe timeout=(5, 30) para requests.post()
Datetimes ingênuos de fuso horário em agendamento
Se você agendar e-mails com um campo de data e hora, sempre use datas e horas com reconhecimento de fuso horário: from datetime import datetime, timezone; datetime.now(timezone.utc). Datetimes ingênuas causam erros silenciosos de "off-by-hours" em implantações multirregionais.
Correção: sempre use timezone.utc para objetos datetime
Impacto do GIL em envios de alto volume encadeados
O GIL do Python limita o paralelismo real de threads para tarefas intensivas em CPU, mas requisições HTTP são intensivas em I/O - threads funcionam bem. Para envios de alto volume (1000+/dia), use um pool de threads (concurrent.futures.ThreadPoolExecutor) ou descarregar para uma fila Celery.
Corrigir: usar ThreadPoolExecutor ou Celery para envios em lote

Perguntas frequentes

Perguntas frequentes sobre o uso da API de e-mail em Python com a API unificada de e-mail da Unipile.

Use a API unificada de e-mail da Unipile em vez do smtplib ou de uma conexão SMTP direta. Instale solicitações, obtenha sua chave de API e DSN no painel do Unipile, vincule uma conta Gmail ou Outlook via OAuth, depois envie um POST para /api/v1/emails com o seu account_id, para, assuntoe corpo. Nenhum servidor SMTP, nenhuma porta 587, nenhuma configuração TLS necessária em seu código Python.

Django: chame a API em uma view ou comando de gerenciamento. Para Django assíncrono (3.1+), use httpx.AsyncClient em views assíncronas.

Frasco chame a API em um manipulador de rota do lado do servidor. Nunca a chame de um template Jinja ou de JS do lado do cliente. Use Flask-Celery para descarregar envios de alto volume para workers em segundo plano.

FastAPI: usar httpx.AsyncClient dentro async def endpoints. O síncrono solicitações biblioteca bloqueia o loop de eventos assíncrono - sempre use um cliente HTTP assíncrono no FastAPI.

smtplib conecta diretamente a um servidor SMTP a partir do seu processo Python. Você gerencia credenciais SMTP, configuração TLS e peculiaridades por provedor (senhas de aplicativo do Gmail, autenticação moderna do Outlook). Ele também é apenas síncrono.

A API de e-mail Unipile é uma abstração em nuvem: vincule contas via OAuth (sem credenciais SMTP no seu código para Gmail/Outlook), obtenha uma API HTTP única e consistente para todos os provedores, e a Unipile cuida do transporte, atualização de tokens e tentativas. A contrapartida é que os envios passam pela infraestrutura da Unipile em vez de uma conexão SMTP direta.

Sim, mas você precisa de um cliente HTTP async - o padrão solicitações biblioteca é síncrona e bloqueará seu event loop. Use httpx (recomendado, alternativa assíncrona substituível) ou aiohttp.

import httpx, os, json async def enviar_email_asyncPara: str, assunto: str, corpo: str): assíncrono com httpx.AsyncClient() como cliente: resp = await cliente.postagem( f'{os.environ["UNIPILE_DSN"]}/api/v1/emails', cabeçalhos={'X-API-KEY': os.environ['UNIPILE_API_KEY']}, dados={'id_da_conta': os.environ['ID_DA_CONTA_UNIPILE'], 'a': json.despejos([{'identificador': para}]), 'assunto': assunto, 'corpo': corpo} ) resp.raise_for_status() return resp.json()

Use uma fila de tarefas Celery com um broker Redis ou RabbitMQ. Cada e-mail se torna uma tarefa - o Celery gerencia a concorrência e as tentativas automaticamente. Limite a concorrência por worker para evitar limites de taxa (geralmente 5-10 envios simultâneos por conta vinculada). Para envios de marketing de alto volume (milhões/dia), combine o Unipile para envios transacionais baseados em OAuth com um ESP dedicado para campanhas em massa.

Para casos de uso mais leves, concurrent.futures.ThreadPoolExecutor(max_workers=5) com o solicitações A biblioteca é uma abordagem mais simples que evita a sobrecarga do Celery.

Sim. Crie uma tarefa Celery que chama requests.post() para o endpoint Unipile. Os workers do Celery são processos Python síncronos padrão, então solicitações funciona perfeitamente. Use o embutido do Celery autoretry_for=(requests.exceptions.HTTPError,) com max_tentativas=3 e atraso_padrao_tentativa=5 para nova tentativa automática em falhas transitórias. Combine com Chave-Idempotente cabeçalhos para prevenir envios duplicados em reinícios de worker.

Ainda tem dúvidas? Nossa equipe está aqui para ajudar.

pt_BRBR