Skip to main content

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 aiosmtpd for 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.0 for 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

🙏 Acknowledgments

  • Built with aiosmtpd
  • Inspired by modern async Python patterns
  • Community feedback and contributions

Made with ❤️ by the DripEmails Team

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

dripemails_smtp_server-1.0.0.tar.gz (34.4 kB view details)

Uploaded Source

Built Distribution

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

dripemails_smtp_server-1.0.0-py3-none-any.whl (6.2 kB view details)

Uploaded Python 3

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

Hashes for dripemails_smtp_server-1.0.0.tar.gz
Algorithm Hash digest
SHA256 92154733e772fb8c0602239099f923f627002c01e84fcb42baa42722bddd3a75
MD5 8e83fc9c2c75b8c37769a418b0a69d40
BLAKE2b-256 5fbc45b628dffa915cbe0132c4e1b0c57ab6a2538cb6b41c57f0072bf245b529

See more details on using hashes here.

File details

Details for the file dripemails_smtp_server-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for dripemails_smtp_server-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bf7f96138ee2c196a6afa6cfb05fc367964245c40d7a4bd852cb320deadcea59
MD5 acab7833d0f1bcfba7de1cdfa64a44cf
BLAKE2b-256 094acd87a12abad688c692da544a58783e0e63169dd3bfe1ffdcd5ca9493c29f

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