smtplib

SMTP (Simple Mail Transfer Protocol)

The SMTP (Simple Mail Transfer Protocol) protocol is used to send emails over the internet. It is a client-server protocol, where the client (usually an email client) connects to the server (usually an email server) and sends the email message.

The SMTP protocol defines a set of commands that the client can send to the server, and a set of responses that the server can send back to the client. The most common SMTP commands are:

  • HELO: The client introduces itself to the server.

  • MAIL FROM: The client specifies the sender's email address.

  • RCPT TO: The client specifies the recipient's email address.

  • DATA: The client sends the email message.

  • QUIT: The client terminates the connection.

SMTPLIB

SMTPLIB is a Python module that implements the SMTP protocol. The SMTPLIB module provides a simple interface for sending emails over the internet. To use SMTPLIB, you just need to import the module and create an SMTP object. The SMTP object can then be used to send emails using the SMTP commands described above.

Here is a simple example of how to use SMTPLIB to send an email:

import smtplib

# Create an SMTP object
smtp = smtplib.SMTP('smtp.example.com', 587)

# Send the HELO command
smtp.helo('mydomain.com')

# Send the MAIL FROM command
smtp.mail('from@mydomain.com')

# Send the RCPT TO command
smtp.rcpt('to@example.com')

# Send the DATA command
smtp.data('Hello from Python!')

# Send the QUIT command
smtp.quit()

Potential Applications

SMTPLIB can be used to send emails from any Python program. This can be useful for a variety of applications, such as:

  • Sending notifications to users

  • Sending marketing emails

  • Sending automated reports

  • Sending emails from web forms

Real-World Implementations

SMTPLIB is used in a variety of real-world applications, including:

  • The Django web framework uses SMTPLIB to send emails from web forms.

  • The Celery task queue uses SMTPLIB to send notifications to users.

  • The Jenkins continuous integration server uses SMTPLIB to send automated reports.

Further Reading


Introduction to SMTP Client Session

The smtplib module in Python provides a client library for sending emails using the Simple Mail Transfer Protocol (SMTP) or its extended version, Extended Simple Mail Transfer Protocol (ESMTP).

SMTP Class

The SMTP class represents an SMTP client session. It provides a comprehensive set of methods to perform SMTP and ESMTP operations.

Initialization:

import smtplib

smtp = smtplib.SMTP(host='smtp.example.com', port=587, local_hostname='my_local_host')
  • host: The hostname or IP address of the SMTP server.

  • port: The port number of the SMTP server (default is 25).

  • local_hostname: The fully qualified domain name (FQDN) of the local host (optional).

SMTP Methods

Connection Methods:

  • connect(): Establishes a connection to the SMTP server.

  • ehlo(): Sends an EHLO command to the server, identifying the client and requesting ESMTP capabilities.

  • helo(): Sends a HELO command to the server, identifying the client (without ESMTP capabilities).

Authentication Methods:

  • login(): Authenticates with the server using the username and password provided by the SMTP object.

  • starttls(): Initiates a TLS (Transport Layer Security) connection encryption.

Email Sending Methods:

  • sendmail(): Sends an email message to the specified recipients.

  • send(): Sends data to the server, which may include multiple email messages.

  • quit(): Closes the SMTP session.

Real-World Applications

SMTP is widely used in email applications to send emails from clients to mail servers.

import smtplib

smtp = smtplib.SMTP('smtp.example.com', 587)
smtp.ehlo()
smtp.starttls()
smtp.login('username', 'password')
smtp.sendmail('sender@example.com', 'recipient@example.com', 'Hello World!')
smtp.quit()

This code snippet demonstrates a complete email sending process using the SMTP client class:

  • Establishes a connection to the SMTP server using EHLO.

  • Secures the connection using TLS.

  • Authenticates with the server using the provided credentials.

  • Sends an email message to the specified recipient.

  • Closes the SMTP session.


SMTP (Simple Mail Transfer Protocol)

Introduction:

SMTP is a communication protocol used to transfer emails over the internet. It enables you to send emails from a client (e.g., your email program) to a mail server (e.g., Gmail, Yahoo Mail).

SMTP Class:

The smtplib module in Python provides the SMTP class, which allows you to interact with an SMTP server for sending emails.

Topics:

1. Initialization:

  • SMTP("domain.org") establishes a connection with an SMTP server at the specified domain.

2. Sending Mail:

  • sendmail(from_addr, to_addrs, msg) sends an email message from the specified sender address (from_addr) to the recipient addresses (to_addrs).

    • msg is a string representing the email message, typically constructed using the email module.

3. Quitting:

  • quit() terminates the connection with the SMTP server.

Example:

import smtplib

# Initialize SMTP connection
smtp = smtplib.SMTP("smtp.example.com")

# Construct email message (using email package)
msg = """
From: you@example.com
To: recipient@example.com
Subject: Hello World

This is an email message sent using Python smtplib.
"""

# Send email
smtp.sendmail("you@example.com", ["recipient@example.com"], msg)

# Quit connection
smtp.quit()

Using with Statement:

You can use the with statement to automatically issue the QUIT command when done using the SMTP object:

with smtplib.SMTP("smtp.example.com") as smtp:
    smtp.noop()  # Perform an action, such as checking for new mail

Potential Applications:

  • Sending automated emails from web applications

  • Building email clients

  • Relaying emails from your own server

  • Handling large email volumes efficiently


Simplified Explanation of smtplib.send()

smtplib.send() Method

The smtplib.send() method is used to send an email message to a remote host. It takes two main arguments:

  • self: The SMTP object that manages the connection to the remote host.

  • data: The bytes representing the email message.

Auditing Event

When smtplib.send() is called, it triggers an auditing event with the following arguments:

  • self: The SMTP object.

  • data: The bytes sent to the remote host.

This event can be used to log or monitor email activity.

Version Changes

  • Version 3.3: Added support for "with" statement and the source_address argument.

  • Version 3.5: Added support for SMTPUTF8 extension.

  • Version 3.9: Changed the behavior of timeout parameter, raising a ValueError if set to zero to prevent non-blocking socket creation.

Real-World Applications

smtplib.send() is essential for sending emails in Python applications. It can be used in various scenarios, such as:

  • Sending notifications

  • Sending newsletters

  • Sending automated emails from web forms

Complete Code Implementation

Here is a simple example of using smtplib.send():

import smtplib

# Create an SMTP object
smtp = smtplib.SMTP('smtp.example.com', 587)

# Start TLS encryption
smtp.starttls()

# Login to the email server
smtp.login('username', 'password')

# Prepare the email message
message = """
From: John Doe <john.doe@example.com>
To: Jane Smith <jane.smith@example.com>
Subject: Hello!

Hi Jane,

I hope this email finds you well.

Best,
John
"""

# Send the email
smtp.sendmail('john.doe@example.com', 'jane.smith@example.com', message.encode('utf-8'))

# Quit the SMTP connection
smtp.quit()

Potential Applications

The following are potential applications of smtplib.send():

  • Email Automation: Automating the sending of emails based on certain events or triggers.

  • Customer Relationship Management (CRM): Sending personalized emails to customers for marketing or support purposes.

  • Notifications: Sending notifications about system events, updates, or alerts.


SMTP_SSL (Secure Sockets Layer)

What is SMTP_SSL?

SMTP_SSL is a secure version of the Simple Mail Transfer Protocol (SMTP) that uses encryption to protect email data during transmission. This ensures that emails remain confidential and cannot be intercepted or read by third parties.

When to Use SMTP_SSL?

SMTP_SSL should be used in situations where maintaining the privacy and security of emails is crucial, such as when sending sensitive information or financial data.

How to Use SMTP_SSL

To use SMTP_SSL, you need to:

  1. Import the smtplib module.

  2. Instantiate an SMTP_SSL object with the appropriate parameters:

    • host: The hostname or IP address of the SMTP server.

    • port: The port number for secure SMTP (usually 465).

  3. Use the SMTP_SSL object to send emails as usual.

Code Example:

import smtplib

smtp_ssl = smtplib.SMTP_SSL('smtp.example.com', 465)
smtp_ssl.login('username', 'password')
smtp_ssl.sendmail('from@example.com', 'to@example.com', 'Subject: Secure Email')
smtp_ssl.quit()

Parameters:

  • host: The hostname or IP address of the SMTP server. Defaults to the local host.

  • port: The port number for secure SMTP. Defaults to 465 (the standard SMTP-over-SSL port).

  • local_hostname: The hostname of the local machine.

  • timeout: A timeout value for the connection. Defaults to None (no timeout).

  • context: An ssl.SSLContext object to configure the secure connection.

  • source_address: The source IP address or hostname to use for outgoing connections.

Real-World Applications:

SMTP_SSL is widely used in the following applications:

  • Banking and finance: To securely transmit account statements and other sensitive financial information.

  • Healthcare: To protect patient data and medical records.

  • Government and military: To handle classified or confidential communications.

  • Personal email: To safeguard personal information and communications.


Simplified Explanation of LMTP Protocol

LMTP (Local Mail Transfer Protocol) is a mail delivery protocol similar to SMTP but optimized for local message transfers. It's often used in conjunction with Unix sockets for faster communication within a single server or cluster.

LMTP Class in Python's smtplib Module

The smtplib.LMTP class provides an interface for connecting to an LMTP server. It extends the smtplib.SMTP class, inheriting its core functionality for sending and receiving messages.

Arguments:

  • host (str): Hostname or Unix socket path of the LMTP server. For Unix sockets, use an absolute path starting with '/'.

  • port (int): Port number (default: 2003).

  • local_hostname (str): Local hostname to use in HELO/EHLO commands.

  • source_address (str): Source address to use for connections.

  • timeout (float): Number of seconds to wait for connection and data transfer (default: None).

Authentication:

LMTP supports SMTP authentication mechanisms, but it's not always required. When using Unix sockets, authentication is typically not needed.

Real-World Example:

Sending an email using LMTP:

import smtplib

# Create an LMTP connection
with smtplib.LMTP('localhost', 2003) as server:
    # Identify server and send HELO command
    server.helo('my-hostname')

    # Send email message
    server.sendmail('sender@example.com', 'recipient@example.com', 'Subject: Test Message\n\nHello!')

Potential Applications:

  • Message Delivery within a Server: LMTP can be used to transfer messages between processes or components running on the same server.

  • Clustered Email Servers: LMTP provides a more efficient way to send messages between email servers in a cluster or distributed system.

  • Local Message Queuing: LMTP can be used as a local message queue, allowing applications to send messages to a central queue for later processing.


Exceptions in Python's smtplib Module

1. SMTPException

  • Base class for all SMTP-related exceptions.

  • Subclass of OSError.

  • Raised in situations where a general error occurs during SMTP operations.

2. SMTPServerDisconnected

  • Raised when the server unexpectedly disconnects or when an attempt is made to use an SMTP instance before connecting it to a server.

  • Prevents the usage of an SMTP instance that is not connected to a server.

Example:

try:
    smtp = smtplib.SMTP('smtp.example.com', 587)
    # Do something with the SMTP instance
except SMTPServerDisconnected:
    # Handle the exception

3. SMTPResponseException

  • Base class for exceptions that include an SMTP error code.

  • Attributes:

    • smtp_code: SMTP error code

    • smtp_error: SMTP error message

  • Raised when the SMTP server returns an error code.

4. SMTPSenderRefused

  • Raised when the sender address is refused by the SMTP server.

  • Attribute:

    • sender: Sender address that was refused

Example:

try:
    smtp = smtplib.SMTP('smtp.example.com', 587)
    smtp.sendmail('sender@example.com', 'recipient@example.com', 'Message')
except SMTPSenderRefused as e:
    print(e.smtp_error)  # Output: Sender address rejected: sender@example.com

5. SMTPRecipientsRefused

  • Raised when all recipient addresses are refused by the SMTP server.

  • Attribute:

    • recipients: Dictionary of recipient addresses and error messages

Example:

try:
    smtp = smtplib.SMTP('smtp.example.com', 587)
    smtp.sendmail('sender@example.com', ['recipient1@example.com', 'recipient2@example.com'], 'Message')
except SMTPRecipientsRefused as e:
    print(e.smtp_error)  # Output: All recipient addresses rejected: recipient1@example.com, recipient2@example.com

6. SMTPDataError

  • Raised when the SMTP server refuses to accept the message data.

  • Indicates a problem with the message body or its formatting.

7. SMTPConnectError

  • Raised when an error occurs during the establishment of a connection with the SMTP server.

  • Causes may include network issues or incorrect server settings.

8. SMTPHeloError

  • Raised when the server refuses the HELO (hostname identification) message sent by the SMTP client.

  • Indicates a problem with the client's hostname or its configuration.

9. SMTPNotSupportedError

  • Raised when the SMTP server does not support a requested command or option.

  • Useful for handling optional or experimental features that might not be supported by all servers.

10. SMTPAuthenticationError

  • Raised when SMTP authentication fails.

  • Indicates incorrect username or password or authentication method not supported by the server.

Real-World Applications

  • Email Sending: SMTP exceptions help handle errors that can occur during the process of sending emails, ensuring that messages are sent and received successfully.

  • Error Handling: SMTP exceptions provide specific information about errors, allowing for customized error messages and appropriate responses to different types of exceptions.

  • Debugging: By catching and inspecting SMTP exceptions, developers can identify and resolve issues with SMTP configurations, server responses, or message formats.

  • Robust SMTP Clients: SMTP exceptions enable the creation of robust SMTP clients that gracefully handle various error scenarios, minimizing service disruptions and improving user experience.


Simple Mail Transfer Protocol (SMTP)

SMTP is a protocol used to send email messages over the internet. smtplib is a Python module that provides an interface to the SMTP protocol. It allows you to send email messages from your Python programs.

Installing smtplib

pip install smtplib

Using smtplib

To use smtplib, you first need to create an SMTP object. This object represents a connection to an SMTP server. You can then use the SMTP object to send email messages.

import smtplib

# Create an SMTP object
smtp = smtplib.SMTP('smtp.gmail.com', 587)

# Start TLS encryption
smtp.starttls()

# Login to the SMTP server
smtp.login('username@gmail.com', 'password')

# Send an email message
smtp.sendmail('username@gmail.com', 'recipient@example.com', 'Subject: This is an email from Python\n\nThis is the body of the email.')

# Quit the SMTP server
smtp.quit()

SMTP Service Extensions (ESMT)

ESMT is an extension to the SMTP protocol that allows for additional functionality, such as sending email messages with attachments. smtplib supports ESMT by providing a number of methods that can be used to send extended SMTP commands.

# Send an email message with an attachment
smtp.sendmail('username@gmail.com', 'recipient@example.com', 'Subject: This is an email from Python with an attachment\n\nThis is the body of the email.', attachments=['attachment.txt'])

Potential Applications

  • Sending email notifications. smtplib can be used to send email notifications when certain events occur in your application. For example, you could send an email notification when a new user registers for your website or when a new order is placed.

  • Sending marketing emails. smtplib can be used to send marketing emails to your customers. You can use smtplib to create personalized emails that target specific users.

  • Sending transactional emails. smtplib can be used to send transactional emails, such as order confirmations and invoices. Transactional emails are typically sent automatically in response to a user's action.


SMTP Objects

Description: SMTP objects represent connections to SMTP servers for sending emails.

Methods:

1. sendmail(from_addr, to_addrs, msg, mail_options=[], rcpt_options=[])

  • from_addr: Sender's email address.

  • to_addrs: List of recipient email addresses.

  • msg: Email message as a string or MIME object.

  • mail_options: Optional list of ESMTP options for the MAIL command.

  • rcpt_options: Optional list of ESMTP options for the RCPT command.

Example:

import smtplib

# Sender's email address
from_addr = 'sender@example.com'

# List of recipient email addresses
to_addrs = ['recipient1@example.com', 'recipient2@example.com']

# Email message as a string
msg = "This is a test email."

# Establish SMTP connection
with smtplib.SMTP('smtp.example.com', 587) as server:
    # Send email
    server.sendmail(from_addr, to_addrs, msg)

2. send_message(msg, mail_options=[], rcpt_options=[])

  • msg: Email message as a MIME object.

  • mail_options: Optional list of ESMTP options for the MAIL command.

  • rcpt_options: Optional list of ESMTP options for the RCPT command.

Example:

import smtplib
from email.mime.text import MIMEText

# Create MIME text message
msg = MIMEText("This is a test email.")

# Establish SMTP connection
with smtplib.SMTP('smtp.example.com', 587) as server:
    # Send email
    server.send_message(msg)

3. set_debuglevel(level)

  • level: Debugging level (0 for no debugging, 1 for basic debugging).

Application in Real World:

SMTP objects are used to send emails from your application or script to recipients outside your email system (e.g., sending notifications, automated emails). For example:

  • Notifying users of account updates or order confirmations.

  • Sending automated newsletters or promotional messages.

  • Integrating with email marketing platforms for bulk email campaigns.


SMTP.set_debuglevel() Method

The SMTP.set_debuglevel() method in the smtplib module sets the level of debugging output.

Parameters:

  • level: An integer or boolean value specifying the debug output level:

    • 0 or False: No debugging output

    • 1 or True: Debug output for connection and messages

    • 2: Timestamped debug output for connection and messages

Simplified Explanation:

This method allows you to control how much debugging information is displayed during SMTP communication. Higher values result in more detailed debugging output.

Code Snippet:

import smtplib

smtp_server = "smtp.example.com"
smtp_port = 587

smtp_client = smtplib.SMTP(smtp_server, smtp_port)
smtp_client.set_debuglevel(2)  # Enable timestamped debugging output

# Send an email
sender = "sender@example.com"
recipient = "recipient@example.com"
message = "Hello, world!"

smtp_client.sendmail(sender, recipient, message)

Real-World Applications:

  • Troubleshooting SMTP communication: Debugging output can help identify problems with connecting to the SMTP server or sending emails.

  • Optimizing SMTP communication: By monitoring the timestamps in debug output, you can assess the performance of your SMTP connection and identify potential bottlenecks.

  • Debugging custom SMTP clients: Developers can use debugging output to understand how their custom SMTP clients interact with SMTP servers.

Complete Implementation:

The following complete code implementation sends an email using the SMTP.set_debuglevel() method to enable timestamped debugging output:

import smtplib

smtp_server = "smtp.example.com"
smtp_port = 587

smtp_client = smtplib.SMTP(smtp_server, smtp_port)
smtp_client.set_debuglevel(2)  # Enable timestamped debugging output

# Send an email
sender = "sender@example.com"
recipient = "recipient@example.com"
message = "Hello, world!"

try:
    smtp_client.sendmail(sender, recipient, message)
    print("Email sent successfully.")
except smtplib.SMTPException as e:
    print("Error sending email:", e)

smtp_client.quit()

This code sends the email and prints any debugging output to the console, including timestamps, socket I/O operations, and SMTP commands and responses.


Simplified Explanation:

The docmd() method in Python's smtplib module allows you to send custom commands to an SMTP server. These commands are used for advanced operations or debugging purposes.

Topics:

  • Command: The custom command you want to send to the server.

  • Arguments: Optional arguments to pass to the command.

  • Response: A 2-tuple containing:

    • Response code (numeric)

    • Response line (text)

Real-World Applications:

  • Custom SMTP Extensions: Some SMTP servers support private extensions that can be accessed through the docmd() method.

  • Debugging: You can use docmd() to troubleshoot issues or gather information about the SMTP server's capabilities.

Example:

import smtplib

# Create an SMTP connection
smtp = smtplib.SMTP('smtp.example.com', 587)
smtp.ehlo()

# Send a custom command to get a list of extensions
response = smtp.docmd('EXPN')
code, line = response

# Print the response code and line
print(code, line)

# Close the connection
smtp.quit()

Improved Example:

The previous example simply prints the response code and line. A more useful implementation would parse the response line to extract the actual extension list:

import smtplib

def get_extensions(smtp):
    """Get a list of SMTP extensions supported by the server.

    Args:
        smtp (smtplib.SMTP): An SMTP connection.

    Returns:
        list: A list of extension names.
    """
    response = smtp.docmd('EXPN')
    code, line = response

    if code != 250:
        raise SMTPException('Failed to get extensions: {}'.format(line))

    # Parse the response line to extract the extension list
    extensions = line.split(' ')[1:]

    return extensions

This improved example encapsulates the extension retrieval process in a function, making it reusable and easier to incorporate into larger applications.


Simplified Explanation

The SMTP.connect method establishes a connection to an email server. It takes two optional parameters: host and port. The host parameter specifies the address of the email server, and the port parameter specifies the port number. If no port number is specified, the default port number for SMTP is 25.

Detailed Explanation

Parameters

  • host (str): The address of the email server. This can be an IP address or a domain name.

  • port (int): The port number to connect to. The default port number for SMTP is 25.

Return Value

The SMTP.connect method returns a 2-tuple of the response code and the message sent by the server in its connection response. The response code is a three-digit number that indicates the status of the connection. The following are some common response codes:

  • 220: Service ready

  • 250: OK

  • 421: Service not available

  • 550: Requested action not taken: mailbox unavailable

The message sent by the server in its connection response is a text string that provides additional information about the connection.

Code Snippet

The following code snippet shows how to connect to an email server using the SMTP.connect method:

import smtplib

# Create an SMTP object
smtp = smtplib.SMTP()

# Connect to the email server
smtp.connect(host="mail.example.com", port=25)

Real-World Example

The SMTP.connect method is used to establish a connection to an email server before sending an email. For example, the following code snippet shows how to send an email using the SMTP.connect method:

import smtplib

# Create an SMTP object
smtp = smtplib.SMTP()

# Connect to the email server
smtp.connect(host="mail.example.com", port=25)

# Send the email
smtp.sendmail(from_addr="sender@example.com", to_addrs=["recipient@example.com"], msg="Hello, world!")

# Quit the SMTP session
smtp.quit()

Potential Applications

The SMTP.connect method can be used in a variety of real-world applications, including:

  • Sending emails from a web application

  • Sending emails from a command-line script

  • Sending emails from a desktop application


SMTP.helo() Method in smtplib Module

Simplifying the Explanation:

The SMTP.helo() method allows you to send a "HELO" command to an SMTP server to introduce yourself and identify the sending host.

Details:

Purpose:

  • Identifies the sending host and initiates the email sending process.

Parameters:

  • name (optional): The Fully Qualified Domain Name (FQDN) of the sending host. Defaults to the local host's FQDN.

Returns:

  • The message returned by the SMTP server after processing the "HELO" command.

Usage:

Typically, you don't need to call SMTP.helo() explicitly as smtplib handles it for you when you send an email. However, in certain scenarios, you may need to use it, such as when you want to:

  • Connect to an SMTP server using a non-default hostname.

  • Custom-implement email sending or debug the SMTP connection.

Example:

import smtplib

# Create an SMTP object
smtp = smtplib.SMTP('mail.example.com', 587)

# Send the HELO command using a custom hostname
hostname = 'my-custom-host'
smtp.helo(hostname)

# Continue with email sending operations

Real-World Applications:

  • Custom Email Sending: Implementing email sending from scratch or integrating it with custom applications.

  • Debugging: Diagnosing issues with the SMTP connection by manually sending HELO commands and analyzing the server responses.

  • Advanced SMTP Operations: Controlling the hostname of the sending server for specific purposes or troubleshooting.

Additional Notes:

  • The HELO command is a basic SMTP greeting command that informs the server about the client's identity.

  • The server's response typically includes a greeting and the hostname of the server.

  • In modern SMTP implementations, the HELO command is sometimes replaced by the EHLO command, which supports extended capabilities.


SMTP.ehlo() method in python's smtplib module is used to identify an SMTP server and check if it supports ESMTP (Extended SMTP).

Parameters:

  • name: (optional) The hostname to use in the EHLO command. Defaults to the fully qualified domain name of the local host.

Returns:

  • None. This method sets several informational attributes on the SMTP object:

    • ehlo_resp: The message returned by the server.

    • does_esmtp: True if the server supports ESMTP, False otherwise.

    • esmtp_features: A dictionary containing the names of the SMTP service extensions supported by the server and their parameters.

Usage:

When you connect to an SMTP server using the SMTP class, the ehlo() method is called implicitly. However, you may want to call it explicitly to check for specific SMTP service extensions before sending mail.

Here's an example:

import smtplib

# Create an SMTP object
smtp = smtplib.SMTP('smtp.example.com')

# Send the EHLO command
smtp.ehlo()

# Check if the server supports the STARTTLS extension
if smtp.has_extn('STARTTLS'):
    # Start TLS encryption
    smtp.starttls()

# Send the mail
smtp.sendmail(...)

# Quit the SMTP session
smtp.quit()

Real-world applications:

The ehlo() method is useful in the following situations:

  • Checking if a server supports specific SMTP service extensions, such as STARTTLS or AUTH.

  • Identifying the capabilities of a server before sending mail.

  • Troubleshooting SMTP connection issues.

Code snippet:

Here's a complete code snippet that demonstrates the ehlo() method:

import smtplib

# Create an SMTP object and connect to the server
smtp = smtplib.SMTP('smtp.example.com')

# Send the EHLO command
smtp.ehlo()

# Print the EHLO response
print(smtp.ehlo_resp)

# Print whether the server supports ESMTP
print(smtp.does_esmtp)

# Print the supported SMTP service extensions
print(smtp.esmtp_features)

# Quit the SMTP session
smtp.quit()

Output:

250-smtp.example.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH LOGIN
250 OK
True
{'PIPELINING': None, 'SIZE': '10240000', 'VRFY': None, 'ETRN': None, 'STARTTLS': None, 'AUTH': {'mechanism': 'LOGIN'}}

SMTP.ehlo_or_helo_if_needed() method

Simplified Explanation:

This method ensures that an "EHLO" or "HELO" command is sent to the SMTP server before performing any other operations. These commands establish a session with the server and determine the supported features.

Details:

  • SMTP (Simple Mail Transfer Protocol) is used to send emails over a network.

  • The "EHLO" command is newer and more advanced than "HELO".

  • "EHLO" provides more information about the server's capabilities, such as supported extensions.

  • The method first attempts to send an "EHLO" command. If the server doesn't support it, it falls back to the older "HELO" command.

  • An "SMTPHeloError" is raised if the server doesn't respond properly to either command.

Code Snippet:

import smtplib

smtp = smtplib.SMTP('smtp.example.com', 587)
smtp.ehlo_or_helo_if_needed()

Real-World Application:

This method is commonly used in email client libraries and other applications that send emails via SMTP. It ensures a reliable connection to the SMTP server and allows the client to negotiate the appropriate feature set.

Additional Notes:

  • The port number specified in the code snippet (587) is the default TLS port for SMTP connections.

  • For secure email sending, it's recommended to use an encrypted connection established via TLS or SSL.

  • The "EHLO" command is preferred over "HELO" as it provides more detailed information about the server's capabilities.


SMTP.has_extn(name)

Purpose: Checks if the SMTP server supports a specific service extension.

Simplified Explanation:

SMTP servers can offer additional functionality through service extensions. This method checks if the server supports a particular extension by name.

Usage:

import smtplib

smtp = smtplib.SMTP('example.com', 25)
smtp.ehlo()
if smtp.has_extn('STARTTLS'):
    smtp.starttls()

In this example, we first establish a connection to the SMTP server and send an EHLO command to request its capabilities. Then, we check if the server supports the STARTTLS extension, which allows for secure communication. If it does, we can enable TLS encryption.

Real-World Applications:

  • Checking if a server supports authentication mechanisms (e.g., PLAIN, XOAUTH2)

  • Enabling encryption protocols (e.g., TLS) for secure email communication

  • Utilizing server-specific features for improved email delivery or handling

Improved Code Snippets:

  • Check multiple extensions simultaneously:

extensions = ['STARTTLS', 'PIPELINING', 'CHUNKING']
for ext in extensions:
    if smtp.has_extn(ext):
        print(f'{ext} extension supported')
  • Use a case-insensitive comparison:

extension = 'STARTTLS'
if smtp.has_extn(extension.lower()):
    smtp.starttls()

SMTP.verify() method in smtplib module

The SMTP.verify() method in smtplib module checks the validity of an email address on a given SMTP server using the SMTP VRFY command. It returns a tuple containing the SMTP response code and the full email address, including the human name, if the address is valid. Otherwise, it returns an SMTP error code of 400 or greater and an error string.

Syntax:

def SMTP.verify(address)

Parameters:

  • address: The email address to verify.

Returns:

  • A tuple containing the SMTP response code and the full email address.

Example:

import smtplib

smtp_server = 'smtp.example.com'
smtp_port = 587

smtp = smtplib.SMTP(smtp_server, smtp_port)
smtp.ehlo()
smtp.starttls()
smtp.login('username', 'password')

response, email = smtp.verify('user@example.com')

if response == 250:
    print('Email address is valid.')
else:
    print('Email address is invalid.')

Real-World Applications:

  • Verifying email addresses before sending emails to avoid sending emails to invalid addresses.

  • Checking if an email address exists on a particular SMTP server.

  • Implementing email address autocompletion features.

Potential Applications:

  • Email marketing: Verifying email addresses before sending marketing emails to improve deliverability and avoid bouncing.

  • Customer support: Checking if an email address provided by a customer is valid before responding to their inquiries.

  • Social networking: Validating email addresses during user registration to prevent spam and improve security.


SMTP.login() Method in Python's smtplib Module

Purpose:

The SMTP.login() method allows you to authenticate with an SMTP server that requires a username and password.

Syntax:

SMTP.login(user, password, *, initial_response_ok=True)

Parameters:

  • user: Your SMTP username.

  • password: Your SMTP password.

  • initial_response_ok (optional, default True): Specifies whether to send an initial response with the AUTH command.

Exceptions:

The following exceptions may be raised:

  • SMTPHeloError: The server didn't respond properly to the initial greeting.

  • SMTPAuthenticationError: The server didn't accept the username/password combination.

  • SMTPNotSupportedError: The AUTH command is not supported by the server.

  • SMTPException: No supported authentication method was found.

Working:

  1. The method first tries ESMTP EHLO if it hasn't been sent before.

  2. It then tries supported authentication methods in order.

  3. If the authentication is successful, the method returns normally. Otherwise, an exception is raised.

Real-World Examples:

Example 1: Logging into a Gmail SMTP Server

import smtplib

# Create an SMTP object
smtp = smtplib.SMTP("smtp.gmail.com", 587)

# Start TLS encryption
smtp.starttls()

# Login
smtp.login("your_username@gmail.com", "your_password")

Potential Applications:

  • Sending emails from scripts or applications that require authentication.

  • Integrating with email services like Gmail or Microsoft Outlook for automated email tasks.

Additional Tips:

  • If your server supports it, set initial_response_ok to False to improve security by preventing initial response leaks.

  • Always use TLS/SSL encryption when logging into SMTP servers to protect your credentials.

  • Consider using OAuth2 authentication for more secure and convenient login.


Method Signature

SMTP.auth(mechanism, authobject, *, initial_response_ok=True)

Parameters

  • mechanism: Authentication mechanism to use, such as 'LOGIN' or 'PLAIN'.

  • authobject: A callable object that handles the challenge-response authentication.

  • initial_response_ok: If True, the authobject is called first without a challenge to provide an initial response. Defaults to True.

Functionality

The SMTP.auth() method initiates the authentication process with an SMTP server using the specified mechanism and a callable object (authobject) that processes the server's challenge-response.

Initial Response

If initial_response_ok is True, the authobject is initially called without a challenge. It can return an initial response string (in ASCII format) that will be encoded and sent with the AUTH command. This response is typically used for mechanisms like CRAM-MD5 that require an initial client challenge. If initial_response_ok is False or the authobject does not support initial responses, this step is skipped.

Challenge-Response

After the initial response (if any), the server sends a challenge response to the client. The authobject is called with this challenge as an argument (a bytes object). It should return an ASCII string data that will be base64 encoded and sent to the server.

Authobject

The authobject must implement a callable that takes a single optional argument:

data = authobject(challenge=None)
  • If challenge is None, the authobject should provide an initial response (if supported).

  • If challenge is not None, it contains the server's challenge response and the authobject should process it and return the corresponding response string.

Real-World Example

A simple example of using the SMTP.auth() method to authenticate with a PLAIN mechanism:

import smtplib

# Create an SMTP object
smtp = smtplib.SMTP('smtp.example.com', 587)

# Start TLS encryption
smtp.starttls()

# Authenticate using PLAIN mechanism
def plain_auth(challenge=None):
    # Return an initial response (not needed for PLAIN)
    if challenge is None:
        return None
    # Process challenge and return response
    username, password = challenge.decode('ascii').split()
    response = '\0' + username + '\0' + password
    return response.encode('ascii')

smtp.auth('PLAIN', plain_auth)

Applications

The SMTP.auth() method is used to authenticate with SMTP servers that require authentication, allowing applications to send emails securely. Common applications include:

  • Sending emails from a local application

  • Integrating email functionality into web applications

  • Automating email notifications or reminders


SMTP Authentication in Python's smtplib Module

Introduction

The smtplib module in Python provides a way to send emails over the Simple Mail Transfer Protocol (SMTP). It also allows for authentication, which is required by most email servers to prevent unauthorized access.

Authentication Objects

The smtplib module provides three authentication objects for the following mechanisms:

  • SMTP.auth_cram_md5: Uses the CRAM-MD5 mechanism, which is based on a challenge-response system.

  • SMTP.auth_plain: Uses the PLAIN mechanism, which sends the username and password in plaintext.

  • SMTP.auth_login: Uses the LOGIN mechanism, which prompts the server for a username and password.

Setting Authentication Parameters

These authentication objects require the user and password properties of the SMTP instance to be set appropriately.

import smtplib

smtp = smtplib.SMTP('smtp.example.com', 587)  # Use SSL/TLS port 587
smtp.user = 'myusername'
smtp.password = 'mypassword'

login() Method

User code typically doesn't call the auth method directly. Instead, they use the login() method, which tries each of the three authentication mechanisms in sequence.

smtp.login()  # Attempts CRAM-MD5, PLAIN, and LOGIN in that order

Custom Authentication

If you need to implement a custom authentication method, you can use the auth method directly.

import smtplib

def my_auth(smtp):
    # Implement your custom authentication logic here

smtp = smtplib.SMTP('smtp.example.com', 587)
smtp.auth = my_auth
smtp.login()  # Calls my_auth() to perform authentication

Real-World Applications

SMTP authentication is essential for securing email communication. It prevents unauthorized users from sending emails from your domain, which can damage your reputation or result in phishing attacks.

Here are some potential applications:

  • Sending emails from a business domain: Use SMTP authentication to ensure that only authorized employees can send emails from your company's domain.

  • Setting up email forwarding: Use SMTP authentication to configure email forwarding from one account to another, preventing unauthorized access to sensitive emails.

  • Preventing spam and phishing: Implement custom authentication mechanisms to mitigate spam and phishing attacks by identifying and blocking unauthorized senders.


SMTP.starttls() Method

The SMTP.starttls() method in Python's smtplib module enables Transport Layer Security (TLS) encryption for an SMTP connection. All subsequent SMTP commands will be sent and received securely.

Syntax

SMTP.starttls(*, context=None)

Parameters

  • context (optional): An optional ssl.SSLContext object to use for TLS configuration. If provided, the keyfile and certfile parameters should be None.

Exception

  • SMTPHeloError: Raised if the server does not respond properly to the HELO greeting.

  • SMTPNotSupportedError: Raised if the server does not support the STARTTLS extension.

  • RuntimeError: Raised if SSL/TLS support is not available in the Python interpreter.

How to Use

Once you have connected to an SMTP server using SMTP.connect(), you can call SMTP.starttls() to enable TLS encryption. This should be followed by another EHLO command to re-establish the SMTP session in TLS mode:

import smtplib

smtp = smtplib.SMTP('smtp.example.com', 587)
smtp.starttls()
smtp.ehlo()

# Send an encrypted email message
smtp.sendmail('sender@example.com', 'recipient@example.com', 'Hello, world!')

Real-World Applications

TLS encryption for SMTP is essential for securing email communications, especially when transmitting sensitive information. It protects against eavesdropping and tampering during email transmission.

Alternatives

An alternative to using SMTP.starttls() is to establish a secure connection using SMTP_SSL. This method creates a new socket secured with TLS before initiating the SMTP session:

import smtplib

smtp = smtplib.SMTP_SSL('smtp.example.com', 465)

# Send an encrypted email message
smtp.sendmail('sender@example.com', 'recipient@example.com', 'Hello, world!')

SMTP.sendmail() Method in Python's smtplib Module

The SMTP.sendmail() method in Python's smtplib module provides a convenient way to send an email message. It handles the process of connecting to an SMTP server, constructing the email envelope, and sending the message data.

Parameters:

  • from_addr: The email address of the sender.

  • to_addrs: A list of email addresses of the recipients.

  • msg: The message to be sent. Can be a string containing ASCII characters or a byte string.

  • mail_options (optional): A list of ESMTP options to be used in the MAIL FROM command.

  • rcpt_options (optional): A list of ESMTP options to be used with all RCPT commands.

Process:

The sendmail() method follows these steps:

  1. Connects to an SMTP server using the hostname and port specified in the SMTP object's constructor.

  2. Constructs the email envelope, which includes the sender's address, recipient addresses, and message headers.

  3. Sends the MAIL FROM command with the sender's address and any specified mail_options.

  4. Sends the RCPT TO command for each recipient address in to_addrs, with any specified rcpt_options.

  5. Sends the DATA command and the message data.

  6. Closes the connection to the SMTP server.

Note:

  • The from_addr and to_addrs parameters are used to create the email envelope and do not affect the message headers.

  • If msg is a string, it is encoded using the ASCII codec, and lone and characters are converted to \r.

  • If msg is a byte string, it is sent without any modifications.

Real-World Example:

import smtplib

# Create an SMTP object and connect to a server
smtp_server = 'smtp.example.com'
smtp_port = 587
smtp_object = smtplib.SMTP(smtp_server, smtp_port)

# Start TLS encryption
smtp_object.starttls()

# Log in to the server
smtp_object.login('user@example.com', 'password')

# Send an email
from_addr = 'user@example.com'
to_addrs = ['recipient1@example.com', 'recipient2@example.com']
msg = 'Hello, world!'
smtp_object.sendmail(from_addr, to_addrs, msg)

# Quit the SMTP server
smtp_object.quit()

Potential Applications:

  • Sending notifications and alerts

  • Sending email campaigns and newsletters

  • Automating email communication in various applications


What is the EHLO/HELO command?

In the SMTP protocol, the EHLO/HELO command is used to establish communication between an email client and a mail server. It allows the client to identify itself and ask the server about its capabilities.

SMTP (Simple Mail Transfer Protocol)

  • SMTP is the protocol for sending emails over the internet.

  • It is a client-server protocol, where the client (e.g. your email software) connects to the server (e.g. your email provider's mail server) and sends the email.

  • The server then tries to deliver the email to the recipient's email address.

Enhanced SMTP (ESMTP)

  • ESMTP is an extended version of SMTP that supports additional features, such as:

    • Larger email sizes

    • Authentication

    • Encryption

The EHLO/HELO command

The EHLO/HELO command is used by the client to identify itself to the server and to ask which ESMTP features the server supports.

  • If the server supports ESMTP, the client will send the EHLO command.

  • If the server does not support ESMTP, the client will send the HELO command.

The syntax of the EHLO/HELO command is:

EHLO/HELO hostname

where hostname is the name of the client.

For Example:

import smtplib

server = smtplib.SMTP("smtp.example.com", 587)
server.ehlo()

The above code will send the EHLO command to the server smtp.example.com on port 587.

Potential applications:

The EHLO/HELO command is used in a variety of applications, including:

  • Sending emails

  • Receiving emails

  • Managing email accounts

  • Email security

Real-world example:

The following code shows how to use the EHLO/HELO command to send an email:

import smtplib

server = smtplib.SMTP("smtp.example.com", 587)
server.ehlo()
server.starttls()
server.login("username", "password")
server.sendmail("from@example.com", "to@example.com", "Hello, world!")
server.quit()

This code will send the email "Hello, world!" from the sender from@example.com to the recipient to@example.com.


Exceptions in smtplib

SMTPRecipientsRefused

This exception is raised when all the recipients of an email are refused by the server. The exception object has a recipients attribute that contains a dictionary with information about the refused recipients.

Example:

import smtplib

# Create an SMTP object
smtp = smtplib.SMTP('smtp.example.com', 587)

# Send an email
try:
    smtp.sendmail('sender@example.com', ['recipient1@example.com', 'recipient2@example.com'], 'Hello, world!')
except smtplib.SMTPRecipientsRefused as e:
    print("All recipients were refused:", e.recipients)

SMTPHeloError

This exception is raised when the server does not reply properly to the HELO greeting.

Example:

import smtplib

# Create an SMTP object
smtp = smtplib.SMTP('smtp.example.com', 587)

try:
    # Send the HELO greeting
    smtp.helo('example.com')
except smtplib.SMTPHeloError as e:
    print("The server did not reply properly to the HELO greeting:", e)

SMTPSenderRefused

This exception is raised when the server does not accept the sender address.

Example:

import smtplib

# Create an SMTP object
smtp = smtplib.SMTP('smtp.example.com', 587)

try:
    # Send the MAIL FROM command
    smtp.mail('sender@example.com')
except smtplib.SMTPSenderRefused as e:
    print("The server did not accept the sender address:", e)

SMTPDataError

This exception is raised when the server replies with an unexpected error code (other than a refusal of a recipient).

Example:

import smtplib

# Create an SMTP object
smtp = smtplib.SMTP('smtp.example.com', 587)

try:
    # Send the DATA command
    smtp.data('Hello, world!')
except smtplib.SMTPDataError as e:
    print("The server replied with an unexpected error code:", e)

SMTPNotSupportedError

This exception is raised when the SMTPUTF8 option is specified, but the server does not support it.

Example:

import smtplib

# Create an SMTP object
smtp = smtplib.SMTP('smtp.example.com', 587)

try:
    # Send the MAIL FROM command with the SMTPUTF8 option
    smtp.mail('sender@example.com', [], mail_options=['SMTPUTF8'])
except smtplib.SMTPNotSupportedError as e:
    print("The server does not support the SMTPUTF8 option:", e)

Real-world applications:

  • SMTPRecipientsRefused: This exception can be useful for handling cases where an email cannot be delivered to any of the intended recipients. For example, you could use this exception to send an error message to the sender of the email.

  • SMTPHeloError: This exception can be useful for handling cases where the server is not responding properly to the HELO greeting. For example, you could use this exception to try connecting to a different SMTP server.

  • SMTPSenderRefused: This exception can be useful for handling cases where the server does not accept the sender address. For example, you could use this exception to check if the sender address is valid before sending an email.

  • SMTPDataError: This exception can be useful for handling cases where the server replies with an unexpected error code. For example, you could use this exception to retry sending the email.

  • SMTPNotSupportedError: This exception can be useful for handling cases where the server does not support the SMTPUTF8 option. For example, you could use this exception to fall back to using a different encoding for the email.


Simplified Explanation:

The SMTP.send_message() method in Python's smtplib module allows you to send an email message represented by an email.message.Message object.

Specific Topics:

1. send_message() Method:

  • Purpose: Send an email message using an email.message.Message object as the message representation.

  • Arguments:

    • msg: An email.message.Message object representing the email message.

    • from_addr (optional): The sender's email address. Defaults to the Sender or From header in the msg object.

    • to_addrs (optional): A list of recipient email addresses. Defaults to the combined addresses from the To, Cc, and Bcc headers in the msg object.

    • mail_options (optional): A list of additional mail options to include.

    • rcpt_options (optional): A list of additional recipient options to include.

2. Message Addressing:

  • By default, send_message() extracts the sender's address from the Sender or From header in the msg object.

  • If the Resent-* headers are present, they are used instead of the regular headers.

3. Message Handling:

  • If the message contains more than one set of Resent-* headers, a ValueError is raised.

4. Applications:

SMTP.send_message() is used in various real-world applications, such as:

  • Sending email notifications

  • Automated email campaigns

  • Email confirmation after user registration

  • Email support systems

Example:

import smtplib
from email.message import EmailMessage

# Create an email message
msg = EmailMessage()
msg['Subject'] = 'Hello from Python'
msg['From'] = 'sender@example.com'
msg['To'] = 'recipient@example.com'
msg.set_content('This is a test email.')

# Create an SMTP connection
smtp_server = 'smtp.example.com'
smtp_port = 587
smtp = smtplib.SMTP(smtp_server, smtp_port)

# Send the message
smtp.send_message(msg)

# Close the connection
smtp.quit()

In this example, an email message is created using the EmailMessage class. The send_message() method on the smtplib.SMTP object is then used to send the message. The sender and recipient addresses are obtained from the From and To headers in the msg object, respectively.


Simplified Explanation of smtplib.send_message() Method:

Purpose: The send_message method in the smtplib module sends an email message to specified recipients.

Parameters:

  • msg: An email message object (an instance of the email.message.Message class).

  • from_addr: The sender's email address (optional).

  • to_addrs: A list of recipient email addresses (optional).

Customization:

  • The message is serialized using email.generator.BytesGenerator with line breaks ().

  • The method calls the sendmail function to transmit the message.

  • The from_addr and to_addrs can be omitted, and the values specified in the email message's headers will be used.

BCC/Resent-BCC Headers:

  • send_message ignores any Bcc or Resent-Bcc headers in the message.

SMTPUTF8 and BODY=8BITMIME Options:

  • If the server supports SMTPUTF8 (for internationalized addresses) and BODY=8BITMIME (for non-ASCII characters), the EmailPolicy of the message is cloned with utf8 set to True, and these options are added to the message.

Real-World Example:

import smtplib
from email.message import EmailMessage

# Create an email message
msg = EmailMessage()
msg['Subject'] = 'Hello from Python'
msg['From'] = 'sender@example.com'
msg['To'] = 'recipient@example.com'
msg.set_content('This is a test email.')

# Connect to the SMTP server
smtp_server = 'smtp.example.com'
smtp_port = 587
smtp = smtplib.SMTP(smtp_server, smtp_port)

# Send the email
smtp.sendmail(msg['From'], msg['To'], msg.as_bytes())

# Disconnect from the SMTP server
smtp.quit()

Potential Applications:

  • Sending email notifications

  • Automated email campaigns

  • Email confirmation and verification

  • Password reset emails

  • Customer support and feedback collection


SMTP.quit() Method

Purpose: Terminates the SMTP session and closes the connection with the server.

Syntax:

SMTP.quit()

Return Value:

Returns the result of the SMTP QUIT command.

Example:

import smtplib

# Create an SMTP connection
smtp_server = 'smtp.example.com'
smtp_port = 587
smtp = smtplib.SMTP(smtp_server, smtp_port)

# Send an email
smtp.sendmail('sender@example.com', 'recipient@example.com', 'Subject: Test Email')

# Terminate the SMTP session
smtp.quit()

Low-Level SMTP Commands

In addition to high-level methods like sendmail, smtplib also supports low-level methods corresponding to specific SMTP commands:

  • HELP: Requests help information from the server.

  • RSET: Resets the session to its initial state.

  • NOOP: Does nothing, but can be used to check if the server is responsive.

  • MAIL: Initiates a mail transaction by specifying the sender's email address.

  • RCPT: Adds a recipient to the mail transaction.

  • DATA: Starts the data input phase, where the actual email message is sent.

Usage of Low-Level SMTP Commands

These commands are typically used for advanced scenarios, such as:

  • Handling non-standard SMTP responses.

  • Debugging SMTP interactions.

  • Implementing custom email sending mechanisms.

Example Using Low-Level SMTP Commands:

import smtplib

# Create an SMTP connection
smtp_server = 'smtp.example.com'
smtp_port = 587
smtp = smtplib.SMTP(smtp_server, smtp_port)

# Send the HELO command
smtp.helo("client.example.com")

# Then, you can use low-level SMTP commands directly. For example, to send a message from `sender@example.com` to `recipient@example.com`:

smtp.mail('sender@example.com')
smtp.rcpt('recipient@example.com')
smtp.data()
smtp.sendmail('sender@example.com', 'recipient@example.com', 'Subject: Test Email')

# Terminate the SMTP session
smtp.quit()

Potential Applications

SMTP and its low-level commands have numerous applications in real-world scenarios:

  • Email Sending: Sending emails from applications, web servers, and other automated systems.

  • SMTP Debugging: Troubleshooting email delivery issues by examining SMTP interactions.

  • Custom Email Handling: Creating custom email forwarding, filtering, or validation logic.

  • Spam Detection: Analyzing SMTP headers and message content for suspicious behavior.

  • Bulk Email Campaigns: Sending large volumes of emails efficiently.

  • Email Authentication: Implementing SMTP authentication mechanisms for secure email delivery.


SMTP Example (Simplified and Explained)

The SMTP example in Python's smtplib module demonstrates how to send an email using the Simple Mail Transfer Protocol (SMTP). It involves manually crafting an email message and sending it via an SMTP server.

Step-by-Step Explanation

1. Prompt for Sender and Recipient Information

The example begins by prompting the user for the sender's email address (fromaddr) and a list of recipient email addresses (toaddrs).

fromaddr = prompt("From: ")
toaddrs  = prompt("To: ").split()

2. Create Email Message

The user is then prompted to enter the email message content, including the email's header information. The header information specifies the sender and recipient email addresses, as well as any additional headers you may need.

msg = ("From: %s
To: %s

"
      % (fromaddr, ", ".join(toaddrs)))
while True:
    try:
        line = input()
    except EOFError:
        break
    if not line:
        break
    msg = msg + line

3. Connect to SMTP Server

To send the email, the example connects to an SMTP server. In this case, it uses the local SMTP server running on the machine where the script is executed.

server = smtplib.SMTP('localhost')

4. Set Debug Level

Setting the debug level to 1 enables debug messages to be printed to the console, helping you troubleshoot any issues with sending the email.

server.set_debuglevel(1)

5. Send Email

The sendmail() method is used to send the email message. It takes three arguments: the sender's email address, a list of recipient email addresses, and the email message.

server.sendmail(fromaddr, toaddrs, msg)

6. Quit the SMTP Session

After sending the email, the SMTP session is closed by calling the quit() method.

server.quit()

Real-World Applications

SMTP is widely used in real-world applications, including:

  • Sending emails from websites or web applications.

  • Automating email notifications in software systems.

  • Communicating with remote devices (e.g., Internet of Things devices) via email.

Improved Version and Example

Here's an improved version of the example that demonstrates sending an email with a more realistic message format and using a real SMTP server:

import smtplib
from email.message import EmailMessage

# Create the email message
msg = EmailMessage()
msg['Subject'] = 'Test Email'
msg['From'] = 'sender@example.com'
msg['To'] = 'recipient@example.com'
msg.set_content('Hello, this is a test email.')

# Send the email
with smtplib.SMTP('smtp.example.com', 587) as server:
    server.starttls()
    server.login('sender@example.com', 'password')
    server.sendmail('sender@example.com', ['recipient@example.com'], msg.as_string())