lunes, 23 de marzo de 2026

Automatizacion con Python - Cap2 - parte 4

Capítulo 02 // Parte 4

Enviar Notificaciones por Email

Python Automation Cookbook — Alertas Automáticas vía SMTP

El correo electrónico se ha convertido en una herramienta ineludible para el uso diario. Es posiblemente el mejor lugar para enviar una notificación si una tarea automatizada ha detectado algo.

Por otro lado, las bandejas de entrada de correo electrónico ya están demasiado llenas de mensajes de spam, así que ten cuidado. Los filtros de spam también son una realidad. Ten cuidado con a quién envías correos electrónicos y el número de correos a enviar.

REQUISITOS

Preparación

Para esta receta, requerimos una cuenta de correo electrónico válida configurada, que incluye:

  • Servidor SMTP: Servidor de correo válido usando el protocolo SMTP
  • Puerto: Puerto para conectarse (465 para SSL, 587 para TLS)
  • Dirección: Tu dirección de correo electrónico
  • Contraseña: Contraseña o contraseña de aplicación
Algunos servicios de correo electrónico, como Gmail, te animarán a configurar 2FA. Típicamente, te permitirán crear una contraseña específica para apps a usar, evitando la solicitud de 2FA.
CÓDIGO

Script de Envío de Email

email_task.py
import argparse
import configparser
import smtplib
from email.message import EmailMessage

def main(to_email, server, port, from_email, password):
    print(f'With love, from {from_email} to {to_email}')
    
    # Crear el mensaje
    subject = 'With love, from ME to YOU'
    text = '''This is an example test'''
    
    msg = EmailMessage()
    msg.set_content(text)
    msg['Subject'] = subject
    msg['From'] = from_email
    msg['To'] = to_email
    
    # Abrir comunicación y enviar
    server = smtplib.SMTP_SSL(server, port)
    server.login(from_email, password)
    server.send_message(msg)
    server.quit()

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('email', type=str, help='destination email')
    parser.add_argument('-c', dest='config', type=argparse.FileType('r'),
                        help='config file', default=None)
    
    args = parser.parse_args()
    
    if not args.config:
        print('Error, a config file is required')
        parser.print_help()
        exit(1)
    
    config = configparser.ConfigParser()
    config.read_file(args.config)
    
    main(args.email,
         server=config['DEFAULT']['server'],
         port=config['DEFAULT']['port'],
         from_email=config['DEFAULT']['email'],
         password=config['DEFAULT']['password'])

Archivo de Configuración

email_conf.ini
[DEFAULT]
email = TU_EMAIL@gmail.com
server = smtp.gmail.com
port = 465
password = TU_PASSWORD

Proteger el Archivo de Configuración

TERMINAL
$ chmod 600 email_conf.ini
# Permisos 600 = solo lectura/escritura para el propietario

Ejecutar el Script

TERMINAL
$ python3 email_task.py -c email_conf.ini destino@server.com
With love, from TU_EMAIL@gmail.com to destino@server.com
AVANZADO

Email con HTML y Texto Plano

email_html.py
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

USER = 'your.account@gmail.com'
PASSWORD = 'YourPassword'
sent_from = USER
send_to = [USER]

# Versión texto plano
text = """Hi!
This is the text version linking to https://www.packtpub.com/
Cheers!"""

# Versión HTML
html = """<html><head></head><body>
<p>Hi!<br>
This is the HTML version linking to 
<a href="https://www.packtpub.com/">Packt</a><br>
</p>
</body></html>"""

# Componer mensaje
msg = MIMEMultipart('alternative')
msg['Subject'] = 'An interesting email'
msg['From'] = sent_from
msg['To'] = ', '.join(send_to)

# Añadir partes
part_plain = MIMEText(text, 'plain')
part_html = MIMEText(html, 'html')
msg.attach(part_plain)
msg.attach(part_html)  # La última es la preferida

# Enviar
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as server:
    server.login(USER, PASSWORD)
    server.sendmail(sent_from, send_to, msg.as_string())
La última parte añadida es la alternativa preferida según el formato MIME, así que añadimos la parte HTML al final. Hacer una versión de texto plano es una buena práctica.
EXTRAS

Añadir Adjuntos

adjuntos.py
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage

message = MIMEMultipart()

# Añadir texto
part1 = MIMEText('some text', 'plain')
message.attach(part1)

# Añadir imagen
with open('path/image', 'rb') as image:
    part2 = MIMEImage(image.read())
message.attach(part2)
Aunque es posible etiquetar sent_from como una dirección diferente a la usada para enviar, no se recomienda. Esto puede interpretarse como un intento de falsificar el origen del email y provocar que sea etiquetado como spam.

Resumen del Capítulo 2

01 // Preparar una Tarea

Estructurar tareas para ejecución autónoma con puntos de entrada claros y sin interactividad.

02 // Configurar Cron

Programar tareas periódicas en Unix/Linux con sintaxis crontab.

03 // Capturar Errores

Implementar logging robusto con el módulo logging de Python.

04 // Notificaciones Email

Enviar correos programáticamente usando SMTP con HTML y adjuntos.