Tutorial 6 — Email with Mailer
Tutorial 6: Envío de Emails
Section titled “Tutorial 6: Envío de Emails”This tutorial demonstrates PyGo’s native mailer package — SMTP email sending with templates and bulk support.
🎯 What You’ll Build
Section titled “🎯 What You’ll Build”A contact form that sends email notifications using:
- SMTP configuration
- HTML templates
- Bulk sending capabilities
📝 Step 1: Configure SMTP
Section titled “📝 Step 1: Configure SMTP”[mailer]host = "smtp.gmail.com"port = 587username = "your-app@gmail.com"password = "your-app-password" # Use environment variable in productionfrom = "no-reply@yourapp.com"
# Optional: enable queueing for high volumequeue = true📝 Step 2: Create HTML Email Template
Section titled “📝 Step 2: Create HTML Email Template”Create app/templates/emails/contact.html:
<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>Thank You for Your Message</title></head><body style="font-family: sans-serif; max-width: 600px; margin: 0 auto;"> <h1>Thank You, {{ name }}!</h1>
<p>We received your message:</p>
<blockquote style="border-left: 3px solid #ccc; padding-left: 1em; margin: 1em 0;"> {{ message }} </blockquote>
<p>Our team will respond within 24 hours.</p>
<hr> <p style="color: #666; font-size: 0.9em;"> PyGo Framework • Automated Email System </p></body></html>📝 Step 3: Send Email in Handler
Section titled “📝 Step 3: Send Email in Handler”from mailer import Send, WithTemplate
# Load template once at startupcontact_template = WithTemplate("emails/contact.html")
handler contact: contact(name: String, email: Email, message: String) -> String: # Log the contact submission log.info("Contact form submitted", {"email": email})
# Send confirmation email to user Send( to=[email], subject="Thank you for your message!", html=contact_template.render({ "name": name, "message": message, }), )
# Send notification to admin Send( to=["admin@yourapp.com"], subject=f"New contact form submission from {name}", html=f""" <h2>New Contact Submission</h2> <p><strong>Name:</strong> {name}</p> <p><strong>Email:</strong> {email}</p> <p><strong>Message:</strong> {message}</p> """, )
return '<div class="alert alert-success">✅ Message sent! We will reply soon.</div>'📝 Step 4: HTML Contact Form
Section titled “📝 Step 4: HTML Contact Form”<form hx-post="/contact" hx-swap="outerHTML" x-data="{ submitting: false }" @submit="submitting = true"> <div> <label>Name</label> <input type="text" name="name" required /> </div>
<div> <label>Email</label> <input type="email" name="email" required /> </div>
<div> <label>Message</label> <textarea name="message" rows="5" required></textarea> </div>
<button type="submit" :disabled="submitting"> <span x-show="!submitting">Send Message</span> <span x-show="submitting">⏳ Sending...</span> </button></form>📋 Mailer Features
Section titled “📋 Mailer Features”Single Email
Section titled “Single Email”from mailer import Send
Send( to=["user@example.com"], subject="Welcome!", text="Your account was created.", html="<h1>Welcome!</h1><p>Your account was created.</p>",)Template-based Email
Section titled “Template-based Email”from mailer import WithTemplate
tmpl = WithTemplate("emails/welcome.html")Send( to=[user.email], subject="Welcome to the platform!", html=tmpl.render({"name": user.name, "verify_url": verify_url}),)Bulk Emails
Section titled “Bulk Emails”from mailer import SendBulk
messages = []for user in users: messages.append({ "to": [user.email], "subject": "Newsletter Update", "html": render_template("emails/newsletter.html", {"user": user}), })
# Send all emails (uses queue if enabled)SendBulk(messages)Queue Integration
Section titled “Queue Integration”# When queue=true in config, emails are queued and sent# asynchronously by the pygo worker process# No code changes needed — Send() automatically queues⚙️ Environment-based Configuration
Section titled “⚙️ Environment-based Configuration”# Use environment variables for credentialsexport MAIL_HOST="smtp.sendgrid.net"export MAIL_PORT="587"export MAIL_USERNAME="apikey"export MAIL_PASSWORD="SG.xxxxx"export MAIL_FROM="noreply@yourapp.com"# pygo.toml — reference env vars[mailer]host = "${MAIL_HOST}"port = "${MAIL_PORT}"username = "${MAIL_USERNAME}"password = "${MAIL_PASSWORD}"from = "${MAIL_FROM}"🧪 Testing Emails
Section titled “🧪 Testing Emails”from mailer import TestMailer
test_mailer = TestMailer()
# Capture sent emails instead of sendingtest_mailer.capture()
Send(to=["test@example.com"], subject="Test", html="<p>Hi</p>")
# Inspect captured emailsemails = test_mailer.sent()assert len(emails) == 1assert emails[0].to == ["test@example.com"]assert emails[0].subject == "Test"🚀 Pro Tips
Section titled “🚀 Pro Tips”- Always use templates for HTML emails — never inline HTML in
.pgofiles - Enable queueing for high volume (>100 emails/minute)
- Use environment variables for credentials — never hardcode
- Test with TestMailer — never send real emails in tests
🚀 Next Steps
Section titled “🚀 Next Steps”- pygo-mcp v0.1.0 — AI assistant integration
- Mailer API Reference
- pygo-notifications-enterprise — for WhatsApp Business API