Skip to main content

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


🧪 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


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

mailbridge-2.0.0.tar.gz (35.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mailbridge-2.0.0-py3-none-any.whl (23.6 kB view details)

Uploaded Python 3

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

Hashes for mailbridge-2.0.0.tar.gz
Algorithm Hash digest
SHA256 74ca906c9355d602dd11a33862b7ed2ed20b09886cc7d0c4f50d01083e932329
MD5 328ed5f20275c52d508d6ed70162f8ee
BLAKE2b-256 b08b7c47fcf23a57964898a3ba8023f4fc9acc9fde147412f7a5157f33902398

See more details on using hashes here.

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

Hashes for mailbridge-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c3f98d68b7e9d5ee768fe5eb5582b45c98d4dd838323105d072d8b7d16245fbf
MD5 ddfa7959315b8caebf77421d82ab0a5a
BLAKE2b-256 3ca5e9bde068a5563d13a75dcd3aec70c2555c3cc4c5739808a9c01339b63ac3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page