Unified Python email library with multi-provider support (SendGrid, SES, Postmark, Mailgun, Brevo, SMTP)
Project description
MailBridge 📧
Unified Python email library with multi-provider support
MailBridge is a flexible Python library for sending emails, allowing you to use multiple providers through a single, simple interface. It supports SMTP, SendGrid, Mailgun, Amazon SES, Postmark, and Brevo.
✨ Features
- 🎨 Template Support - Use dynamic templates with all major providers
- 📎 Attachment Support - Add file attachment in email message
- 📦 Bulk Sending - Send thousands of emails efficiently with native API optimization
- 🔧 Unified Interface - Same code works with any provider
- ✅ Fully Tested - 156 unit tests, 96% coverage
- 🚀 Production Ready - Battle-tested and reliable
- 📚 Great Documentation - Extensive examples and guides
📦 Installation
pip install mailbridge
Optional dependencies:
# For SendGrid
pip install mailbridge[sendgrid]
# For Amazon SES
pip install mailbridge[ses]
# For all providers
pip install mailbridge[all]
# SMTP and Postmark work out of the box
🚀 Quick Start
Basic Email
from mailbridge import MailBridge
# Initialize with your provider
mailer = MailBridge(provider='sendgrid', api_key='your-api-key')
# Send email
response = mailer.send(
to='recipient@example.com',
subject='Hello from MailBridge!',
body='<h1>It works!</h1><p>Email sent successfully.</p>'
)
print(f"Sent! Message ID: {response.message_id}")
Template Email
# Send template with dynamic data
response = mailer.send(
to='user@example.com',
subject='', # From template
body='', # From template
template_id='welcome-template',
template_data={
'name': 'John Doe',
'company': 'Acme Corp',
'activation_link': 'https://...'
}
)
Bulk Sending
from mailbridge import MailBridge, EmailMessageDto
messages = [
EmailMessageDto(
to='user1@example.com',
subject='Welcome',
body='<p>Welcome User 1!</p>'
),
EmailMessageDto(
to='user2@example.com',
subject='Welcome',
body='<p>Welcome User 2!</p>'
),
# ... more messages
]
result = mailer.send_bulk(messages)
print(f"Sent: {result.successful}/{result.total}")
🎯 Supported Providers
| Provider | Templates | Bulk API | Features |
|---|---|---|---|
| SendGrid | ✅ | ✅ Native | Personalizations, tracking |
| Amazon SES | ✅ | ✅ Native | 50/call batching, config sets |
| Postmark | ✅ | ✅ Native | Open/click tracking, streams |
| Mailgun | ✅ | ✅ Native | Templates, tracking |
| Brevo | ✅ | ✅ Native | Templates, SMS support |
| SMTP | ❌ | ❌ | Universal compatibility |
📖 Provider Setup
SendGrid
from mailbridge import MailBridge
mailer = MailBridge(
provider='sendgrid',
api_key='SG.xxxxx',
from_email='noreply@yourdomain.com'
)
Amazon SES
mailer = MailBridge(
provider='ses',
aws_access_key_id='AKIAXXXX',
aws_secret_access_key='xxxxx',
region_name='us-east-1',
from_email='verified@yourdomain.com'
)
# Or using IAM role (EC2/Lambda)
mailer = MailBridge(
provider='ses',
region_name='us-east-1',
from_email='verified@yourdomain.com'
)
Note: Email addresses must be verified in sandbox mode. Request production access to send to any email.
Postmark
mailer = MailBridge(
provider='postmark',
server_token='xxxxx-xxxxx',
from_email='verified@yourdomain.com'
)
# With tracking
response = mailer.send(
to='user@example.com',
subject='Tracked Email',
body='<p>Click <a href="https://...">here</a></p>',
track_opens=True,
track_links='HtmlAndText'
)
Mailgun
mailer = MailBridge(
provider='mailgun',
api_key='key-xxxxx',
domain='mg.yourdomain.com', # Required
from_email='noreply@yourdomain.com'
)
Note: Uses same API as SendGrid. See SendGrid examples for usage patterns.
Brevo (Sendinblue)
mailer = MailBridge(
provider='brevo',
api_key='xkeysib-xxxxx',
from_email='noreply@yourdomain.com'
)
# Template ID is a number
mailer.send(
to='user@example.com',
template_id=123, # Not a string
template_data={'name': 'John'}
)
Note: Similar to SendGrid/Postmark. Template IDs are integers. See SendGrid examples for usage patterns.
SMTP (Gmail, Outlook, Custom)
# Gmail
mailer = MailBridge(
provider='smtp',
host='smtp.gmail.com',
port=587,
username='you@gmail.com',
password='app-password', # Not your regular password!
use_tls=True,
from_email='you@gmail.com'
)
# Outlook
mailer = MailBridge(
provider='smtp',
host='smtp.office365.com',
port=587,
username='you@outlook.com',
password='your-password',
use_tls=True,
from_email='you@outlook.com'
)
# Custom server
mailer = MailBridge(
provider='smtp',
host='mail.yourdomain.com',
port=465,
username='user',
password='pass',
use_ssl=True, # For port 465
from_email='noreply@yourdomain.com'
)
Gmail: Use App Password (requires 2FA)
💡 Common Use Cases
Welcome Emails
mailer.send(
to=new_user.email,
template_id='welcome-email',
template_data={
'name': new_user.name,
'activation_link': generate_activation_link(new_user)
}
)
Password Reset
mailer.send(
to=user.email,
template_id='password-reset',
template_data={
'reset_link': generate_reset_link(user),
'expiry_hours': 24
}
)
Newsletters (Bulk)
from mailbridge import EmailMessageDto
subscribers = User.objects.filter(subscribed=True)
messages = [
EmailMessageDto(
to=sub.email,
template_id='newsletter',
template_data={
'name': sub.name,
'unsubscribe_link': generate_unsubscribe_link(sub)
}
)
for sub in subscribers
]
result = mailer.send_bulk(messages)
print(f"Sent: {result.successful}/{result.total}")
Transactional Notifications
mailer.send(
to=order.customer_email,
template_id='order-confirmation',
template_data={
'order_number': order.id,
'total': order.total,
'items': order.items,
'tracking_url': order.tracking_url
}
)
🔧 Advanced Features
Attachments
from pathlib import Path
mailer.send(
to='customer@example.com',
subject='Your Invoice',
body='<p>Invoice attached.</p>',
attachments=[
Path('invoice.pdf'),
Path('receipt.pdf')
]
)
CC and BCC
mailer.send(
to='client@example.com',
subject='Project Update',
body='<p>Latest update...</p>',
cc=['manager@company.com', 'team@company.com'],
bcc=['archive@company.com']
)
Custom Headers and Tags
mailer.send(
to='user@example.com',
subject='Campaign Email',
body='<p>Special offer!</p>',
headers={'X-Campaign-ID': 'summer-2024'},
tags=['marketing', 'campaign']
)
Context Manager
with MailBridge(provider='smtp', host='...', port=587) as mailer:
mailer.send(to='user@example.com', subject='Test', body='...')
# Connection automatically closed
📊 Bulk Sending Performance
Provider Optimizations:
- SendGrid: Uses native batch API (up to 1000/call)
- SES: Auto-batches to 50 recipients per call
- Postmark: Uses batch API (up to 500/call)
- Mailgun: Native batch API
- Brevo: Native batch API
- SMTP: Reuses connection for multiple sends
Example:
# Send 1000 emails efficiently
messages = [
EmailMessageDto(
to=f'user{i}@example.com',
template_id='campaign',
template_data={'user_id': i}
)
for i in range(1000)
]
result = mailer.send_bulk(messages)
print(f"Sent {result.successful} in {result.total_time:.2f}s")
📚 Documentation & Examples
- Examples Directory - Complete examples for all providers
- SendGrid Examples - Basic, template, bulk
- SES Examples - AWS setup, templates, bulk
- Postmark Examples - Tracking features
- SMTP Examples - Gmail, Outlook, custom
- Test Suite - 156 unit tests, 96% coverage
- Changelog - Version history
🧪 Testing
MailBridge includes a comprehensive test suite:
# Clone repo
git clone https://github.com/radomirbrkovic/mailbridge
cd mailbridge
# Install dev dependencies
pip install -r requirements-dev.txt
# Run tests
pytest tests/ -v
# With coverage
pytest tests/ --cov=mailbridge --cov-report=html
# Results: 156 tests, 96% coverage
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
# Setup development environment
git clone https://github.com/radomirbrkovic/mailbridge
cd mailbridge
pip install -e ".[dev]"
# Run tests
pytest
📄 License
MIT License - see LICENSE file for details.
🙏 Acknowledgments
Built with ❤️ for developers who need reliable email delivery.
Credits:
- SendGrid Python SDK
- Boto3 (AWS SDK)
- Postmark API
- Python SMTP library
📞 Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mailbridge-2.0.0.tar.gz.
File metadata
- Download URL: mailbridge-2.0.0.tar.gz
- Upload date:
- Size: 35.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
74ca906c9355d602dd11a33862b7ed2ed20b09886cc7d0c4f50d01083e932329
|
|
| MD5 |
328ed5f20275c52d508d6ed70162f8ee
|
|
| BLAKE2b-256 |
b08b7c47fcf23a57964898a3ba8023f4fc9acc9fde147412f7a5157f33902398
|
File details
Details for the file mailbridge-2.0.0-py3-none-any.whl.
File metadata
- Download URL: mailbridge-2.0.0-py3-none-any.whl
- Upload date:
- Size: 23.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c3f98d68b7e9d5ee768fe5eb5582b45c98d4dd838323105d072d8b7d16245fbf
|
|
| MD5 |
ddfa7959315b8caebf77421d82ab0a5a
|
|
| BLAKE2b-256 |
3ca5e9bde068a5563d13a75dcd3aec70c2555c3cc4c5739808a9c01339b63ac3
|