Skip to content

Instantly share code, notes, and snippets.

@turicas
Last active August 1, 2024 15:47
Show Gist options
  • Save turicas/1455741 to your computer and use it in GitHub Desktop.
Save turicas/1455741 to your computer and use it in GitHub Desktop.
Send emails easily in Python (with attachments and multipart)
#!/usr/bin/env python
# coding: utf-8
# This little project is hosted at: <https://gist.github.com/1455741>
# Copyright 2011-2020 Álvaro Justen [alvarojusten at gmail dot com]
# License: GPL <http://www.gnu.org/copyleft/gpl.html>
import os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from mimetypes import guess_type
from email.encoders import encode_base64
from getpass import getpass
from smtplib import SMTP
def get_email(email):
if '<' in email:
data = email.split('<')
email = data[1].split('>')[0].strip()
return email.strip()
class Email(object):
def __init__(self, from_, to, subject, message, message_type='plain',
attachments=None, cc=None, message_encoding='us-ascii'):
self.email = MIMEMultipart()
self.email['From'] = from_
self.email['To'] = to
self.email['Subject'] = subject
if cc is not None:
self.email['Cc'] = cc
text = MIMEText(message, message_type, message_encoding)
self.email.attach(text)
if attachments is not None:
for filename in attachments:
mimetype, encoding = guess_type(filename)
mimetype = mimetype.split('/', 1)
fp = open(filename, 'rb')
attachment = MIMEBase(mimetype[0], mimetype[1])
attachment.set_payload(fp.read())
fp.close()
encode_base64(attachment)
attachment.add_header('Content-Disposition', 'attachment',
filename=os.path.basename(filename))
self.email.attach(attachment)
def __str__(self):
return self.email.as_string()
class EmailConnection(object):
def __init__(self, server, username, password):
if ':' in server:
data = server.split(':')
self.server = data[0]
self.port = int(data[1])
else:
self.server = server
self.port = 25
self.username = username
self.password = password
self.connect()
def connect(self):
self.connection = SMTP(self.server, self.port)
self.connection.ehlo()
self.connection.starttls()
self.connection.ehlo()
self.connection.login(self.username, self.password)
def send(self, message, from_=None, to=None):
if type(message) == str:
if from_ is None or to is None:
raise ValueError('You need to specify `from_` and `to`')
else:
from_ = get_email(from_)
to = get_email(to)
else:
from_ = message.email['From']
if 'Cc' not in message.email:
message.email['Cc'] = ''
to_emails = [message.email['To']] + message.email['Cc'].split(',')
to = [get_email(complete_email) for complete_email in to_emails]
message = str(message)
return self.connection.sendmail(from_, to, message)
def close(self):
self.connection.close()
#!/usr/bin/env python
# coding: utf-8
# This script asks your name, email, password, SMTP server and destination
# name/email. It'll send an email with this script's code as attachment and
# with a plain-text message. You can also pass `message_type='html'` in
# `Email()` to send HTML emails instead of plain text.
# You need email_utils.py to run it correctly. You can get it on:
# https://gist.github.com/1455741
# Copyright 2011-2020 Álvaro Justen [alvarojusten at gmail dot com]
# License: GPL <http://www.gnu.org/copyleft/gpl.html>
import sys
from getpass import getpass
from email_utils import EmailConnection, Email
print 'I need some information...'
name = raw_input(' - Your name: ')
email = raw_input(' - Your e-mail: ')
password = getpass(' - Your password: ')
mail_server = raw_input(' - Your mail server: ')
to_email = raw_input(' - Destination email: ')
to_name = raw_input(' - Name of destination: ')
subject = 'Sending mail easily with Python'
message = 'here is the message body'
attachments = [sys.argv[0]]
print 'Connecting to server...'
server = EmailConnection(mail_server, email, password)
print 'Preparing the email...'
email = Email(from_='"%s" <%s>' % (name, email), #you can pass only email
to='"%s" <%s>' % (to_name, to_email), #you can pass only email
subject=subject, message=message, attachments=attachments)
print 'Sending...'
server.send(email)
print 'Disconnecting...'
server.close()
print 'Done!'
#!/usr/bin/env python3
# Script to send emails using Python using the command-line.
# Copyright 2020 Álvaro Justen [alvarojusten at gmail dot com]
# License: GPL <http://www.gnu.org/copyleft/gpl.html>
import argparse
import os
import smtplib
import sys
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
def send_mail(
smtp_host, smtp_port, smtp_user, smtp_pass, from_address, to_addresses,
subject, text, html=False
):
# TODO: use `emails_utils` code
message = MIMEMultipart()
message["From"] = from_address
message["To"] = ",".join(to_addresses)
message["Subject"] = subject
if html:
message.attach(MIMEText(text, "html", "utf-8"))
else:
message.attach(MIMEText(text, "plain", "utf-8"))
server = smtplib.SMTP(host=smtp_host, port=smtp_port)
server.starttls()
server.login(smtp_user, smtp_pass)
server.sendmail(from_address, to_addresses, message.as_string())
server.quit()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--html", action="store_true")
parser.add_argument("--smtp-host", default=os.environ.get("SMTP_HOST"))
parser.add_argument("--smtp-port", default=os.environ.get("SMTP_PORT", 587))
parser.add_argument("--smtp-user", default=os.environ.get("SMTP_USER"))
parser.add_argument("--smtp-pass", default=os.environ.get("SMTP_PASS"))
parser.add_argument("from_address")
parser.add_argument("to_addresses", help="If more than one, separate by comma")
parser.add_argument("subject")
parser.add_argument("message")
args = parser.parse_args()
if None in (args.smtp_host, args.smtp_port, args.smtp_user, args.smtp_pass):
print("ERROR: missing SMTP configuration", file=sys.stderr)
exit(1)
to_addresses = [
address.strip()
for address in args.to_addresses.split(",")
if address.strip()
]
send_mail(
smtp_host=args.smtp_host,
smtp_port=args.smtp_port,
smtp_user=args.smtp_user,
smtp_pass=args.smtp_pass,
from_address=args.from_address,
to_addresses=to_addresses,
subject=args.subject,
text=args.message,
html=args.html,
)
@pythonmars
Copy link

ok, i found the answer:
change line mimetype, encoding = guess_type(filename) to:
mimetype, _ = guess_type(filename)
then no more warning

@JachiOnuoha
Copy link

Great Script!! But, how can I make the program include my gmail signature for outgoing emails?

@prasathn1984
Copy link

Can anyone explain, how to attach recent backup file to send through mail by daily basis?

@prasathn1984
Copy link

I am doing backupjob of my cisco devices and it will store with today's name. I want to attach and send mail of latest files to DL. How do i write script as i am new to python. Could you help me on this?

@ayyoubmaulana
Copy link

ayyoubmaulana commented Nov 20, 2019 via email

@prasathn1984
Copy link

prasathn1984 commented Nov 20, 2019 via email

@advaybajaj
Copy link

can someone please tell me what to write when we input "mail_server"

@Sankalp004
Copy link

Sankalp004 commented Oct 28, 2020

can someone please tell me what to write when we input "mail_server"

"""
SMTP Server Links :
Gmail-> smtp.gmail.com:587
Yahoo-> smtp.mail.yahoo.com:587
Outlook -> smtp-mail.outlook.com:587
"""

@SandhyaArja
Copy link

hi, Im new to python script help to attach pdf in my code with the helpof encoders
from email.message import EmailMessage
import ssl ,smtplib
from pandas import *
df = pandas.read_csv("mail.csv")
f=df["Name"].tolist()
g=df["Pdf"].tolist()
print(g)
receiver=df["Mail"].tolist()
for f in receiver:
sender = ''
paswd = ''
subject = 'Going To Ice Cream'
body = 'Guys when we are going to have Fun'
mail= EmailMessage() #it is an object to EmailMessage CLASS
mail['From'] = sender
mail['To'] = f
mail['Subject'] = subject
mail.set_content(body)
context = ssl.create_default_context()
with smtplib.SMTP_SSL('smtp.gmail.com' , 465,context= context) as mi:
mi.login(sender,paswd)
mi.sendmail(sender,f,mail.as_string())
print(f'mail sent successfully to {f} please check your email inbox')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment