SMTP for Python — mail from your script or Django app that arrives
Python has SMTP built in: with smtplib you send a message in a handful of lines, and Django wraps that in its own mail layer with EMAIL settings. What neither provides is deliverability — that depends on the server you send through.
Whether you have a standalone script, a Flask app or a Django project: the settings are the same five details. You point them at your relay and the code that builds the messages stays untouched.
Why it goes wrong without a relay
Python mail often comes from the background: a nightly report, a cron job that sends invoices, a script that warns when a reading falls outside the margin. Nobody is watching — so nobody notices that the receiving server quietly refuses them. With Django there is the classic go-live surprise on top: in development everything goes to the console, in production to real providers that do check reputation.
Setting up SMTP in Python
Collect your details
Log in to your 2mail account and retrieve your SMTP server, username and password there.
Fill them in inside Python
In a Django project you set the EMAIL settings in the settings: the SMTP backend as the email backend, the relay's host, port 587, the STARTTLS option on, the username and password, and a default sender address on your own domain. If you work directly with smtplib, you connect to the host on port 587, call starttls, log in with username and password and then send the message. In both cases, read the details from environment variables, not from the code.
Authenticate your domain
Make sure SPF, DKIM and DMARC are set correctly for your domain, so recipients can verify that the mail comes from you.
Test
Send a test message to an address at a major provider and check that it arrives in the inbox and not in the spam folder.
The fields Python asks for
Every platform names them slightly differently, but it is always the same five. The actual values are tied to your account and can be found in your 2mail account — take them from there, so you are sure to use the right ones.
| Field | What you enter |
|---|---|
| SMTP server (host) | The server name from your 2mail account. |
| Port | The port that matches your chosen encryption; your account shows which one. |
| Encryption | TLS. Never send unencrypted — your credentials would otherwise travel in plain text. |
| Username | The SMTP login of your 2mail account. |
| Password | The matching password. Never use the password of an employee's mailbox. |
Which emails Python sends
As soon as the relay is set up, all of these run through 2mail — you do not have to configure them one by one.
Pitfalls with Python
TLS option and port have to match
Django has two separate TLS settings: one for STARTTLS and one for TLS from the start. Switch on only the STARTTLS setting; that is the one for port 587. Both at once produces a configuration error; neither sends your login unencrypted, which a relay rightly refuses.
One connection per batch, not per message
A script that opens a new SMTP connection for each of a thousand messages behaves like an attacker. Open one connection, send the batch, close it. Django has a function for sending several messages over a single connection.
Silent failures in background jobs
An exception in a cron job disappears into a log file nobody reads. Catch errors when sending and report them somewhere they get noticed — and hook up 2mail's webhooks for delivery and bounce, so you also see what goes wrong after handover.
A different platform?
SMTP is a standard protocol: any system that speaks SMTP — a CRM, an ERP, a custom application or a server — can send through 2mail using the same five fields.