Vamos a conocer un módulo bastante especial que nos permitirá agregar una funcionalidad crítica en nuestro framework: el envío de correos electrónicos, lo cual, es ideal para enviar correos a un usuario autenticado en Flask.
Debemos recordar que Flask es un micro-framework, lo que significa que incorpora las mínimas funcionalidades necesarias para operar. Por ello, herramientas que hoy en día son vitales, como el envío de emails, no vienen incluidas de serie. Para suplir esta necesidad, utilizaremos la extensión Flask-Mail.
Flask Mail, permite enviar correos electrónicos mediante un cliente SMTP previamente configurado en la aplicación en Flask.
Instalación
Para obtener este paquete, realizaremos el mismo proceso que con módulos anteriores mediante el comando pip:
$ pip install flask-mailEl paquete es bastante liviano, por lo que la instalación apenas demorará unos segundos. Una vez instalado, podemos levantar nuestra aplicación perfectamente.
️ Configuración e Inicialización
Para dar los primeros pasos, debemos importar el módulo e inicializarlo con la instancia de nuestra aplicación (app).
from flask_mail import Mail
# ... después de declarar la app
mail = Mail(app)Configuraremos el servidor SMTP al cual vamos a conectarnos en el archivo de configuración:
app\my_app\config.py
class DevConfig(Config):
MAIL_SERVER = 'localhost'
MAIL_PORT = 25
MAIL_USERNAME = 'username'
MAIL_PASSWORD = 'password' Y en el modo de desarrollo, también habilitamos:
app\my_app\config.py
class DevConfig(Config):
***
MAIL_DEBUG = True
MAIL_SUPPRESS_SEND = False
TESTING = TrueRegistramos la extensión de manera global a nivel de la aplicación:
app\my_app\__init__.py
from flask_mail import Mail
***
mail = Mail()
mail.init_app(app)Es un esquema similar al que usamos con Bootstrap o la protección CSRF. Al pasarle la instancia de la aplicación, el módulo queda listo para realizar las configuraciones.
Debes asegurarte de que las configuraciones de la app se carguen antes de inicializar el objeto Mail. Si lo haces al revés, podrías encontrarte con errores de conexión, ya que el módulo intentará conectarse sin conocer los parámetros del servidor.
⚙️ Parámetros del Servidor de Correo
En el archivo de configuración (ya sea en base_config o en el de tu ambiente específico), debemos definir los parámetros del servidor SMTP. Aquí te explico los más importantes:
- MAIL_SERVER: El servidor de salida (ej. smtp.gmail.com o localhost).
- MAIL_PORT: Generalmente el 25, 465, 587 o 2525.
- MAIL_USE_TLS / MAIL_USE_SSL: Para encriptar la comunicación.
- MAIL_USERNAME / MAIL_PASSWORD: Tus credenciales de acceso.
- MAIL_DEFAULT_SENDER: El correo que aparecerá como remitente por defecto.
- MAIL_SUPPRESS_SEND: Si está en True, los correos no se enviarán realmente. Es ideal para entornos de desarrollo para no gastar cuotas de envío.
Pruebas con Mailtrap
Para no tener que configurar un servidor real de Gmail o contratar un hosting, utilizaremos Mailtrap, un servicio gratuito que intercepta los correos salientes y los muestra en una bandeja de entrada virtual.
Una vez registrados en Mailtrap, seleccionamos la integración con Flask y el servicio nos proporcionará los datos de servidor, puerto, usuario y contraseña que debemos pegar en nuestro archivo de configuración.
Envío de Mensajes
Para enviar un correo, utilizaremos la clase Message. Podemos definir el asunto, los destinatarios (como una lista) y el cuerpo del mensaje.
1. Mensaje Básico (Texto y HTML)
Puedes enviar contenido en texto plano mediante .body o en formato enriquecido mediante .html. Si defines ambos, el cliente de correo priorizará el HTML.
from flask_mail import Message
msg = Message("Hola Flask", recipients=["andres@desarrollolibre.net"])
msg.body = "Hola mundo en texto plano"
msg.html = "<b>Hola mundo en negritas</b>"
mail.send(msg)2. Adjuntar Archivos
También podemos "atachar" archivos. Es muy útil para enviar imágenes o documentos. Necesitamos abrir el archivo en modo binario y usar la función attach.
with app.open_resource("static/logo.png") as fp:
msg.attach("logo.png", "image/png", fp.read())3. Personalizar el Remitente
Puedes configurar el remitente de forma más elegante pasando una tupla en lugar de solo un string, para que aparezca un nombre descriptivo:
MAIL_DEFAULT_SENDER = ("Andrés de Desarrollo Libre", "andres@email.com")4. Código completo
El siguiente código lo puedes tener de referencia para enviar emails según las configuraciones realizadas anteriormente:
from flask_mail import Message
from my_app import mail
def send_email():
msg = Message(body="Text Example",
sender="no-reply@MyWeb.net",
recipients=["andres@gmail.com"], subject="Subject")
try:
print(mail.send(msg))
except Exception as e:
print(e)Si quieres definir contenido HTML:
msg = Message("Hello", sender=("Me", "me@example.com"))
msg.html = "<b>testing</b>"O simplemente texto:
msg = Message("Hello", sender=("Me", "me@example.com"))
msg.body = "testing"