Introduction
Django is the most popular Python web framework, and email is a core part of nearly every Django application. Whether you are sending password reset links, order confirmations, welcome emails, or marketing newsletters, you need confidence that those messages render correctly and reach the right people before you flip the switch to production.
SendPit gives you a private SMTP sandbox that captures every email your application sends during development and staging. Instead of accidentally delivering test emails to real customers or juggling throwaway inboxes, you point Django at SendPit's SMTP server and inspect every message — headers, HTML, plain text, and attachments — from a clean web dashboard.
Because SendPit works over standard SMTP, there is nothing proprietary to install. You configure Django the same way you would configure any SMTP provider, swap in your SendPit credentials, and start sending. This guide walks you through the full setup, from basic settings.py changes to advanced patterns like environment-specific configuration, HTML emails, Docker networking, Flask integration, and plain Python usage with smtplib.
Prerequisites
Before you begin, make sure you have the following:
- Python 3.8 or higher — any modern Python release will work.
- Django 3.2 or higher — the configuration keys used in this guide have been stable since Django 1.x, so older versions will work too, but 3.2+ is recommended for long-term support.
- A SendPit account — sign up at sendpit.com and create a mailbox. You will receive an SMTP username (starts with
mb_) and password. - pip — to install any helper packages like
python-decouple.
Step 1: Configure Django Settings
Open your project's settings.py and add the following SMTP settings:
# settings.py — SendPit SMTP configuration
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.sendpit.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'mb_your_username_here'
EMAIL_HOST_PASSWORD = 'your_password_here'
DEFAULT_FROM_EMAIL = 'test@example.com'
That is all Django needs. The built-in smtp.EmailBackend handles the TLS handshake, authentication, and message delivery over port 587. Every email your application sends will now land in your SendPit mailbox instead of going out to the public internet.
Step 2: Keep Credentials Out of Code
Hard-coding credentials in settings.py is fine for a quick test but dangerous for shared repositories. Use environment variables instead.
Option A: os.environ (no extra dependencies)
import os
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.sendpit.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = os.environ.get('SENDPIT_USERNAME', '')
EMAIL_HOST_PASSWORD = os.environ.get('SENDPIT_PASSWORD', '')
DEFAULT_FROM_EMAIL = os.environ.get('DEFAULT_FROM_EMAIL', 'test@example.com')
Set the variables in your shell or .env file:
export SENDPIT_USERNAME="mb_a1b2c3d4e5f6g7h8"
export SENDPIT_PASSWORD="your_sendpit_password"
Option B: python-decouple (reads .env files automatically)
Install the package:
pip install python-decouple
Then update settings.py:
from decouple import config
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.sendpit.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = config('SENDPIT_USERNAME')
EMAIL_HOST_PASSWORD = config('SENDPIT_PASSWORD')
DEFAULT_FROM_EMAIL = config('DEFAULT_FROM_EMAIL', default='test@example.com')
Create a .env file in your project root (add it to .gitignore):
SENDPIT_USERNAME=mb_a1b2c3d4e5f6g7h8
SENDPIT_PASSWORD=your_sendpit_password
DEFAULT_FROM_EMAIL=test@example.com
Step 3: Send a Test Email
Open the Django shell and fire off a quick test:
python manage.py shell
from django.core.mail import send_mail
send_mail(
subject='Test Email from Django',
message='Hello from SendPit!',
from_email='from@example.com',
recipient_list=['to@example.com'],
)
Head over to your SendPit dashboard. You should see the email appear within seconds. Click it to inspect the headers, body, and raw source.
Sending HTML Emails
Django's send_mail function is great for plain text, but most applications need HTML emails. Use EmailMultiAlternatives to send both a plain-text fallback and an HTML version:
from django.core.mail import EmailMultiAlternatives
subject = 'Welcome to Our App'
text_content = 'Thanks for signing up! Visit your dashboard to get started.'
html_content = '''
<html>
<body>
<h1 style="color: #333;">Welcome!</h1>
<p>Thanks for signing up. <a href="https://example.com/dashboard">Visit your dashboard</a> to get started.</p>
</body>
</html>
'''
msg = EmailMultiAlternatives(subject, text_content, 'noreply@example.com', ['user@example.com'])
msg.attach_alternative(html_content, 'text/html')
msg.send()
For emails with attachments, use the EmailMessage class:
from django.core.mail import EmailMessage
email = EmailMessage(
subject='Your Invoice',
body='Please find your invoice attached.',
from_email='billing@example.com',
to=['customer@example.com'],
)
email.attach_file('/path/to/invoice.pdf')
email.send()
Both messages will appear in SendPit with full attachment previews and HTML rendering.
Environment-Specific Settings
Most Django projects need different email behavior per environment. Here are two common patterns.
Pattern 1: Separate settings files
# settings/base.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.sendpit.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
# settings/development.py
from .base import *
EMAIL_HOST_USER = 'mb_dev_mailbox_credentials'
EMAIL_HOST_PASSWORD = 'dev_password'
# settings/production.py
from .base import *
EMAIL_HOST = 'smtp.your-production-provider.com'
EMAIL_HOST_USER = 'production_user'
EMAIL_HOST_PASSWORD = 'production_password'
Pattern 2: Single settings file with environment variables
import os
ENVIRONMENT = os.environ.get('DJANGO_ENV', 'development')
if ENVIRONMENT == 'production':
EMAIL_HOST = os.environ['PRODUCTION_SMTP_HOST']
EMAIL_HOST_USER = os.environ['PRODUCTION_SMTP_USER']
EMAIL_HOST_PASSWORD = os.environ['PRODUCTION_SMTP_PASSWORD']
else:
# Development and staging use SendPit
EMAIL_HOST = 'smtp.sendpit.com'
EMAIL_HOST_USER = os.environ.get('SENDPIT_USERNAME', '')
EMAIL_HOST_PASSWORD = os.environ.get('SENDPIT_PASSWORD', '')
EMAIL_PORT = 587
EMAIL_USE_TLS = True
This ensures test emails never escape to real recipients during development.
Plain Python (Without Django)
If you have a Python script, CLI tool, or microservice that does not use Django, you can send emails through SendPit using the standard library's smtplib:
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
smtp_host = 'smtp.sendpit.com'
smtp_port = 587
username = 'mb_a1b2c3d4e5f6g7h8'
password = 'your_sendpit_password'
msg = MIMEMultipart('alternative')
msg['Subject'] = 'Test from Python'
msg['From'] = 'sender@example.com'
msg['To'] = 'recipient@example.com'
text_part = MIMEText('Hello from plain Python!', 'plain')
html_part = MIMEText('<h1>Hello</h1><p>From plain Python!</p>', 'html')
msg.attach(text_part)
msg.attach(html_part)
with smtplib.SMTP(smtp_host, smtp_port) as server:
server.starttls()
server.login(username, password)
server.send_message(msg)
print('Email sent successfully!')
Flask Integration
If you are using Flask, the Flask-Mail extension makes SMTP configuration simple. Install it:
pip install Flask-Mail
Configure your Flask app:
from flask import Flask
from flask_mail import Mail, Message
app = Flask(__name__)
app.config['MAIL_SERVER'] = 'smtp.sendpit.com'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = 'mb_a1b2c3d4e5f6g7h8'
app.config['MAIL_PASSWORD'] = 'your_sendpit_password'
app.config['MAIL_DEFAULT_SENDER'] = 'noreply@example.com'
mail = Mail(app)
@app.route('/send-test')
def send_test():
msg = Message('Test from Flask', recipients=['user@example.com'])
msg.body = 'Hello from Flask + SendPit!'
msg.html = '<h1>Hello!</h1><p>From Flask + SendPit.</p>'
mail.send(msg)
return 'Email sent!'
Testing with SendPit in Django Tests
When running automated tests, you may want to verify that emails are sent without actually hitting the SMTP server. Django provides a built-in locmem backend for this. However, if you want your test suite to send real emails to SendPit for visual inspection, use the override_settings decorator:
from django.test import TestCase, override_settings
from django.core.mail import send_mail
@override_settings(
EMAIL_BACKEND='django.core.mail.backends.smtp.EmailBackend',
EMAIL_HOST='smtp.sendpit.com',
EMAIL_PORT=587,
EMAIL_USE_TLS=True,
EMAIL_HOST_USER='mb_test_mailbox',
EMAIL_HOST_PASSWORD='test_password',
)
class EmailIntegrationTest(TestCase):
def test_welcome_email_sends(self):
result = send_mail(
'Welcome',
'Thanks for joining!',
'noreply@example.com',
['newuser@example.com'],
)
self.assertEqual(result, 1)
For most unit tests, stick with Django's default locmem backend and use django.core.mail.outbox to assert email content. Reserve SendPit integration tests for end-to-end or staging test suites where you need to visually verify rendered HTML.
Docker Configuration
When your Django application runs inside a Docker container, the SMTP host depends on your network setup.
Docker Compose (SendPit is external)
If SendPit is a hosted service, your container needs to reach the public internet:
# No changes needed — smtp.sendpit.com resolves normally from inside containers
EMAIL_HOST = 'smtp.sendpit.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
Accessing host services from a container
If you are running a local SMTP server on the host machine, use Docker's special DNS name:
# macOS / Windows
EMAIL_HOST = 'host.docker.internal'
# Linux (add --add-host=host.docker.internal:host-gateway to your docker run command)
EMAIL_HOST = 'host.docker.internal'
Docker Compose with a shared network
If your SMTP service is another container on the same Docker network, use the service name:
EMAIL_HOST = 'smtp' # The service name in docker-compose.yml
EMAIL_PORT = 1025 # Internal container port
EMAIL_USE_TLS = False # Local containers typically don't use TLS
Troubleshooting
SMTPAuthenticationError (535)
Double-check your EMAIL_HOST_USER and EMAIL_HOST_PASSWORD. The username should start with mb_. Copy and paste directly from your SendPit dashboard to avoid trailing whitespace.
Connection Timeout
- Verify that port 587 is not blocked by your firewall or corporate network.
- Test connectivity with:
python -c "import socket; s = socket.create_connection(('smtp.sendpit.com', 587), timeout=10); print('OK'); s.close()" - If you are behind a proxy, configure your environment's proxy settings.
Emails Not Appearing in SendPit
- Confirm
send_mailreturns1(meaning Django handed the message to the SMTP server successfully). - Check that you are looking at the correct mailbox in the SendPit dashboard.
- Verify
EMAIL_BACKENDis set todjango.core.mail.backends.smtp.EmailBackend— Django defaults toconsole.EmailBackendin some project templates.
SSL/TLS Errors
Make sure you are using EMAIL_USE_TLS = True (STARTTLS on port 587), not EMAIL_USE_SSL = True (implicit SSL on port 465). SendPit uses STARTTLS.
Django Sends Email but Nothing Arrives
If send_mail returns 1 but nothing shows up, ensure your EMAIL_HOST_USER matches an active mailbox. An expired or deleted mailbox will silently accept connections but discard messages.
Next Steps
You now have Django fully configured to send emails through SendPit. Here are some things to explore:
- Inspect HTML rendering — Open any captured email in the SendPit dashboard to see how it renders across different contexts.
- Test attachments — Send PDFs, images, and other files to verify they arrive intact.
- Team collaboration — Invite teammates to your SendPit organization so everyone can inspect test emails.
- Multiple mailboxes — Create separate mailboxes for different projects, branches, or environments to keep test data organized.
- Check headers — Use SendPit's raw view to inspect SMTP headers, MIME boundaries, and encoding for debugging.