Cómo enviar correos electrónicos a través de la API en Python (tutorial rápido)

Índice
Índice 11 secciones
Empezando
Enviar correos electrónicos
Producción
Referencia
Tutorial de Python

Cómo Enviar correo electrónico a través de API en Python (Tutorial Rápido)

Omite la información de configuración de SMTP. Esta guía te muestra cómo usar el API de correo electrónico unificado de Unipile para enviar correo electrónico en Python - con ejemplos de copiar y pegar para Gmail, Outlook e IMAP utilizando la función solicita biblioteca.

api de email en python api de envío de correo electrónico python Gmail / Outlook / IMAP solicitudes / aiohttp Flask / Django / FastAPI
send_email.py
import solicitudes, os CLAVE_API = os.environ['UNIPILE_API_KEY'] DSN = os.environ['UNIPILE_DSN'] ID_CUENTA = os.environ['UNIPILE_CUENTA_ID'] response = requests.Correo electrónico:( f'{DSN}/api/v1/correos', encabezados={'X-API-KEY': CLAVE_API}, datos={ 'id_cuenta': ID_CUENTA, 'a': '[{"display_name":"Alice","identifier":"alice@acme.com"}]', 'asunto': 'Hola desde Python', 'cuerpo': '

¡Enviado vía Unipile!

'
} ) print(respuesta.json())
Correo entregado - 202 Aceptado
Funciona con: Gmail Outlook IMAP
En resumen

Ejemplo de Python de 5 líneas

Si ya sabes qué es una API de envío de correo electrónico y solo quiero el código Python de la API de correo electrónico que funcione, aquí está. El tutorial completo sigue a continuación.

1
Instalar requests
pip install requests python-dotenv
2
Establecer variables de entorno
Añadir UNIPILE_DSN, UNIPILE_API_KEYy UNIPILE_ID_DE_CUENTA a tu .env archivo.
3
Vincular una cuenta de correo electrónico
Credenciales OAuth para Gmail/Outlook o SMTP para cualquier servidor IMAP. Una llamada a la API: solo la realizas una vez por cuenta.
4
PUBLICAR a /api/v1/emails
Pasar account_id, a, temay cuerpo. Hecho.
El mismo código Python funciona para Gmail, Outlook y cualquier servidor IMAP, no se necesita lógica específica del proveedor. Comprueba Guía de la API de correo electrónico Para la descripción general completa del concepto.
send_email.py
import solicitudes, os from dotenv import cargar_dotenv cargar_dotenv() CLAVE_API = os.environ['UNIPILE_API_KEY'] DSN = os.environ['UNIPILE_DSN'] ID_CUENTA = os.environ['UNIPILE_CUENTA_ID'] resp = requests.Correo electrónico:( f'{DSN}/api/v1/correos', encabezados={'X-API-KEY': CLAVE_API}, datos={ 'id_cuenta': ID_CUENTA, 'a': '[{"display_name":"Alice","identifier":"alice@acme.com"}]', 'asunto': 'Hola desde Python', 'cuerpo': '

¡Enviado vía Unipile!

'
} ) print(resp.json()) # {'tracking_id': 'msg_...'}
Configurar

Requisitos previos y configuración

Antes de poder usar el flujo de trabajo de Python de la API de correo electrónico en producción, necesita cuatro cosas: Python 3.9+, la solicita biblioteca, una clave de API con DSN y una cuenta de correo electrónico vinculada.

Python 3.9+ (3.11 recomendado)
Todos los ejemplos usan f-strings, | tipos de unión y características de la biblioteca estándar de Python 3.9+. Se recomienda Python 3.11 LTS para producción. Verifica tu versión con python --version.
Clave API y DSN de Unipile
Regístrate en el panel de control de Unipile para obtener tu token de acceso y DSN (un punto de conexión HTTPS personal como api4.unipile.com:13444. Ambos son necesarios en cada encabezado de solicitud.
Entorno virtual
Siempre usa un venv para aislar dependencias: python -m venv .venv && source .venv/bin/activate. Nunca instales paquetes en el Python del sistema, esto es especialmente importante para el manejo de credenciales.
Una cuenta de correo electrónico vinculada
Envías correo electrónico a través de una cuenta vinculada (Gmail, Outlook o IMAP). La siguiente sección te guiará a través del flujo de OAuth para vincular una. Solo haces esto una vez por cuenta.
Instalando dependencias
pip
pipenv
poesía
pip install requests python-dotenv # Opcional: soporte asíncrono pip install aiohttp httpx # Opcional: lógica de reintento pip install tenacity
pipenv install requests python-dotenv tenacity
poetry add requests python-dotenv tenacity
.env
# Credenciales de Unipile - nunca confirmes este archivo UNIPILE_DSN=https://api4.unipile.com:13444 UNIPILE_API_KEY=tu_token_de_acceso_aqui # La ID de la cuenta de correo electrónico vinculada UNIPILE_ID_DE_CUENTA=acc_xxxxxxxxxxxxxxxx

Añadir .env a tu .gitignore. Cargar con python-dotenv vía cargar_dotenv() en la parte superior de tu script. En producción, prefiere variables de entorno reales inyectadas por tu plataforma de despliegue (Heroku, Railway, Docker Compose).

¿Listo para enviar tu primer correo electrónico?
Obtén una clave API gratuita - toma 30 segundos, no se requiere tarjeta de crédito.
Obtenga su clave API gratuita
Vincular cuenta

Conectando tu primera cuenta de correo electrónico

Antes de poder enviar, necesitas vincular una cuenta de correo electrónico a Unipile. Este es un paso único por cuenta. Ver el completo guía de integración de API de correo electrónico unificada para más información sobre flujos de cuentas múltiples.

Unipile utiliza un asistente de autenticación alojado: tu script de Python genera un enlace de autenticación, el usuario hace clic en él y completa OAuth en el navegador, luego Unipile llama a tu webhook con el nuevo account_id. No se almacenan credenciales SMTP en tu código para Gmail o Outlook.

GmailOAuth de Gmail
OutlookOutlook OAuth
IMAPIMAP / SMTP
connect_gmail.py
import solicitudes, os from dotenv import cargar_dotenv cargar_dotenv() CLAVE_API = os.environ['UNIPILE_API_KEY'] DSN = os.environ['UNIPILE_DSN'] # Paso 1: crear un enlace de autenticación alojado para OAuth de Gmail resp = requests.Correo electrónico:( f'{DSN}/api/v1/hosted/accounts/link', encabezados={'X-API-KEY': CLAVE_API}, datos={ 'tipo': 'GOOGLE', 'nombre': 'Alice Gmail', 'url_exito': 'https://yourapp.com/oauth/success', 'url_fallo': 'https://yourapp.com/oauth/fallo' } ) # Paso 2: envía esta URL a tu usuario auth_url = resp.json()['url'] print(Dirigir al usuario a: {auth_url}') # Paso 3: Unipile publica POSTs de {account_id} en tu webhook después de OAuth # Ver /gmail-api-send-email-a-comprehensive-guide-for-developers/ para detalles de Gmail
import solicitudes, os from dotenv import cargar_dotenv cargar_dotenv() # Outlook OAuth - cubre Outlook personal + Microsoft 365 # Ver /microsoft-graph-api-email-integration-guide/ resp = requests.Correo electrónico:( f'{os.environ["UNIPILE_DSN"]}/api/v1/hosted/accounts/link', encabezados={'X-API-KEY'os.environ['UNIPILE_API_KEY']}, datos={ 'tipo': 'MICROSOFT', 'nombre': 'Bob Outlook', 'url_exito': 'https://yourapp.com/oauth/success', 'url_fallo': 'https://yourapp.com/oauth/fallo' } ) print(resp.json()['url'])
import requests, os, json # IMAP: pase las credenciales SMTP/IMAP directamente (no se necesita redirección OAuth) # Ver /the-developers-guide-to-imap-api-solution/ para obtener detalles completos de la API de IMAP resp = requests.Correo electrónico:( f'{os.environ["UNIPILE_DSN"]}/api/v1/cuentas', encabezados={'X-API-KEY'os.environ['UNIPILE_API_KEY']}, json={ 'proveedor': 'IMAP', 'nombre de usuario': 'alice@company.com', 'contraseña': 'contraseña_de_aplicación_aquí', 'imap_host': 'imap.company.com', 'smtp_host': 'smtp.company.com' } ) account_id = resp.json()['id_cuenta'] print(Cuenta vinculada: {account_id}')
Gmail
Gmail
Usa Google OAuth 2.0. No se almacenan contraseñas. La renovación de tokens es automática. Ver Guía de envío de correos electrónicos con la API de Gmail para detalles del alcance.
Outlook
Outlook / Microsoft 365
Usa OAuth de Microsoft Graph. Cubre Outlook personal y Microsoft 365 / Exchange Online. Ver el Guía de correo electrónico de Microsoft Graph para flujos de consentimiento de administrador.
IMAP
IMAP / SMTP
Pasa las credenciales directamente. Funciona con cualquier servidor IMAP: Zoho, Yahoo, FastMail, Exchange personalizado. Ver la Guía de solución de API IMAP para la configuración del puerto.
API principal

Enviando tu primer correo electrónico desde Python

El punto de conexión de envío acepta multipart/form-data. Usa datos= no jsonen requests.post(). El a, ccy con copia oculta los campos son cadenas codificadas en JSON dentro de los datos del formulario.

1
Correo electrónico de texto sin formato
Básico
import requests, os, json solicitudes.Correo electrónico:( f'{os.environ["UNIPILE_DSN"]}/api/v1/correos', encabezados={'X-API-KEY'os.environ['UNIPILE_API_KEY']}, datos={ 'id_cuenta'os.environ['UNIPILE_CUENTA_ID'], 'a': json.vertidos([{'nombre_en_pantalla': 'Alicia', 'identificador': 'alice@acme.com'}]), 'asunto': 'Actualización rápida', 'cuerpo': 'Hola Alice, solo quería contactarte.' } )
Nota: En cuerpo El campo acepta texto plano y HTML. Usa

etiquetas para formato HTML.

2
Correos electrónicos HTML con CC y CCO
Común
import requests, os, json response = requests.Correo electrónico:( f'{os.environ["UNIPILE_DSN"]}/api/v1/correos', encabezados={'X-API-KEY'os.environ['UNIPILE_API_KEY']}, datos={ 'id_cuenta'os.environ['UNIPILE_CUENTA_ID'], 'a'json.vertidos([{'identificador': 'alice@acme.com'}]), 'cc'json.vertidos([{'identificador': 'manager@acme.com'}]), 'CCO': json.vertidos([{'identificador': 'crm@yourapp.com'}]), 'asunto': 'Tu factura está lista', 'cuerpo': '

Factura #1042

Por favor, encuentre su factura adjunta.

'
} ) # 202 Aceptado = en cola para entrega print(código_estado.respuesta, respuesta.json())
3
Gestión de respuestas
Producción
import requests, os, json def enviar_correopara_correo: cadena, asunto: cadena, cuerpo: cadena) -> diccionario: """Enviar correo electrónico a través del wrapper de Python de la API de correo electrónico de Unipile.""" response = requests.Correo electrónico:( f'{os.environ["UNIPILE_DSN"]}/api/v1/correos', encabezados={'X-API-KEY'os.environ['UNIPILE_API_KEY']}, datos={ 'id_cuenta'os.environ['UNIPILE_CUENTA_ID'], 'a'json.vertidos([{'identificador': para_correo}]), 'asunto': asunto, 'cuerpo'cuerpo, }, tiempo de espera=30 ) respuesta.lanzar_para_estado() # genera HTTPError en 4xx/5xx return respuesta.json() # {'tracking_id': 'msg_...'}
Consejo: Siempre pasa tiempo de espera=30 para evitar que se cuelgue para siempre en problemas de red. Usar raise_for_status() para propagar errores HTTP como excepciones de Python.
Gratis para empezar
Pruébalo ahora: clave de API gratuita en 30 segundos

Obtenga su clave de API, vincule una cuenta de Gmail o Outlook en minutos y ejecute los ejemplos de Python de esta guía contra buzones reales.

Archivos adjuntos

Enviar archivos adjuntos en Python

Los archivos adjuntos se envían como parte de los datos del formulario multipart usando Python archivos= parámetro. Abre el archivo en modo binario ('rb') - bytes, no cadenas.

adjuntar.py
import requests, os, json # Adjunto de un solo archivo con abrir('factura.pdf', 'rb') como f: resp = requests.Correo electrónico:( f'{os.environ["UNIPILE_DSN"]}/api/v1/correos', encabezados={'X-API-KEY'os.environ['UNIPILE_API_KEY']}, datos={ 'id_cuenta'os.environ['UNIPILE_CUENTA_ID'], 'a': json.vertidos([{'identificador': 'client@example.com'}]), 'asunto': 'Factura adjunta', 'cuerpo': '

Por favor, vea la factura adjunta.

'
}, archivos={'adjuntos': ('factura.pdf', f, 'application/pdf')} ) # Múltiples adjuntos: pasar una lista de tuplas # archivos=[('adjuntos', ('a.pdf', f1, 'application/pdf')), # ('adjuntos', ('b.png', f2, 'image/png'))]
Siempre abierto en modo binario
Utilice abrir('archivo.pdf', 'rb'), no 'r'. Pasar un objeto de archivo de texto a archivos= plantea Error de tipo. Esta es una peculiaridad común específica de Python al migrar desde smtplib.
Múltiples adjuntos
Pasar una lista de tuplas a archivos=cada tupla es ('adjuntos', (nombre_archivo, objeto_archivo, tipo_contenido)). Requests maneja el límite multipart automáticamente.
Archivos en memoria (BytesIO)
Para PDFs generados dinámicamente o exportaciones CSV, pase un BytesIO objeto directamente desde io import BytesIO; buf = BytesIO(pdf_bytes) entonces ('informe.pdf', buf, 'application/pdf').
Límites del proveedor: Gmail permite hasta 25 MB en total por envío. Outlook permite hasta 20 MB. Los límites de IMAP dependen de la configuración de su servidor. Para archivos que superen estos límites, envíe un enlace de descarga en su lugar.
¿Necesitas archivos adjuntos más grandes o límites de envío más altos?
Unipile planea escalar desde prototipos hasta cargas de trabajo de producción. Compare las cuotas en la página de precios.
Unipile - API avanzada de Python
Avanzado

Respuestas, Hilos y Seguimiento

Para enviar un correo electrónico en nombre de un usuario, concurrencia, y seguimiento de entrega basado en webhooks, estos son los patrones de Python que necesitas.

01
Enhebrar con in_reply_to

Para responder dentro de un hilo existente, pase la en_respuesta_a campo con el seguimiento_id del correo electrónico al que desea responder. Unipile se encarga del Referencias y En respuesta a encabezados automáticamente.

reply.py
solicitudes.Correo electrónico:( f'{DSN}/api/v1/correos', encabezados={'X-API-KEY': CLAVE_API}, datos={ 'id_cuenta': ID_CUENTA, 'a': json.vertidos([{'identificador': 'alice@acme.com'}]), 'asunto': 'Re: Tu pregunta', 'cuerpo': '

Dando seguimiento a tu mensaje.

'
, 'en_respuesta_a': 'ID de seguimiento original' } )
02
Webhooks en Python (ejemplo con Flask)

Registre una URL de webhook en su panel de Unipile para recibir eventos de entrega (enviado, rebotado, abierto). Aquí hay un receptor básico de Flask:

webhook_flask.py
from frasco import Flask, request, jsonify import registro apartamento = Matraz(__nombre__) registro.basicConfig(nivel=logging.INFORMACIÓN) @app.ruta('/webhook/email', métodos=[POST]) def webhook_de_correo_electronico(): evento = solicitud.get_json() tipo_evento = evento.consiga('tipo') tracking_id = evento.consiga('id_de_seguimiento') registro.información(f'Correo electrónico del evento: {event_type} para {tracking_id}') return convertir a JSONok=Verdadero), 200
03
Claves de idempotencia

Para evitar envíos duplicados en reintentos de red, pasa un único Clave-Idempotencia header. Si la misma clave se envía dos veces, Unipile devuelve la respuesta original sin enviar un segundo correo electrónico.

idempotencia.py
import uuid, solicitudes, os, json clave = cadenauuid.uuid4()) # generar una vez, almacenar en DB solicitudes.Correo electrónico:( f'{os.environ["UNIPILE_DSN"]}/api/v1/correos', encabezados={ 'X-API-KEY'os.environ['UNIPILE_API_KEY'], 'Clave de Idempotencia'llave }, datos={'id_cuenta'os.environ['UNIPILE_CUENTA_ID'], 'a': json.vertidos([{'identificador': 'alice@acme.com'}]), 'asunto': '¡Bienvenido!', 'cuerpo': '¡Hola!'} )
Producción

Manejo de Errores y Reintentos

El código Python de producción para la API de correo electrónico necesita un manejo de excepciones adecuado, registro estructurado y reintentos automáticos con retroceso exponencial utilizando tenacidad biblioteca.

Código HTTPSignificadoAcción
202Aceptado - en cola para entregaGuardar tracking_id
400Solicitud incorrecta (campos inválidos)Fix payload, no reintentar
401Clave de API no válidaComprobar UNIPILE_API_KEY
403Cuenta no autorizadaRestablecer enlace de cuenta
404Cuenta no encontradaVerificar UNIPILE_ACCOUNT_ID
429Tasa limitadaRetraso + reintentar (ver código)
500Error del servidorReintentar después de 5 segundos
retry.py
import requests, os, json, logging from tenacidad import ( reintentar, detener_después_del_intento, espera_exponencial, reintentar_si_tipo_excepcion ) registro.basicConfig(nivel=logging.INFORMACIÓN) logger = logging.obtenerLogger(__nombre__) clase ErrorDeLímiteDeTasa(Excepción): Pasa @reintentar( parar=detener_después_del_intento(4), esperaespera_exponencial(multiplicador=1, mínimo=2, máximo=30), reintentar=reiniciar_si_es_tipo_excepcion(ErrorDeLímiteDeTasa) ) def enviar_con_reintentoa: cadena, asunto: cadena, cuerpo: cadena) -> diccionario: resp = requests.Correo electrónico:( f'{os.environ["UNIPILE_DSN"]}/api/v1/correos', encabezados={'X-API-KEY'os.environ['UNIPILE_API_KEY']}, datos={ 'id_cuenta'os.environ['UNIPILE_CUENTA_ID'], 'a'json.vertidos([{'identificador': a}]), 'asunto': asunto, 'cuerpo'cuerpo }, tiempo de espera=30 ) si resp.status_code == 429: registrador.advertencia('Límite de tasa alcanzado, retrocediendo...') elevar ErrorDeLímiteDeTasa() resp.lanzar_para_estado() return resp.json()
Seguridad

Buenas prácticas de seguridad en Python

Para una guía completa sobre cómo proteger tu integración de API de correo electrónico, consulta la Guía de seguridad de API de correo electrónico. Aquí están los elementos esenciales específicos de Python.

Nunca codifiques claves en el código
Utilice os.environ o python-dotenv. Nunca pongas UNIPILE_API_KEY como un literal de cadena en tu código fuente. Si se sube accidentalmente a Git, rota la clave inmediatamente desde tu panel de control.
Entornos virtuales
Siempre aísla las dependencias con venv o conda. Esto previene ataques de confusión de dependencias y hace tu requirements.txt Auditable. Fija versiones en producción.
Renovación de token OAuth
Unipile maneja el refresco de tokens OAuth automáticamente para Gmail y Outlook. Nunca almacenas ni rotas tokens de proveedor tú mismo, solo mantén tu UNIPILE_API_KEY válido.
Solo del lado del servidor
Nunca llames a la API de Unipile desde código del lado del cliente (navegador o aplicación móvil). En Flask/Django/FastAPI, mantén siempre las llamadas a la API en vistas del lado del servidor o tareas en segundo plano (Celery).
Validar cargas útiles de webhook
Al recibir webhooks de Unipile en Flask o FastAPI, valida el origen de la solicitud a través de la cabecera secreta o la firma HMAC antes de procesar el evento. Nunca confíes ciegamente en los payloads entrantes sin procesar.
Auditoría y registro
Registro seguimiento_id por cada correo electrónico enviado para habilitar auditorías de entrega. Utiliza el estándar de Python registro módulo - nunca imprimir() en producción. Envíe los registros a un SIEM para casos de uso en los que el cumplimiento de normativas sea importante.
DKIM y SPF: Estas son configuraciones a nivel de DNS, no código Python. Configura los registros SPF y DKIM para tu dominio de envío. Lee el completo Guía de seguridad de API de correo electrónico para la configuración paso a paso del DNS.
Trampas

Errores comunes específicos de Python

Estos son los errores más comunes que cometen los desarrolladores de Python al integrar la API de correo electrónico. Si en cambio estás en Node.js, consulta nuestra Tutorial de API para enviar correos electrónicos con JavaScript.

Utilizando json en vez de datos=
El endpoint de envío de Unipile requiere multipart/form-data, no JSON. Utiliza siempre requests.post(..., data={...}). Utilización de json={...} devolverá un error 400. La a, ccy con copia oculta los campos son cadenas JSON dentro de los datos del formulario - usar json.dumps() para codificar la matriz de destinatarios.
Corrección: uso de data= con json.dumps() para matrices de destinatarios
Abrir archivos adjuntos en modo texto
Siempre abre los archivos adjuntos con abrir('archivo.pdf', 'rb') - modo binario. Modo de texto'r') plantea un Error de tipo cuando se pasa a la archivos= parámetro. Para el contenido en memoria, utilice io.BytesIO.
Corregir: abrir siempre archivos como 'rb'
Mezclar síncrono y asíncrono (asyncio)
En solicita library es síncrona. Llamarla dentro de un async def bloquea el bucle de eventos. Usa httpx.AsyncClient o aiohttp.ClientSession para contextos asíncronos de Python (FastAPI, vistas asíncronas de Django, scripts de asyncio).
Corrección: utilizar httpx.AsyncClient para contextos async/await
Tiempo de espera de solicitud faltante
Por defecto, requests.post() espera para siempre. Una conexión colgada bloqueará su hilo (o Celery worker) indefinidamente. Pase siempre tiempo de espera=30 (tiempo de espera de conexión, tiempo de espera de lectura en segundos).
Corregir: siempre pase timeout=(5, 30) a requests.post()
Fechas y horas sin zona horaria en la planificación
Si programa correos electrónicos con un campo de marca de tiempo, utilice siempre fechas y horas con conocimiento de la zona horaria: desde datetime import datetime, timezone; datetime.now(timezone.utc). Las fechas y horas ingenuas causan errores silenciosos de horas de diferencia en despliegues multirregión.
Corregir: siempre usar timezone.utc para objetos datetime
Impacto del GIL en envíos de alto volumen con hilos
El GIL de Python limita el paralelismo real de hilos para trabajos limitados por CPU, pero las solicitudes HTTP están limitadas por E/S, por lo que los hilos funcionan bien. Para envíos de alto volumen (1000+/día), use un grupo de hilos.ThreadPoolExecutor concurrente.futuroso descargar a una cola de Celery.
Corregir: usar ThreadPoolExecutor o Celery para envíos en lotes

Preguntas frecuentes

Preguntas frecuentes sobre el uso de la API de correo electrónico en Python con la API unificada de correo electrónico de Unipile.

Utilice la API unificada de correo electrónico de Unipile en lugar de smtplib o una conexión SMTP directa. Instalar solicita, obtén tu clave de API y DSN del panel de control de Unipile, vincula una cuenta de Gmail u Outlook a través de OAuth, y luego haz POST a /api/v1/emails contigo account_id, a, temay cuerpo. No es necesario configurar ningún servidor SMTP, puerto 587 ni TLS en su código Python.

Django: llame a la API en una vista o comando de administración. Para Django asíncrono (3.1+), use httpx.AsyncClient en vistas asíncronas.

Frasco llama la API en un manejador de rutas del lado del servidor. Nunca la llames desde una plantilla Jinja o JavaScript del lado del cliente. Usa Flask-Celery para descargar envíos de alto volumen a trabajadores en segundo plano.

FastAPI: usar httpx.AsyncClient dentro async def endpoints. El síncrono solicita La biblioteca bloquea el bucle de eventos asincrónicos: siempre use un cliente HTTP asincrónico en FastAPI.

smtplib se conecta directamente a un servidor SMTP desde tu proceso de Python. Tú gestionas las credenciales SMTP, la configuración TLS y las peculiaridades por proveedor (contraseñas de aplicación de Gmail, autenticación moderna de Outlook). También es exclusivamente síncrono.

La API de correo electrónico Unipile es una abstracción en la nube: vincula cuentas a través de OAuth (sin credenciales SMTP en tu código para Gmail/Outlook), obtén una única API HTTP consistente para todos los proveedores, y Unipile maneja el transporte, la actualización de tokens y los reintentos. La contrapartida es que los envíos pasan por la infraestructura de Unipile en lugar de una conexión SMTP directa.

Sí, pero necesitas un cliente HTTP asíncrono, el estándar solicita La biblioteca es síncrona y bloqueará tu bucle de eventos. Usa httpx (recomendado, alternativa asíncrona de inserción) o aiohttp.

import httpx, os, json async def enviar_correo_asincrónicamentea: cadena, asunto: cadena, cuerpo: cadena): asincrono con httpx.AsyncClient() como cliente: resp = await cliente.Correo electrónico:( f'{os.environ["UNIPILE_DSN"]}/api/v1/correos', encabezados={'X-API-KEY'os.environ['UNIPILE_API_KEY']}, datos={'id_cuenta'os.environ['UNIPILE_CUENTA_ID'], 'a': json.vertidos([{'identificador': a}]), 'asunto': asunto, 'cuerpo': cuerpo} ) resp.lanzar_para_estado() return resp.json()

Usa una cola de tareas de Celery con un broker Redis o RabbitMQ. Cada correo electrónico se convierte en una tarea: Celery maneja la concurrencia y los reintentos automáticamente. Limita la concurrencia por trabajador para evitar límites de tasa (típicamente 5-10 envíos concurrentes por cuenta vinculada). Para envíos de marketing de muy alto volumen (millones/día), combina Unipile para envíos transaccionales basados en OAuth con un ESP dedicado para campañas masivas.

Para casos de uso más ligeros, concurrent.futures.ThreadPoolExecutor(max_workers=5) con el solicita la biblioteca es un enfoque más simple que evita la sobrecarga de Celery.

Sí. Crea una tarea de Celery que llame requests.post() al endpoint de Unipile. Los workers de Celery son procesos estándar sincronizados de Python, así que solicita Funciona perfectamente. Usa el Celery incorporado autoretry_for=(requests.exceptions.HTTPError,) con max_reintentos=3 y retraso_reintento_predeterminado=5 para reintentos automáticos ante fallos transitorios. Combinar con Clave-Idempotencia encabezados para evitar envíos duplicados en reinicios de trabajadores.

¿Aún tiene preguntas? Nuestro equipo está aquí para ayudarle.

es_ESES