A modern, async SMTP server built with aiosmtpd for Python 3.11+
Project description
DripEmails SMTP Server
A modern, async SMTP server built with aiosmtpd for Python 3.11+. Perfect for development, testing, and production email handling.
🚀 Features
- Modern Async Architecture: Built with
aiosmtpdfor high-performance async email handling - Python 3.11+ Compatible: Optimized for modern Python versions
- Django Integration: Seamless integration with Django applications
- Webhook Support: Forward email metadata to external services
- Database Logging: Store email metadata in your database
- Rate Limiting: Built-in protection against spam and abuse
- Authentication: Support for PLAIN and LOGIN authentication
- Debug Mode: Comprehensive logging and debugging capabilities
- Production Ready: Designed for both development and production use
📋 Requirements
- Python 3.11 or higher
aiosmtpd>=1.4.4- Optional: Django 4.0+ for database integration
- Optional:
aiohttp>=3.8.0for webhook support
🛠️ Installation
From PyPI (Coming Soon)
pip install dripemails-smtp-server
From Source
git clone https://github.com/dripemails/smtp_server.git
cd smtp_server
pip install -e .
🚀 Quick Start
Basic Usage
from core.smtp_server import create_smtp_server
# Create server with default configuration
server = create_smtp_server()
# Start server on localhost:1025
server.start('localhost', 1025)
# Keep server running
import time
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
server.stop()
Django Integration
# In your Django management command
from django.core.management.base import BaseCommand
from core.smtp_server import run_smtp_server
class Command(BaseCommand):
help = 'Run SMTP server'
def handle(self, *args, **options):
config = {
'debug': True,
'save_to_database': True,
'allowed_domains': ['yourdomain.com'],
}
run_smtp_server('localhost', 1025, config)
Command Line Usage
# Run with debug mode
python -m core.smtp_server --debug --port 1025
# Run with custom configuration
python -m core.smtp_server --config smtp_config.json --port 1025
⚙️ Configuration
Basic Configuration
config = {
'debug': False, # Enable debug output
'save_to_database': True, # Save emails to database
'log_to_file': True, # Log to file
'log_file': 'email_log.jsonl', # Log file path
'allowed_domains': [ # Allowed recipient domains
'yourdomain.com',
'localhost',
'127.0.0.1'
],
'webhook_url': None, # Webhook URL for notifications
'forward_to_webhook': False, # Enable webhook forwarding
'auth_enabled': True, # Enable authentication
'allowed_users': ['founders'], # Allowed users for auth
}
Configuration File (JSON)
{
"debug": true,
"save_to_database": true,
"log_to_file": true,
"log_file": "email_log.jsonl",
"allowed_domains": ["yourdomain.com", "localhost"],
"webhook_url": "https://api.yourdomain.com/webhook",
"forward_to_webhook": true,
"auth_enabled": true,
"allowed_users": ["founders", "admin"],
"max_message_size": 10485760,
"timeout": 30
}
🔧 Django Integration
1. Add to INSTALLED_APPS
INSTALLED_APPS = [
# ... other apps
'core',
]
2. Run Migrations
python manage.py makemigrations core
python manage.py migrate
3. Create Management Command
# core/management/commands/run_smtp_server.py
from django.core.management.base import BaseCommand
from core.smtp_server import run_smtp_server
class Command(BaseCommand):
help = 'Run SMTP server'
def add_arguments(self, parser):
parser.add_argument('--port', type=int, default=1025)
parser.add_argument('--debug', action='store_true')
parser.add_argument('--config', type=str)
def handle(self, *args, **options):
config = {
'debug': options['debug'],
'save_to_database': True,
}
run_smtp_server('localhost', options['port'], config)
4. Run Server
python manage.py run_smtp_server --debug --port 1025
📧 Email Processing
Email Metadata Structure
{
'from': 'sender@example.com',
'to': 'recipient@yourdomain.com',
'subject': 'Test Email',
'date': '2024-01-01T12:00:00',
'message_id': '<unique-message-id>',
'received_at': '2024-01-01T12:00:00.123456',
'size': 1024,
'body': 'Email content...'
}
Database Model (Django)
from django.db import models
class EmailLog(models.Model):
sender = models.EmailField(max_length=254)
recipient = models.EmailField(max_length=254)
subject = models.CharField(max_length=255)
body = models.TextField()
message_id = models.CharField(max_length=255, blank=True)
received_at = models.DateTimeField(auto_now_add=True)
size = models.IntegerField(default=0)
processed = models.BooleanField(default=False)
error_message = models.TextField(blank=True)
class Meta:
ordering = ['-received_at']
indexes = [
models.Index(fields=['sender']),
models.Index(fields=['recipient']),
models.Index(fields=['received_at']),
]
🔐 Authentication
Supported Methods
- PLAIN: Simple username/password authentication
- LOGIN: Base64 encoded credentials
Django User Authentication
The server integrates with Django's authentication system:
# Users must exist in Django and be active
# Authentication checks against Django's User model
# Supports user groups and permissions
🌐 Webhook Support
Webhook Payload
{
"from": "sender@example.com",
"to": "recipient@yourdomain.com",
"subject": "Test Email",
"date": "2024-01-01T12:00:00",
"message_id": "<unique-message-id>",
"received_at": "2024-01-01T12:00:00.123456",
"size": 1024,
"body": "Email content..."
}
Configuration
config = {
'webhook_url': 'https://api.yourdomain.com/webhook',
'forward_to_webhook': True,
}
🧪 Testing
Test Script
import smtplib
from email.mime.text import MIMEText
def test_smtp_server(host='localhost', port=1025):
# Create message
msg = MIMEText('Test email content')
msg['From'] = 'test@example.com'
msg['To'] = 'test@yourdomain.com'
msg['Subject'] = 'Test Email'
# Send email
server = smtplib.SMTP(host, port)
server.send_message(msg)
server.quit()
print("Test email sent successfully!")
# Run test
test_smtp_server()
Automated Tests
# Run tests
pytest tests/
# Run with coverage
pytest --cov=core tests/
📊 Monitoring
Server Statistics
server = create_smtp_server()
stats = server.get_stats()
print(f"Emails received: {stats['emails_received']}")
print(f"Emails processed: {stats['emails_processed']}")
print(f"Emails failed: {stats['emails_failed']}")
print(f"Uptime: {stats['uptime']} seconds")
Logging
import logging
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
🚀 Production Deployment
Using Supervisord
[program:dripemails-smtp]
command=python manage.py run_smtp_server --port 25
directory=/path/to/your/project
user=www-data
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/dripemails-smtp.log
Using Docker
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 25
CMD ["python", "manage.py", "run_smtp_server", "--port", "25"]
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
Development Setup
# Clone repository
git clone https://github.com/dripemails/smtp_server.git
cd smtp_server
# Install development dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Format code
black core/ tests/
# Lint code
flake8 core/ tests/
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🆘 Support
- Documentation: GitHub Wiki
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Email: founders@dripemails.org
🙏 Acknowledgments
- Built with aiosmtpd
- Inspired by modern async Python patterns
- Community feedback and contributions
Made with ❤️ by the DripEmails Team
Project details
Release history Release notifications | RSS feed
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 dripemails_smtp_server-1.0.0.tar.gz.
File metadata
- Download URL: dripemails_smtp_server-1.0.0.tar.gz
- Upload date:
- Size: 34.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
92154733e772fb8c0602239099f923f627002c01e84fcb42baa42722bddd3a75
|
|
| MD5 |
8e83fc9c2c75b8c37769a418b0a69d40
|
|
| BLAKE2b-256 |
5fbc45b628dffa915cbe0132c4e1b0c57ab6a2538cb6b41c57f0072bf245b529
|
File details
Details for the file dripemails_smtp_server-1.0.0-py3-none-any.whl.
File metadata
- Download URL: dripemails_smtp_server-1.0.0-py3-none-any.whl
- Upload date:
- Size: 6.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bf7f96138ee2c196a6afa6cfb05fc367964245c40d7a4bd852cb320deadcea59
|
|
| MD5 |
acab7833d0f1bcfba7de1cdfa64a44cf
|
|
| BLAKE2b-256 |
094acd87a12abad688c692da544a58783e0e63169dd3bfe1ffdcd5ca9493c29f
|