In today’s digital world, automated communication is essential for businesses, developers, and even personal projects. Python provides powerful tools to send both emails and SMS messages programmatically. In this guide, we’ll explore how to implement these features in your Python applications.
1. Sending Emails with Python <a name=”sending-emails”></a>
Python’s smtplib
module makes sending emails straightforward. Let’s explore how to use it effectively.
Setting up SMTP <a name=”smtp-setup”></a>
First, you’ll need SMTP server details. For Gmail, these are:
-
SMTP server:
smtp.gmail.com
-
Port: 587 (for TLS) or 465 (for SSL)
-
Username: Your full email address
-
Password: Your password or app password (recommended)
For security, consider using environment variables for credentials:
1 2 3 4 5 6 7 8 9 |
import os from dotenv import load_dotenv load_dotenv() EMAIL_HOST = os.getenv('EMAIL_HOST') EMAIL_PORT = os.getenv('EMAIL_PORT') EMAIL_USER = os.getenv('EMAIL_USER') EMAIL_PASS = os.getenv('EMAIL_PASS') |
Basic Email <a name=”basic-email”></a>
Here’s how to send a simple text email:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart def send_email(to_email, subject, body): # Create message container msg = MIMEMultipart() msg['From'] = EMAIL_USER msg['To'] = to_email msg['Subject'] = subject # Attach body msg.attach(MIMEText(body, 'plain')) try: # Create SMTP session with smtplib.SMTP(EMAIL_HOST, EMAIL_PORT) as server: server.starttls() # Enable TLS server.login(EMAIL_USER, EMAIL_PASS) server.send_message(msg) print("Email sent successfully!") except Exception as e: print(f"Error sending email: {e}") # Usage send_email( to_email="recipient@example.com", subject="Test Email", body="Hello, this is a test email sent from Python!" ) |
HTML Emails <a name=”html-emails”></a>
For richer content, send HTML emails:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
def send_html_email(to_email, subject, html_content): msg = MIMEMultipart() msg['From'] = EMAIL_USER msg['To'] = to_email msg['Subject'] = subject # Attach HTML content msg.attach(MIMEText(html_content, 'html')) try: with smtplib.SMTP(EMAIL_HOST, EMAIL_PORT) as server: server.starttls() server.login(EMAIL_USER, EMAIL_PASS) server.send_message(msg) print("HTML email sent successfully!") except Exception as e: print(f"Error sending HTML email: {e}") # Usage html_content = """ <html> <body> <h1>Welcome!</h1> <p>This is an <strong>HTML email</strong> sent from Python.</p> <a href="https://example.com">Visit our website</a> </body> </html> """ send_html_email( to_email="recipient@example.com", subject="HTML Email Test", html_content=html_content ) |
Email Attachments <a name=”email-attachments”></a>
To attach files to your emails:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
from email.mime.base import MIMEBase from email import encoders def send_email_with_attachment(to_email, subject, body, file_path): msg = MIMEMultipart() msg['From'] = EMAIL_USER msg['To'] = to_email msg['Subject'] = subject # Attach body msg.attach(MIMEText(body, 'plain')) # Attach file with open(file_path, 'rb') as attachment: part = MIMEBase('application', 'octet-stream') part.set_payload(attachment.read()) encoders.encode_base64(part) part.add_header( 'Content-Disposition', f'attachment; filename= {os.path.basename(file_path)}' ) msg.attach(part) try: with smtplib.SMTP(EMAIL_HOST, EMAIL_PORT) as server: server.starttls() server.login(EMAIL_USER, EMAIL_PASS) server.send_message(msg) print("Email with attachment sent successfully!") except Exception as e: print(f"Error sending email: {e}") # Usage send_email_with_attachment( to_email="recipient@example.com", subject="Report Attachment", body="Please find the attached report.", file_path="monthly_report.pdf" ) |
Multiple Recipients <a name=”multiple-recipients”></a>
To send to multiple recipients:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
def send_email_to_multiple(to_emails, subject, body): msg = MIMEMultipart() msg['From'] = EMAIL_USER msg['To'] = ", ".join(to_emails) # Comma-separated list msg['Subject'] = subject msg.attach(MIMEText(body, 'plain')) try: with smtplib.SMTP(EMAIL_HOST, EMAIL_PORT) as server: server.starttls() server.login(EMAIL_USER, EMAIL_PASS) server.send_message(msg) print("Email sent to multiple recipients successfully!") except Exception as e: print(f"Error sending email: {e}") # Usage recipients = ["user1@example.com", "user2@example.com", "user3@example.com"] send_email_to_multiple( to_emails=recipients, subject="Team Update", body="Hello team, here's our weekly update..." ) |
Multiple Recipients <a name=”multiple-recipients”></a>
To send to multiple recipients:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
def send_email_to_multiple(to_emails, subject, body): msg = MIMEMultipart() msg['From'] = EMAIL_USER msg['To'] = ", ".join(to_emails) # Comma-separated list msg['Subject'] = subject msg.attach(MIMEText(body, 'plain')) try: with smtplib.SMTP(EMAIL_HOST, EMAIL_PORT) as server: server.starttls() server.login(EMAIL_USER, EMAIL_PASS) server.send_message(msg) print("Email sent to multiple recipients successfully!") except Exception as e: print(f"Error sending email: {e}") # Usage recipients = ["user1@example.com", "user2@example.com", "user3@example.com"] send_email_to_multiple( to_emails=recipients, subject="Team Update", body="Hello team, here's our weekly update..." ) |
Email Best Practices <a name=”email-best-practices”></a>
-
Use environment variables for sensitive credentials
-
Handle exceptions properly to avoid crashes
-
Rate limit your emails to avoid being marked as spam
-
Include unsubscribe links in marketing emails
-
Test with sandbox accounts before sending to real users
-
Use email templates for consistent formatting
-
Consider using transactional email services (SendGrid, Mailgun, Amazon SES) for production
2. Sending SMS with Python <a name=”sending-sms”></a>
Sending SMS requires using an SMS gateway service. Let’s explore popular options.
Using Twilio <a name=”twilio-sms”></a>
Twilio is a popular cloud communications platform.
First, install the Twilio package:
1 |
pip install twilio |
Here’s how to send an SMS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
from twilio.rest import Client import os # Load credentials from environment TWILIO_ACCOUNT_SID = os.getenv('TWILIO_ACCOUNT_SID') TWILIO_AUTH_TOKEN = os.getenv('TWILIO_AUTH_TOKEN') TWILIO_PHONE_NUMBER = os.getenv('TWILIO_PHONE_NUMBER') def send_sms_twilio(to_number, message): try: client = Client(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN) message = client.messages.create( body=message, from_=TWILIO_PHONE_NUMBER, to=to_number ) print(f"SMS sent! Message SID: {message.sid}") return True except Exception as e: print(f"Error sending SMS: {e}") return False # Usage send_sms_twilio( to_number="+1234567890", # Format: +[country code][number] message="Hello from Twilio and Python!" ) |
Using Plivo <a name=”plivo-sms”></a>
Plivo is another SMS API provider with competitive pricing.
Install the Plivo package:
1 |
pip install plivo |
Sending an SMS with Plivo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import plivo import os PLIVO_AUTH_ID = os.getenv('PLIVO_AUTH_ID') PLIVO_AUTH_TOKEN = os.getenv('PLIVO_AUTH_TOKEN') PLIVO_PHONE_NUMBER = os.getenv('PLIVO_PHONE_NUMBER') def send_sms_plivo(to_number, message): try: client = plivo.RestClient(PLIVO_AUTH_ID, PLIVO_AUTH_TOKEN) response = client.messages.create( src=PLIVO_PHONE_NUMBER, dst=to_number, text=message ) print(f"SMS sent! Message UUID: {response.message_uuid[0]}") return True except Exception as e: print(f"Error sending SMS: {e}") return False # Usage send_sms_plivo( to_number="+1234567890", message="Hello from Plivo and Python!" ) |
Using AWS SNS <a name=”aws-sns”></a>
Amazon Simple Notification Service (SNS) can also send SMS messages.
Install boto3 (AWS SDK):
1 |
pip install boto3 |
Configure AWS credentials (usually in ~/.aws/credentials) and then:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
import boto3 import os def send_sms_aws_sns(to_number, message): try: # Create an SNS client client = boto3.client( 'sns', aws_access_key_id=os.getenv('AWS_ACCESS_KEY_ID'), aws_secret_access_key=os.getenv('AWS_SECRET_ACCESS_KEY'), region_name=os.getenv('AWS_REGION') ) # Send SMS response = client.publish( PhoneNumber=to_number, Message=message ) print(f"SMS sent! Message ID: {response['MessageId']}") return True except Exception as e: print(f"Error sending SMS: {e}") return False # Usage send_sms_aws_sns( to_number="+1234567890", message="Hello from AWS SNS and Python!" ) |
Sending SMS messages to recipients all over the world is straightforward with GatewayAPI’s robust service. If you’re looking to integrate GatewayAPI SMS services into your application by using Python code, you’re at the right place!
Let’s dive into the process step-by-step.
Getting started
GatewayAPI dashboard:
After logging into GatewayAPI.com, you’ll be presented with a dashboard. This dashboard provides a range of code examples in various languages, ensuring that you can integrate with the API no matter what your preferred language might be. Here we naturally use the Python language example, which is also included with your unique credentials.
Dependencies installation:
Before diving into the code, you’ll need to ensure your Python environment is set up correctly. The key dependency you need is the requests library. To install it, open your terminal or command prompt and run the following command:
1 |
pip install requests |
Setting up your editor:
After installing the necessary dependencies, copy the provided code example from your dashboard into your favorite code editor.
Customizing the message
Input the phone number:
Within the code, locate the placeholder to input the recipient’s phone number.
Change the Sender ID:
Modify the sender’s name from the default “ExampleSMS” to “GatewayAPI” (or any other preferred sender name).
Modify the message content:
The default message in the example says “Hello World.” You can change this to a more personalized message like “Hello Oliver, how are you?” or any other text you’d like.
Remember to change the token:
If you have copied the code below instead of the one in your dashboard, remember to replace the token in the example with your unique token. This can be found in your dashboard under API → API Keys.
The code should now look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# Install deps with: pip install requests import requests def send_sms(sender: str, msg_content: str, recipients: list[int]): token="GoGenerateAnApiToken" payload = { "sender": sender, "message": msg_content, "recipients": [ {"msisdn": recipient_number} for recipient_number in recipients ], } resp = requests.post( "https://gatewayapi.com/rest/mtsms", json=payload, auth=(token, ""), ) resp.raise_for_status() print(resp.json()) send_sms("GatewayAPI", "Hello Oliver, how are you?", [45_1234_5678]) |
Sending the SMS
Run the script:
Once you’ve made all the necessary changes, save your script and head back to your terminal. Execute your Python script, and if everything is set up correctly, the message will be sent to the specified phone number.
Message confirmation:
You’ll be able to see a message pop up on the recipient’s phone. In the tutorial example, the message “Hello Oliver, how are you?” from GatewayAPI was received.
Typical errors
- Using wrong credentials and e.g. mixing up the key with the token.
- Missing Dependencies: Forgetting to install required libraries or modules, leading to ModuleNotFoundError or ImportError.
Python – the holy grail of programming?
Three fun facts about the Python coding language:
- The name “Python” doesn’t come from the snake but from the British comedy group Monty Python. Guido van Rossum, the creator of Python, was a fan of “Monty Python’s Flying Circus,” and wanted a name that was short, unique and slightly mysterious.
- Python has its own set of guiding principles, which you can view by typing import this into a Python interpreter. This will show you “The Zen of Python,” a collection of 19 aphorisms that capture the philosophy of the Python language
- Python is one of the fastest-growing major programming languages in the world. Its simplicity and versatility, especially in data science and web development, have led to its widespread adoption in various industries.
SMS Best Practices <a name=”sms-best-practices”></a>
-
Obtain proper consent before sending SMS messages
-
Include opt-out instructions in your messages
-
Be mindful of timing – avoid sending late at night
-
Keep messages concise (SMS has character limits)
-
Handle country codes properly (always include + and country code)
-
Monitor delivery rates and adjust accordingly
-
Consider using short codes for high-volume messaging
-
Be aware of carrier restrictions and regulations
3. Conclusion <a name=”conclusion”></a>
Python provides powerful capabilities for sending both emails and SMS messages programmatically. Whether you’re building notification systems, marketing tools, or communication features for your application, Python has you covered.
Key takeaways:
-
For emails,
smtplib
is built-in but consider transactional email services for production -
For SMS, you’ll need to use a gateway service like Twilio, Plivo, or AWS SNS
-
Always follow best practices for deliverability and compliance
-
Secure your credentials properly using environment variables
-
Implement proper error handling and logging
By implementing these techniques, you can automate your communication workflows and build more engaging applications. Remember to test thoroughly and monitor your communication systems to ensure reliable delivery.