<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ smtp - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ smtp - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 28 Jul 2026 17:16:54 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/smtp/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Send Emails in Python using Mailtrap SMTP and the Email API ]]>
                </title>
                <description>
                    <![CDATA[ In this tutorial, I’ll walk you through the process of sending emails in Python using two different methods:  The traditional SMTP setup with the built-in ‘smtplib’ module.  Mailtrap email API via Mailtrap’s official SDK.  If you’re unfamiliar wi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/send-emails-in-python-using-mailtrap-smtp-and-the-email-api/</link>
                <guid isPermaLink="false">67e6ab43aa64aee164e7985e</guid>
                
                    <category>
                        <![CDATA[ Phyton ]]>
                    </category>
                
                    <category>
                        <![CDATA[ smtp ]]>
                    </category>
                
                    <category>
                        <![CDATA[ mailtrap ]]>
                    </category>
                
                    <category>
                        <![CDATA[ api ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alex Tray ]]>
                </dc:creator>
                <pubDate>Fri, 28 Mar 2025 13:59:31 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1743110284000/6fb2a037-ddca-4625-acfb-cffbd167ec55.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this tutorial, I’ll walk you through the process of sending emails in Python using two different methods: </p>
<ol>
<li><p>The traditional SMTP setup with the built-in ‘smtplib’ module. </p>
</li>
<li><p>Mailtrap email API via Mailtrap’s official SDK. </p>
</li>
</ol>
<p>If you’re unfamiliar with the tools and workflows, SMTP (Simple Mail Transfer Protocol) is the protocol commonly used for sending emails via apps and websites. Mailtrap is an email delivery platform designed for high deliverability with growth-focused features and industry-best analytics. </p>
<p>By the end of the article, you’ll understand how to integrate email-sending capabilities into Python projects and use Mailtrap for reliable email delivery in real-world scenarios.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-smtplib-setup">'smtplib' Setup</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-send-emails-with-mailtrap-smtp">How to Send emails with Mailtrap SMTP</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-send-emails-with-the-mailtrap-email-api">How to Send emails with the Mailtrap Email API</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-wrapping-up">Wrapping Up</a></p>
</li>
</ol>
<h2 id="heading-smtplib-setup">‘smtplib’ Setup</h2>
<p>To start sending emails with Python, I'll first use the built-in ‘smtplib’ module. This lets you connect to an SMTP server and send emails directly from your app. </p>
<p>So, start by importing the ‘smtplib’ module with the statement below:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> smtplib
</code></pre>
<p>Next, create an ‘SMTP’ object to configure the connection to your SMTP server. This object handles the email sending. </p>
<pre><code class="lang-python">smtpObj = smtplib.SMTP(host, port)
</code></pre>
<ul>
<li><p>‘host’ refers to the SMTP server endpoint, such as ‘live.smtp.mailtrap.io’</p>
</li>
<li><p>‘port’ is the communication channel used by the server. The recommended port is usually 587 for secure email sending with TLS encryption. </p>
</li>
</ul>
<p><strong>Pro tip</strong>: An SMTP object has a ‘sendmail’ instance object with three parameters, where each parameter is a string (‘receivers’ is a list of strings). </p>
<pre><code class="lang-python">smtpObj.sendmail(sender, receivers, message)
</code></pre>
<p>If you want to ensure you’ve properly imported the ‘smtplib’ module and check the full description of arguments and classes, run the following command:</p>
<pre><code class="lang-python">help(smtplib)
</code></pre>
<h2 id="heading-how-to-send-emails-with-mailtrap-smtp">How to Send emails with Mailtrap SMTP</h2>
<p>This method involves setting up the custom SMTP credentials you get for Mailtrap.</p>
<p><strong>Important notes</strong>: </p>
<ul>
<li><p><strong>Testing out the service with Mailtrap’s dummy domain</strong> – To try Mailtrap, you don’t need to verify your domain right away. You can use Mailtrap’s dummy domain (you get access to it when you sign up), which allows you to simulate sending emails without worrying about the DNS records. This is ideal for testing the service and getting familiar with Mailtrap’s features.  </p>
</li>
<li><p><strong>Domain verification for production</strong> – If you plan to send real emails to recipients, you’ll need to verify your domain. This involves adding DNS records such as SPF, DKIM, and <a target="_blank" href="https://dmarcreport.com/">DMARC</a> to your domain provider’s DNS settings. These records ensure your emails are delivered successfully and help protect against phishing and spoofing. In the next section, I'll show you how to set these up in your domain provider's dashboard. </p>
</li>
</ul>
<h3 id="heading-verify-your-sending-domain-spf-dkim-and-dmarc">Verify your sending domain (SPF, DKIM, and DMARC)</h3>
<p>DNS records are critical to ensure your emails are delivered successfully, and mailbox providers such as Gmail and Yahoo require DNS authentication. </p>
<p>But before we go through a quick tutorial on how to do it, let’s review each type of record so you understand why they’re so important:</p>
<ul>
<li><p><strong>SPF (Sender Policy Framework)</strong>: The record helps mail servers determine if the sender’s IP address is authorized to send emails from your domain. Simply, adding an SPF record prevents spammers from sending emails that appear to come from your domain. </p>
</li>
<li><p><strong>DKIM (DomainKeys Identified Mail)</strong>: DKIM uses encryption to verify the sender's domain and ensures that the email content hasn't been tampered with during transmission. This protects your emails from being spoofed. </p>
</li>
<li><p><strong>DMARC (Domain-based Message Authentication, Reporting &amp; Conformance)</strong>: DMARC ties SPF and DKIM together, providing a policy for handling unauthenticated emails and reporting on email activities. In a nutshell, it gives you more control over your domain’s email security. </p>
</li>
</ul>
<p>Now, here’s how to add the records: </p>
<ol>
<li><p>First, you need to access your domain provider's DNS settings. Usually, you can access them in the domain register or domain settings. For example, GoDaddy calls the menu Manage DNS, and it's dubbed similarly with other providers. </p>
</li>
<li><p>Next, add (copy-paste) the DNS records Mailtrap provides into your domain provider's DNS settings. Note that Mailtrap's records are read-made, and SPF is pre-parsed, so you don't need to create anything additional – just add the records. </p>
</li>
</ol>
<p><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXfHx2AAc87krxYh7twU5Ypuz-Iu6gklvJeVBzpdgptvfc7B9g7X3BBnqWai8n47HTDJrj1rZ2ny0jfscJJYgAAFcuEsZeVqYO2OellzvQgaXMjnMMxIeOoPGF0ildRbecEi7rjPbg?key=CJmzmKUWxlFjIw3A041wXvaj" alt="Screenshot showing domain verification" width="1600" height="1175" loading="lazy"></p>
<ol start="3">
<li>Finally, you can check the status of your records with Mailtrap. </li>
</ol>
<p>Below is the bare-bones script for sending emails via Mailtrap using Python. For security reasons, the script uses placeholder credentials for the username and password (except for the SMTP server endpoint and port).</p>
<p>When running the script, be sure to replace these placeholders with your actual Mailtrap credentials to ensure the email is sent successfully. </p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> smtplib
<span class="hljs-keyword">from</span> email.mime.text <span class="hljs-keyword">import</span> MIMEText

<span class="hljs-comment"># Configuration</span>
port = <span class="hljs-number">587</span>
smtp_server = <span class="hljs-string">"live.smtp.mailtrap.io"</span>
login = <span class="hljs-string">"api"</span>  <span class="hljs-comment"># Your login generated by Mailtrap</span>
password = <span class="hljs-string">"1a2b3c4d5e6f7g"</span>  <span class="hljs-comment"># Your password generated by Mailtrap</span>

sender_email = <span class="hljs-string">"mailtrap@example.com"</span>
receiver_email = <span class="hljs-string">"new@example.com"</span>

<span class="hljs-comment"># Plain text content</span>
text = <span class="hljs-string">"""\
Hi,
Check out the new post on the Mailtrap blog:
SMTP Server for Testing: Cloud-based or Local?
https://blog.mailtrap.io/2018/09/27/cloud-or-local-smtp-server/
Feel free to let us know what content would be useful for you!
"""</span>

<span class="hljs-comment"># Create MIMEText object</span>
message = MIMEText(text, <span class="hljs-string">"plain"</span>)
message[<span class="hljs-string">"Subject"</span>] = <span class="hljs-string">"Plain text email"</span>
message[<span class="hljs-string">"From"</span>] = sender_email
message[<span class="hljs-string">"To"</span>] = receiver_email

<span class="hljs-comment"># Send the email</span>
<span class="hljs-keyword">with</span> smtplib.SMTP(smtp_server, port) <span class="hljs-keyword">as</span> server:
    server.starttls()  <span class="hljs-comment"># Secure the connection</span>
    server.login(login, password)
    server.sendmail(sender_email, receiver_email, message.as_string())

print(<span class="hljs-string">'Sent'</span>)
</code></pre>
<p><strong>In the script</strong>:</p>
<ul>
<li><p>The ‘smtplib’ and ‘MIMEText’ modules have been imported from Python’s library. </p>
</li>
<li><p>As mentioned, SMTP server configuration needs to be updated with your credentials. But the server endpoint and port are as is. </p>
</li>
<li><p>Since this is a bare-bones script, I used ‘MIMEText’, which holds ‘plaintext’ only. But the script can be easily refactored to use ‘MIMEMultipart’ for both ‘plaintext’ and ‘HTML’. Jump to the quick tut below to see how it’s done. </p>
</li>
<li><p>When sending the email, I chose to use the ‘with’ statement (context manager) to ensure the SMTP server connection gets closed right after the email gets sent. </p>
</li>
</ul>
<p><strong>Security tip</strong>: </p>
<p>Server information and the login credentials shouldn't be hardcoded into your sending script. When setting the script for production, make sure you use environment variables to store sensitive information. This makes the code more secure and more flexible, particularly when you move it between different dev stages. For example ⬇️</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> os

smtp_server = os.getenv(<span class="hljs-string">"SMTP_SERVER"</span>, <span class="hljs-string">"default.smtp.server"</span>)
login = os.getenv(<span class="hljs-string">"SMTP_LOGIN"</span>)
password = os.getenv(<span class="hljs-string">"SMTP_PASSWORD"</span>)

<span class="hljs-comment"># Example usage in an SMTP connection setup</span>
<span class="hljs-comment"># smtp.login(login, password)</span>
</code></pre>
<p>Note that you need to set the variables in your operating system prior to running the script. </p>
<h3 id="heading-refactor-the-script-to-use-html-emails">Refactor the script to use HTML emails</h3>
<p>HTML emails provide a better user experience. They allow you to include formatted text, images, tables, clickable links, and custom styling. This works great for marketing emails, newsletters, or any communication where design and branding matter. </p>
<p>So, to refactor the script, you would import ‘MIMEMultipart’ and ‘MIMEText’. This action allows you to customize the HTML emails yet keep the plain-text versions as a fallback if your recipients cannot open the HTML email. </p>
<p>Here’s the revised script:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> smtplib
<span class="hljs-keyword">from</span> email.mime.multipart <span class="hljs-keyword">import</span> MIMEMultipart
<span class="hljs-keyword">from</span> email.mime.text <span class="hljs-keyword">import</span> MIMEText

<span class="hljs-comment"># Configuration</span>
smtp_server = <span class="hljs-string">"live.smtp.mailtrap.io"</span>
port = <span class="hljs-number">587</span>
login = <span class="hljs-string">"api"</span>  <span class="hljs-comment"># Mailtrap login</span>
password = <span class="hljs-string">"1a2b3c4d5e6f7g"</span>  <span class="hljs-comment"># Mailtrap password</span>

sender_email = <span class="hljs-string">"mailtrap@example.com"</span>
receiver_email = <span class="hljs-string">"new@example.com"</span>

message = MIMEMultipart()
message[<span class="hljs-string">"From"</span>] = sender_email
message[<span class="hljs-string">"To"</span>] = receiver_email
message[<span class="hljs-string">"Subject"</span>] = <span class="hljs-string">"HTML Email"</span>

<span class="hljs-comment"># Add plain text content (optional, for email clients that don't render HTML)</span>
message.attach(MIMEText(<span class="hljs-string">"This is a plain text version of the email."</span>, <span class="hljs-string">"plain"</span>))

<span class="hljs-comment"># Add HTML content</span>
html_content = <span class="hljs-string">"""\
&lt;html&gt;
  &lt;body&gt;
    &lt;h1&gt;Welcome to Mailtrap!&lt;/h1&gt;
    &lt;p&gt;This is an example of an HTML email.&lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;
"""</span>
message.attach(MIMEText(html_content, <span class="hljs-string">"html"</span>))

<span class="hljs-comment"># Send the email</span>
<span class="hljs-keyword">with</span> smtplib.SMTP(smtp_server, port) <span class="hljs-keyword">as</span> server:
    server.starttls()
    server.login(login, password)
    server.sendmail(sender_email, receiver_email, message.as_string())

print(<span class="hljs-string">'Sent'</span>)
</code></pre>
<p>Lastly, I’ve included video instructions for the SMTP method – so if that works better for you, feel free to check it out 🔽. </p>
<p><a target="_blank" href="https://www.youtube.com/watch?v=ufLpTc9up8s&amp;t=1s">How to send email in Python using Mailtrap - Tutorial by Mailtrap</a></p>
<h2 id="heading-how-to-send-emails-with-the-mailtrap-email-api">How to Send emails with the Mailtrap email API</h2>
<p>If you're looking to move beyond using SMTP for sending emails and want to integrate Mailtrap’s email API into your Python applications, this section will walk you through how to do that. </p>
<p>The Mailtrap <a target="_blank" href="https://mailtrap.io/smtp-api/">SMTP email API</a> allows you to send emails more efficiently, with added flexibility and scalability. Before starting, make sure you have a verified sending domain on Mailtrap and the Mailtrap API token, which you’ll use to authenticate requests.</p>
<p><strong>Note</strong>: I’m covering the API integration using the official Mailtrap Python SDK. </p>
<p>So, first you install the official SDK with the command below. </p>
<pre><code class="lang-python">pip install mailtrap
</code></pre>
<p><strong>Prerequisite</strong>: Ensure your Python package version is 3.6+ or higher. </p>
<p>After installing the SDK, the next step is to create a Mail object. This object will represent the email you want to send, including essential details like the sender, recipient, subject, and email content. </p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> mailtrap <span class="hljs-keyword">as</span> mt

<span class="hljs-comment"># Create the mail object</span>
mail = mt.Mail(
    sender=mt.Address(email=<span class="hljs-string">"mailtrap@example.com"</span>, name=<span class="hljs-string">"Mailtrap Test"</span>),  <span class="hljs-comment"># Sender info</span>
    to=[mt.Address(email=<span class="hljs-string">"your@email.com"</span>)],  <span class="hljs-comment"># Recipient info</span>
    subject=<span class="hljs-string">"You are awesome!"</span>,  <span class="hljs-comment"># Email subject</span>
    text=<span class="hljs-string">"Congrats for sending a test email with Mailtrap!"</span>  <span class="hljs-comment"># Email content (plain text)</span>
)

<span class="hljs-comment"># Create a client using your API key</span>
client = mt.MailtrapClient(token=<span class="hljs-string">"your-api-key"</span>)

<span class="hljs-comment"># Send the email</span>
client.send(mail)
</code></pre>
<p><strong>Quick notes:</strong></p>
<ul>
<li><p><strong>Sender and recipient</strong>: You need to specify the sender’s email address, which must match your verified domain. Similarly, define the recipient's email.</p>
</li>
<li><p><strong>Subject and text content</strong>: Set the subject and plain text content of the email. You can also add HTML content as I'll cover later.</p>
</li>
<li><p><strong>Client and sending</strong>: The ‘MailtrapClient’ is initialized with your Mailtrap API token, which authenticates the API request. The ‘send’ method is then called on the client, passing the ‘mail’ object.</p>
</li>
</ul>
<p>To create the client using the Mailtrap API token, take the following path within Mailtrap:<br><strong>Settings</strong> &gt; <strong>API Tokens</strong> &gt; <strong>Add Token</strong> </p>
<p><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXeLlNbf0Uiub9YYVxcfiNsZL6_uNHKfuO4dW6ZZGXWEGkF7X4mw82KMsrAWX4hA_u_jYqi1G8aoh1-vOnxKjdXKackVG8HdrsyfHulzaIJVMrMcxmZvllXcNOXVxG7hFOJXgl2VBw?key=CJmzmKUWxlFjIw3A041wXvaj" alt="Add API tokens" width="1600" height="560" loading="lazy"></p>
<p>With that, you can use the following command to send emails:</p>
<pre><code class="lang-python"><span class="hljs-comment"># create client and send</span>
client = mt.MailtrapClient(token=<span class="hljs-string">"your-api-key"</span>)
client.send(mail)
</code></pre>
<p>Finally, here’s the SDK script for sending a bare-bones ‘plaintext’ email via Python SDK.</p>
<pre><code class="lang-python"> <span class="hljs-keyword">from</span> mailtrap <span class="hljs-keyword">import</span> Mail, Address, MailtrapClient

<span class="hljs-comment"># Create a Mail object with basic details for a plain text email</span>
mail = Mail(
    <span class="hljs-comment"># Specify the sender's email address and optional name</span>
    sender=Address(email=<span class="hljs-string">"mailtrap@example.com"</span>, name=<span class="hljs-string">"Mailtrap Test"</span>),
    <span class="hljs-comment"># Specify one or more recipients; here we use a list with a single recipient</span>
    to=[Address(email=<span class="hljs-string">"your@email.com"</span>, name=<span class="hljs-string">"Your Name"</span>)],
    <span class="hljs-comment"># Subject of the email</span>
    subject=<span class="hljs-string">"Simple Plain Text Email"</span>,
    <span class="hljs-comment"># The plain text content of the email</span>
    text=<span class="hljs-string">"This is a plain text email sent using the Mailtrap SDK. Simple and straightforward."</span>,
    <span class="hljs-comment"># Optional: categorize this email for easier sorting or management in the Mailtrap service</span>
    category=<span class="hljs-string">"Test"</span>,
    <span class="hljs-comment"># Optional: Additional headers can be specified, but are not required for plain text emails</span>
    headers={<span class="hljs-string">"X-Example-Header"</span>: <span class="hljs-string">"HeaderValue"</span>}
)

<span class="hljs-comment"># Initialize the MailtrapClient with your API token</span>
client = MailtrapClient(token=<span class="hljs-string">"your-api-key"</span>)

<span class="hljs-comment"># Send the email using the client's send method</span>
client.send(mail)

print(<span class="hljs-string">"Plain text email sent successfully."</span>)
</code></pre>
<p><strong>In the script</strong>:</p>
<ul>
<li><p>The imported classes include ‘MailtrapClient’, ‘Mail’, and ‘Address’ because I’m sending a plain text message. </p>
</li>
<li><p>The ‘Mail’ object contains:</p>
<ul>
<li><p>‘Mail’ constructor to create the object.</p>
</li>
<li><p>‘Sender’ which uses ‘Address’ class to define the name and email of the sender.</p>
</li>
<li><p>‘to’ which is typically an ‘Address’ objects list, but since this is a plain text email, it usually has direct recipients instead of the list. </p>
</li>
<li><p>‘subject’ which is the subject of the email. </p>
</li>
<li><p>‘text’ which contains the email content (in ‘plaintext’)</p>
</li>
<li><p>‘headers’ and ‘category’ which are optional fields that help better manage your emails. </p>
</li>
</ul>
</li>
</ul>
<ul>
<li><p>The email sending flow:</p>
<ul>
<li><p>‘MailtrapClient’ gets created and authenticated via the API token. </p>
</li>
<li><p>The ‘MailtrapClient’ ‘send’ method gets called and passes the ‘mail’ object as an email-sending argument.  </p>
</li>
<li><p>The “Plain text email sent successfully.” message gets printed to confirm the action. </p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-refactor-the-script-to-include-html-and-attachments">Refactor the script to include HTML and attachments</h3>
<p>Again, it’s pretty straightforward to refactor the script using the ‘MIMEMultipart’ class for more complex email structures. </p>
<p>Here’s the refactored code:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> mailtrap <span class="hljs-keyword">as</span> mt
<span class="hljs-keyword">from</span> email.mime.multipart <span class="hljs-keyword">import</span> MIMEMultipart
<span class="hljs-keyword">from</span> email.mime.text <span class="hljs-keyword">import</span> MIMEText

<span class="hljs-comment"># Create a multipart email message</span>
message = MIMEMultipart()
message[<span class="hljs-string">"Subject"</span>] = <span class="hljs-string">"HTML Email"</span>

<span class="hljs-comment"># Plain text version (for email clients that don't support HTML)</span>
message.attach(MIMEText(<span class="hljs-string">"This is the plain text version."</span>, <span class="hljs-string">"plain"</span>))

<span class="hljs-comment"># HTML version</span>
html_content = <span class="hljs-string">"""\
&lt;html&gt;
  &lt;body&gt;
    &lt;h1&gt;Welcome to Mailtrap!&lt;/h1&gt;
    &lt;p&gt;This is an HTML email with some &lt;b&gt;bold text&lt;/b&gt; and a &lt;a href="https://example.com"&gt;link&lt;/a&gt;.&lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;
"""</span>
message.attach(MIMEText(html_content, <span class="hljs-string">"html"</span>))

client = mt.MailtrapClient(token=<span class="hljs-string">"your-api-key"</span>)

<span class="hljs-comment"># Now send the email with Mailtrap's API</span>
mail = mt.Mail(
    sender=mt.Address(email=<span class="hljs-string">"mailtrap@example.com"</span>, name=<span class="hljs-string">"Mailtrap Test"</span>),
    to=[mt.Address(email=<span class="hljs-string">"your@email.com"</span>)],
    subject=<span class="hljs-string">"You are awesome!"</span>,
    html=message.as_string()  <span class="hljs-comment"># Pass the HTML content as a string</span>
)
client.send(mail)
</code></pre>
<h3 id="heading-environmental-setup-for-production">Environmental setup for production</h3>
<p>Before I dive into the details, I’d like to remind you of security best practices:</p>
<ol>
<li><p><strong>Securely store API keys and credentials</strong>: On production, never hardcode sensitive data like API keys, email login credentials, or other secrets directly into your source code. Doing so exposes your application.</p>
</li>
<li><p><strong>Use environment variables</strong>: By doing this, you can keep your credentials safe and easily switch between different configurations (like dev, staging, and production). </p>
</li>
</ol>
<p>Now, here’s how to set it all up:</p>
<ol>
<li><p>Use the ‘python-dotenv’ package to load environment variables from a ‘.env’ file. Install the lib with the following command:</p>
<pre><code class="lang-python"> pip install python-dotenv
</code></pre>
</li>
</ol>
<ol start="2">
<li><p>Create a ‘.env’ file in the root of your project to store your environment variables securely. This file will contain sensitive information, such as your Mailtrap API key, login credentials, and SMTP server details. Here’s an example:</p>
<pre><code class="lang-python"> SMTP_SERVER=smtp.mailtrap.io
 SMTP_PORT=<span class="hljs-number">587</span>
 SMTP_LOGIN=your_mailtrap_login
 SMTP_PASSWORD=your_mailtrap_password
 MAILTRAP_API_KEY=your_mailtrap_api_key
</code></pre>
</li>
</ol>
<p><strong>Important note</strong>: Ensure this ‘.env’ file is never pushed to version control (like Git). Add it to your ‘.gitignore’ to avoid accidental exposure.</p>
<ol start="3">
<li><p>Once you've created your ‘.env’ file, you need to load the variables into your Python script. At the top of your script, import the ‘dotenv’ package and call ‘load_dotenv()’ to load the environment variables.</p>
<pre><code class="lang-python"> <span class="hljs-keyword">from</span> dotenv <span class="hljs-keyword">import</span> load_dotenv
 <span class="hljs-keyword">import</span> os

 <span class="hljs-comment"># Load environment variables from the .env file</span>
 load_dotenv()

 <span class="hljs-comment"># Retrieve environment variables securely</span>
 smtp_server = os.getenv(<span class="hljs-string">"SMTP_SERVER"</span>)
 smtp_port = os.getenv(<span class="hljs-string">"SMTP_PORT"</span>)
 smtp_login = os.getenv(<span class="hljs-string">"SMTP_LOGIN"</span>)
 smtp_password = os.getenv(<span class="hljs-string">"SMTP_PASSWORD"</span>)
 mailtrap_api_key = os.getenv(<span class="hljs-string">"MAILTRAP_API_KEY"</span>)
</code></pre>
</li>
</ol>
<ol start="4">
<li><p>With the environment variables loaded, you can replace the hardcoded credentials in the script with these environment variables. Here’s an example:</p>
<pre><code class="lang-python"> <span class="hljs-keyword">import</span> smtplib
 <span class="hljs-keyword">from</span> email.mime.text <span class="hljs-keyword">import</span> MIMEText
 <span class="hljs-keyword">from</span> dotenv <span class="hljs-keyword">import</span> load_dotenv
 <span class="hljs-keyword">import</span> os

 <span class="hljs-comment"># Load environment variables</span>
 load_dotenv()

 <span class="hljs-comment"># Fetching SMTP credentials from environment variables</span>
 smtp_server = os.getenv(<span class="hljs-string">"SMTP_SERVER"</span>)
 smtp_port = os.getenv(<span class="hljs-string">"SMTP_PORT"</span>)
 smtp_login = os.getenv(<span class="hljs-string">"SMTP_LOGIN"</span>)
 smtp_password = os.getenv(<span class="hljs-string">"SMTP_PASSWORD"</span>)

 sender_email = <span class="hljs-string">"mailtrap@example.com"</span>
 receiver_email = <span class="hljs-string">"new@example.com"</span>
 subject = <span class="hljs-string">"Plain text email"</span>
 text = <span class="hljs-string">"""\
 Hi,
 Check out the new post on the Mailtrap blog:
 https://blog.mailtrap.io/2018/09/27/cloud-or-local-smtp-server/
 """</span>

 <span class="hljs-comment"># Create MIMEText object</span>
 message = MIMEText(text, <span class="hljs-string">"plain"</span>)
 message[<span class="hljs-string">"Subject"</span>] = subject
 message[<span class="hljs-string">"From"</span>] = sender_email
 message[<span class="hljs-string">"To"</span>] = receiver_email

 <span class="hljs-comment"># Send email using environment variables</span>
 <span class="hljs-keyword">with</span> smtplib.SMTP(smtp_server, smtp_port) <span class="hljs-keyword">as</span> server:
     server.starttls()  <span class="hljs-comment"># Secure the connection</span>
     server.login(smtp_login, smtp_password)
     server.sendmail(sender_email, receiver_email, message.as_string())

 print(<span class="hljs-string">"Email sent successfully!"</span>)
</code></pre>
</li>
</ol>
<h4 id="heading-pro-tips">Pro tips:</h4>
<p>First, ensure your environment variables are only accessible to authorized users. On a production server, this typically means only allowing access to the environment variables through the deployment configuration (for example, through Heroku’s config vars, AWS Secrets Manager, or other cloud-based secret management tools).</p>
<p>Second, use different environment variables for development, staging, and production. This ensures that your production environment is isolated and secured from the rest of your development process.</p>
<p>Once your environment variables are configured locally, deploy your application to a production environment. Make sure to set the same environment variables in your production server or service.</p>
<p>If you're deploying to platforms like Heroku, AWS, or Google Cloud, you can use their environment variable management tools to securely store and access your secrets without having to manage a ‘.env’ file manually.</p>
<h2 id="heading-wrapping-up">Wrapping up</h2>
<p>This quick tutorial provides more than enough to get started with sending emails in Python. And note that the scripts featured above can be extended to include HTML, multiple recipients, attachments, images, and so on. </p>
<p>If you’re interested in that and more security tips and best practices, you can check out the Mailtrap blog for more detailed tutorials.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Stop [Marketing] E-Mail Bouncebacks! How to Configure SPF, DMARC & DKIM ]]>
                </title>
                <description>
                    <![CDATA[ By Andreas Lopez Setup Requirements: Your Domain Name System (DNS) Editor (i.e. GoDaddy Admin that has the email addresses registered) 3rd Party e-mail Admin Accounts (e-mail Blast Service [Mailchimp, ConstantContact, etc.], Additional Mail Server y... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/bananas-stop-email-bouncebacks-spf-dmarc-dkim/</link>
                <guid isPermaLink="false">66d45d97052ad259f07e4a55</guid>
                
                    <category>
                        <![CDATA[ Backend Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #content marketing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Digital Marketing  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ email ]]>
                    </category>
                
                    <category>
                        <![CDATA[ email marketing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ newsletters ]]>
                    </category>
                
                    <category>
                        <![CDATA[ servers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ smtp ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sat, 22 Jun 2019 17:10:52 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/06/stop-email-bouncebacks-post-image.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Andreas Lopez</p>
<p><strong>Setup Requirements:</strong></p>
<ul>
<li>Your Domain Name System (DNS) Editor (i.e. GoDaddy Admin that has the email addresses registered)</li>
<li>3rd Party e-mail Admin Accounts (e-mail Blast Service [Mailchimp, ConstantContact, etc.], Additional Mail Server you might be using, etc.)</li>
</ul>
<p>You might be reading this because you want help resolving an error you just received. This error might be stating something about your DMARC records and that the e-mail was not authenticated. And most likely you attempted to e-mail someone with a ‘@gmail.com’ or ‘@yahoo.com’ address or similar free, big e-mail providers which have higher default guidelines than an e-mail server you would set up through your own company.</p>
<p>I was there too and struggled quite some time to get this figured out — not just what you need, but also how to get it done, the right way.</p>
<h3 id="heading-our-statistics-before-and-after-configuring-spf-dmarc-amp-dkim">Our Statistics before and after configuring SPF, DMARC &amp; DKIM:</h3>
<p>As you will be able to see in the following pictures these implementations show us that:</p>
<ul>
<li>Bounce Rate was 70% before implementation, a whole 21441 E-mails that never made it into the subscribers inbox.</li>
<li>After implementation the Bounce Rate was only 5.6%, down to only 1855 Bouncebacks.</li>
<li>The bouncebacks are not all just due to security, some e-mails are deleted or the subscriber made a typo (mail.com instead of gmail.com is a typical one).</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/06/ConstantContact-Before-After.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Constant Contact Bounce Statistics, Before &amp; After configuring SPF, DMARC &amp; DKIM.</em></p>
<h3 id="heading-enough-talk-about-how-important-the-implementation-is-lets-get-to-it">Enough talk about how important the implementation is - lets get to it!</h3>
<p>In order to be 100% compliant in terms of e-mail authentication, you need 3 things configured:</p>
<ul>
<li><strong>SPF (Sender Policy Framework):</strong> a framework used to prevent e-mail forgery aka Spoofing. Spoofing is when someone is pretending to be sent from your e-mail address.</li>
<li><strong>DKIM (DomainKeys Identified Mail):</strong> This will allow a server to send e-mails in your name while being authenticated to make sure it’s really you. For example, if you use MailChimp or ConstantContact for newsletter blasts and say it’s from ‘john@doecompany.com’, the e-mails will still be sent from MailChimp or ConstantContacts server. However, you verified with your Blast e-mail service that is indeed you and not someone pretending to be you. <strong>This is the most important one to set up correctly for businesses, as otherwise there will be a high bounce-back rate!</strong></li>
<li><strong>DMARC (Domain-based Message Authentication, Reporting, and Conformance):</strong> Also an Anti-Spoofing mechanism that will work in conjunction with SPF. Having one or the other is ineffective — you will need both to be properly protected.</li>
</ul>
<p>DNS Editor / DNS Zone Editor, GoDaddy Screenshot Examples (Login and navigate to your Admin Dashboard first):</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*RyXa5A0poh-LVZgw.png" alt="Image" width="549" height="72" loading="lazy">
<em>GoDaddy Manage Domains Dashboard Screenshot with Arrow pointing at Manage option. (1)</em></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*lPnjNy8Qd3T6d7lq.png" alt="Image" width="600" height="400" loading="lazy">
<em>GoDaddy Domains Dashboard Screenshot with the arrow pointing at Manage Zones option. (1)</em></p>
<p>Select the Domain you need to add the DNS entries to in the screen after clicking on Manage Zones.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*CK4w3j4dsw2ZE060.png" alt="Image" width="700" height="216" loading="lazy">
<em>GoDaddy DNS Zone Editor Admin Dashboard Screenshot with Arrow pointing on the Add Option. (1)</em></p>
<p>On the bottom of your records on the right-hand side, you will see an ‘Add’ button which will lead to the following dialog menu in which you will enter the SPF, DMARC &amp; DKIM entries each individually:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*lZzVRpdjY3z0dq53.png" alt="Image" width="600" height="207" loading="lazy">
_GoDaddy Add DNS Entry Admin Dashboard Screenshot with button pointing at Save button and TXT as type, <em>dmarc as Host and the required value under TXT Value highlighted. (1)</em></p>
<p>For other guides for Zone Editors, just go to the knowledge base/support center of your Domain Provider.</p>
<h3 id="heading-setting-up-spf">Setting up SPF:</h3>
<p>The SPF is the easiest to set up. You will need 2 things:</p>
<ol>
<li>Your DNS Editor (i.e. GoDaddy Admin Portal)</li>
<li>The IP address of your e-mail server</li>
</ol>
<p>After accessing your DNS Editor (also called DNS Zone Editor in CPanel), you want to create a new TXT entry. In this TXT Entry, you should have 3 possible fields: Host, TXT Value / Value &amp; TTL (Time-To-Live). What you will enter in these fields is the following (some details might vary, <strong>this is based on a GoDaddy installation</strong>):Host: @ TXT Value: v=spf1 +a +mx +ip4:~allTTL: 1 Hour</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*5dQV9o1PaFDrABCi3ISHVg.png" alt="Image" width="800" height="217" loading="lazy">
<em>GoDaddy DNS Sample TXT Entry for the SPF settings as described above.</em></p>
<p><strong>Explanation / Meaning of these settings:</strong></p>
<p>‘@’ is the designation within GoDaddy that refers to the Domain you are working in. So if you are working inside ‘doecompany.com’ you could replace ‘@’ with ‘doecompany.com’ and the result would be the same. However, it is best practice to use the ‘@’ symbol instead in the case of GoDaddy.</p>
<p> is the IP of where your e-mails are being sent from. This is not necessarily the same IP that the actual website is hosted on.</p>
<p><strong>+a:</strong> Includes A record</p>
<p><strong>+mx:</strong> Includes Mail Server record</p>
<p><strong>+ip4:</strong> Designates from which IPv4 server</p>
<p><strong>~all:</strong> Records outside of the prior declared ones will fail.</p>
<p><strong>TTL = 1 hour</strong> (or 3600 seconds): Time-To-Live, or how often this should expire. If you were to change e-mail servers, you would be glad that there is only a maximum gap of 1 hour of not being authenticated.</p>
<h3 id="heading-setting-up-dkim">Setting up DKIM:</h3>
<p>This is the most tedious of the three to set up and the most critical one. You will authenticate the 3rd party to send on behalf of your e-mail name, i.e. ‘john@doecompany.com’.</p>
<p>I have 2 DKIMs currently set up:</p>
<ol>
<li>For my actual Mail Server which lives on a different server than my actual website (this is more common in Enterprise environments).</li>
<li>For my e-mail newsletter blast service provider (ConstantContact in this case, it could easily be Mailchimp or someone else in your case).</li>
</ol>
<p>For both scenarios, your legwork is the same. You will have to contact the e-mail support of your Mail Server or Third Party e-mail sending service and have them install the DKIM on their end, for your account.</p>
<p>This is completely out of your hands and typically takes them 1–2 days to complete this task. Basically what is happening is that they will register and install an RSA of at least 1024-Bit encoding (2048 is better) on their server.</p>
<p>After they got it set up, they will send you a Public Key that you will be using in the next step to set up your DKIM record.</p>
<p>Just like with the SPF &amp; DMARC records you will access your DNS Editor (also called DNS Zone Editor in CPanel), and create a new TXT entry. In this TXT Entry, you should have 3 possible fields: Host, TXT Value / Value &amp; TTL (Time-To-Live). What you will enter in these fields is the following (some details might vary, this is based on a GoDaddy installation with the e-mails being hosted on inmotionhosting.com and ConstantContact as Newsletter service). Remember to make 1 separate entry per DKIM record:Host: ._domainkeyTXT Value: v=DKIM1; k=rsa; p=TTL: 1 Hour</p>
<p>Make sure not to leave any spaces after the ‘=’ symbols.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*nj_ycXzk_LsASRBfcw7b3A.png" alt="Image" width="800" height="216" loading="lazy">
<em>GoDaddy DNS Sample TXT Entry for the DKIM settings as described above.</em></p>
<p><strong>Explanation / Meaning of these settings:</strong></p>
<p>The host can be a name or number and is truly unique to the third party. When an e-mail is being sent on your behalf, that e-mail will have that name or number included in the header. That is the record it will be looking under your domain for.</p>
<p>In layman’s terms and our example, the recipient server would go to ‘doecompany’s DNS records and look if what the 3rd party claims to be true will be there. Only if the public key properly validates with the key on their server, the e-mails will be sent out.</p>
<p><strong>v=DKIM1:</strong> Simply specifies the version of DKIM being used to clarify further what to look for.</p>
<p><strong>k=rsa:</strong> RSA is the most typical one to use as the Key (k). Your 3rd party might opt-in to use something else. But RSA with a 2048 bit encryption is the most secure option you can have at the moment. 1024 bit is good, too.</p>
<p><strong>p=:</strong> Instead of ‘’ you would be provided with either a 1024 bit or 2048 bit string of seemingly random text and numbers or other values suited to whatever encryption the 3rd party decided to utilize.</p>
<p><strong>TTL = 1 hour</strong> (or 3600 seconds): Time-To-Live, or how often this should expire. If you were to change e-mail servers, you would be glad that there is only a maximum gap of 1 hour of not being authenticated.</p>
<h3 id="heading-setting-up-dmarc">Setting up DMARC:</h3>
<p><strong>Reminder:</strong> In order for the DMARC to do its job, you MUST setup SPF AND DKIM before. Because DMARC verifies SPF &amp; DKIM settings and whether or not the sender suits these settings and is not a spoofer. If SPF &amp; DKIM are not set up, DMARC won’t work and will result in rejected e-mails.</p>
<p>Just like with the SPF records you will access your DNS Editor (also called DNS Zone Editor in CPanel), and create a new TXT entry. In this TXT Entry, you should have 3 possible fields: Host, TXT Value / Value &amp; TTL (Time-To-Live). What you will enter in these fields is the following (some details might vary, this is based on a GoDaddy installation with the e-mails being hosted on inmotionhosting.com):Host: _dmarcTXT Value: v=DMARC1;p=reject;sp=none;adkim=r;aspf=r;pct=100;fo=0;rf=afrf;ri=86400TTL: 1 Hour</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*TvOQkx-VHgLLx7o831YsAg.png" alt="Image" width="800" height="213" loading="lazy">
<em>GoDaddy DNS Sample TXT Entry for the DMARC settings as described above.</em></p>
<p><strong>Explanation / Meaning of these settings:</strong></p>
<p>The Host is declared as ‘_dmarc’ because within GoDaddy it will automatically add ‘.johndoe.com’ as a subdomain. This means when an e-mail is being sent out, the DMARC will always be checked under that selector against your domain. If this is not set up properly as ‘_dmarc’, the e-mail servers won’t be able to find your DMARC entry and will automatically fail your e-mail as they believe there is no entry to begin with.</p>
<p><strong>v=DMARC1:</strong> Declares the version of the DMARC to clarify what is being used and make authentication more legitimate.</p>
<p><strong>p=reject:</strong> E-mails will be rejected from the recipient e-mail server if they don’t match the DMARC records.</p>
<p><strong>sp=none:</strong> Do not check if subdomains and the main domain have aligned settings; this is optional.</p>
<p><strong>adkim=r:</strong> Whether to be strict (s) or relaxed (r) with the DKIM identifier settings; relaxed is the default.</p>
<p><strong>aspf=r:</strong> Whether to be strict (s) or relaxed (r) with the SPF identifier settings; relaxed is the default.</p>
<p><strong>pct=100:</strong> 100 percent of e-mails are going to be affected by the DMARC. Integer values between 1 to 100 only. The smaller set would make sense only for testing; should be 100 for security purposes.</p>
<p><strong>fo=0:</strong> A DMARC error report is created if SPF &amp; DKIM fail to be authenticated. 0 is the default value. Others are 1, d and s. 1 is if either one fails, to generate a record. d if the signature failed evaluation. s if SPF evaluation failed.</p>
<p><strong>rf=afrf:</strong> The formatting for the message failure reports. afrf is the only supported value at the point of this writing.</p>
<p><strong>ri=86400:</strong> How many seconds passed between sending the report to the sender. 86400 is default which is 24 hours or 1 day. Many of the major mailbox providers such as Gmail, Yahoo, etc. will send more than one report a day.</p>
<p><strong>TTL = 1 hour</strong> (or 3600 seconds): Time-To-Live, or how often this should expire. If you were to change e-mail servers, you would be glad that there is only a maximum gap of 1 hour of not being authenticated.</p>
<p>And that is how you properly authenticate your e-mails. I hope this took some of the mystery and complication out for you. You will be on your way of not getting those troublesome kickbacks from your mailer-daemon anymore!</p>
<hr>
<p><strong>Author:</strong></p>
<p>Andreas Lopez — <a target="_blank" href="https://www.linkedin.com/in/andreaslopez/">https://www.linkedin.com/in/andreaslopez/</a></p>
<p><strong>Editors:</strong></p>
<p>Stevan Pupavac — <a target="_blank" href="https://www.linkedin.com/in/stevan-pupavac/">https://www.linkedin.com/in/stevan-pupavac/</a></p>
<p>Frederick Alcantara — <a target="_blank" href="https://www.linkedin.com/in/frederick-alcantara/">https://www.linkedin.com/in/frederick-alcantara/</a></p>
<p><strong>Sources:</strong></p>
<ol>
<li>GoDaddy Screenshots by DMARCanalyzer.com: <a target="_blank" href="https://www.dmarcanalyzer.com/dmarc/dmarc-record-setup-guides/dmarc-setup-guide-godaddy/">https://www.dmarcanalyzer.com/dmarc/dmarc-record-setup-guides/dmarc-setup-guide-godaddy/</a></li>
</ol>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
