ff7da29638
smtp_send: conecta+envia+cierra en un paso via smtplib (TLS/STARTTLS/plain). email_build_html: construye EmailMessagePy frozen dataclass con cuerpo HTML. Solo stdlib Python: smtplib, email.mime. Tests con mock SMTP server threading. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
68 lines
2.7 KiB
Markdown
68 lines
2.7 KiB
Markdown
---
|
|
name: smtp_send
|
|
kind: function
|
|
lang: py
|
|
domain: infra
|
|
version: "1.0.0"
|
|
purity: impure
|
|
signature: "smtp_send(cfg: SMTPConfigPy, from_addr: str, to: list[str], subject: str, body_html: str = '', body_text: str = '', cc: list[str] | None = None, bcc: list[str] | None = None, attachments: list[EmailAttachmentPy] | None = None, headers: dict[str, str] | None = None) -> None"
|
|
description: "Conecta al servidor SMTP, construye el mensaje MIME y envia el email en un solo paso. Soporta TLS directo (port 465), STARTTLS (port 587) y sin cifrado (port 25). Cierra la conexion automaticamente."
|
|
tags: [email, smtp, send, python, smtplib, mime, tls]
|
|
uses_functions: []
|
|
uses_types: []
|
|
returns: []
|
|
returns_optional: false
|
|
error_type: "error_go_core"
|
|
imports: ["smtplib", "email.mime.multipart", "email.mime.text", "email.mime.base", "email.encoders", "dataclasses"]
|
|
params:
|
|
- name: cfg
|
|
desc: "configuracion SMTP: host, port, username, password, tls_mode ('tls', 'starttls' o '')"
|
|
- name: from_addr
|
|
desc: "direccion del remitente"
|
|
- name: to
|
|
desc: "lista de destinatarios principales"
|
|
- name: subject
|
|
desc: "asunto del correo"
|
|
- name: body_html
|
|
desc: "cuerpo HTML (opcional; puede estar vacio si body_text esta presente)"
|
|
- name: body_text
|
|
desc: "cuerpo de texto plano (opcional; puede estar vacio si body_html esta presente)"
|
|
- name: cc
|
|
desc: "lista de destinatarios en copia visible (opcional)"
|
|
- name: bcc
|
|
desc: "lista de destinatarios en copia oculta (opcional)"
|
|
- name: attachments
|
|
desc: "lista de EmailAttachmentPy con filename, content_type y data binarios (opcional)"
|
|
- name: headers
|
|
desc: "diccionario de headers MIME adicionales como X-Mailer (opcional)"
|
|
output: "None si el envio fue exitoso; lanza RuntimeError con descripcion del fallo SMTP"
|
|
tested: true
|
|
tests:
|
|
- "envia texto plano via mock smtpd"
|
|
- "envia html via mock smtpd"
|
|
- "envia con adjunto via mock smtpd"
|
|
- "error si host no existe"
|
|
test_file_path: "python/functions/infra/smtp_send_test.py"
|
|
file_path: "python/functions/infra/smtp_send.py"
|
|
---
|
|
|
|
## Ejemplo
|
|
|
|
```python
|
|
from infra.smtp_send import smtp_send, SMTPConfigPy, EmailAttachmentPy
|
|
|
|
cfg = SMTPConfigPy(host="smtp.gmail.com", port=587, username="u@gmail.com", password="app-pw")
|
|
smtp_send(
|
|
cfg,
|
|
from_addr="u@gmail.com",
|
|
to=["dest@example.com"],
|
|
subject="Reporte",
|
|
body_html="<h1>Hola</h1>",
|
|
body_text="Hola",
|
|
)
|
|
```
|
|
|
|
## Notas
|
|
|
|
Funcion impura — abre conexion TCP real. Usa solo stdlib Python (smtplib, email). Para TLS directo (port 465) usa `SMTP_SSL`; para STARTTLS (port 587) usa `SMTP` + `starttls()`. Los adjuntos se codifican en base64. BCC se incluye en `sendmail` pero no en las cabeceras MIME visibles.
|