Mail Facade
Send emails with multiple backend support.
Supported Drivers
log(default) - Logs to console (development)smtp- SMTP serversendgrid- SendGrid APImailgun- Mailgun APIses- AWS SES
Basic Usage
python
from fastpy_cli.libs import Mail
# Send with template
Mail.to('user@example.com') \
.subject('Welcome!') \
.send('welcome', {'name': 'John'})
# Send raw HTML
Mail.to('user@example.com') \
.subject('Hello') \
.html('<h1>Hello World</h1>') \
.send()
# Send plain text
Mail.to('user@example.com') \
.subject('Hello') \
.text('Hello World') \
.send()Recipients
python
# Single recipient
Mail.to('user@example.com')
# Multiple recipients
Mail.to(['user1@example.com', 'user2@example.com'])
# CC
Mail.to('user@example.com') \
.cc('manager@example.com')
# BCC
Mail.to('user@example.com') \
.bcc('archive@example.com')
# All together
Mail.to('user@example.com') \
.cc(['cc1@example.com', 'cc2@example.com']) \
.bcc('archive@example.com') \
.subject('Team Update') \
.send('update', data)Sender
python
# Set from address
Mail.to('user@example.com') \
.from_address('noreply@myapp.com', 'My App') \
.send('welcome')
# Set reply-to
Mail.to('user@example.com') \
.reply_to('support@myapp.com') \
.send('welcome')
# Set default from globally
Mail.set_default_from('noreply@myapp.com', 'My App')Templates
python
# Use template with data
Mail.to('user@example.com') \
.subject('Order Confirmation') \
.send('orders/confirmation', {
'order_id': 123,
'items': items,
'total': 99.99
})
# Use view method (alias)
Mail.to('user@example.com') \
.subject('Welcome') \
.view('welcome', {'name': 'John'}) \
.send()Attachments
python
# Attach file
Mail.to('user@example.com') \
.attach('/path/to/invoice.pdf') \
.send('invoice')
# Attach with custom filename
Mail.to('user@example.com') \
.attach('/path/to/file.pdf', filename='Invoice-123.pdf') \
.send('invoice')
# Attach raw data
Mail.to('user@example.com') \
.attach_data(pdf_bytes, 'invoice.pdf', 'application/pdf') \
.send('invoice')Priority
python
# High priority
Mail.to('user@example.com') \
.high_priority() \
.send('urgent')
# Low priority
Mail.to('user@example.com') \
.low_priority() \
.send('newsletter')
# Custom priority (1=high, 3=normal, 5=low)
Mail.to('user@example.com') \
.priority(1) \
.send('urgent')Custom Headers
python
Mail.to('user@example.com') \
.with_header('X-Custom', 'value') \
.with_header('X-Campaign', 'welcome-2024') \
.send('welcome')Queuing
python
# Queue for later
Mail.to('user@example.com') \
.queue('welcome', {'name': 'John'})
# Queue with delay (seconds)
Mail.to('user@example.com') \
.later(60, 'reminder', {'name': 'John'})Using Specific Driver
python
# Use SendGrid
Mail.using('sendgrid') \
.to('user@example.com') \
.send('welcome')
# Get driver instance
sendgrid = Mail.driver('sendgrid')Configuration
Set environment variables:
bash
# SMTP
MAIL_DRIVER=smtp
MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_USERNAME=user
MAIL_PASSWORD=password
MAIL_ENCRYPTION=tls
# SendGrid
MAIL_DRIVER=sendgrid
SENDGRID_API_KEY=your-api-key
# Mailgun
MAIL_DRIVER=mailgun
MAILGUN_API_KEY=your-api-key
MAILGUN_DOMAIN=mg.example.com
# AWS SES
MAIL_DRIVER=ses
AWS_ACCESS_KEY_ID=your-key
AWS_SECRET_ACCESS_KEY=your-secret
AWS_REGION=us-east-1Testing
python
from fastpy_cli.libs import Mail
# Enable fake mode
Mail.fake()
# Send emails
Mail.to('user@example.com').subject('Test').send('welcome')
# Assertions
Mail.assert_sent('welcome')
Mail.assert_sent('welcome', count=1)
Mail.assert_not_sent('other_template')
# Access sent emails
for email in Mail.sent:
print(email['to'], email['subject'])Complete Example
python
from fastpy_cli.libs import Mail
class NotificationService:
def send_welcome(self, user):
Mail.to(user.email) \
.subject('Welcome to Our App!') \
.send('emails/welcome', {
'name': user.name,
'login_url': 'https://app.example.com/login'
})
def send_order_confirmation(self, order):
Mail.to(order.user.email) \
.cc(order.user.secondary_email) \
.subject(f'Order #{order.id} Confirmed') \
.attach_data(
self.generate_invoice_pdf(order),
f'invoice-{order.id}.pdf',
'application/pdf'
) \
.send('emails/order_confirmation', {
'order': order,
'items': order.items,
'total': order.total
})
def send_password_reset(self, user, token):
Mail.to(user.email) \
.subject('Password Reset Request') \
.high_priority() \
.send('emails/password_reset', {
'name': user.name,
'reset_url': f'https://app.example.com/reset?token={token}'
})