Home > Enterprise >  Sending E-Mail to various recipients with Python
Sending E-Mail to various recipients with Python

Time:01-22

I want to send an email to various recipients (like 10 people) with the given table in the code, but the mail only reaches the first mail address. Is there a way to code it the way, that I can send an email to various recipients?

df = pd.DataFrame(Table)

filename = str(date.today())   ".png"

#dir = pathlib.Path(__file__).parent.absolute()

folder = r"/results/"

#path_plot = str(dir)   folder   filename

from_mail = "[email protected]"
to_mail = '[email protected],[email protected], [email protected], [email protected]'
smtp_server = "smtp.gmail.com"
smtp_port = 465
def send_email( smtp_server, smtp_port, from_mail, from_password, to_mail):
    '''
        Send results
    '''
 
    msg = MIMEMultipart()
    msg['Subject'] = 'Results'
    msg['From'] = from_mail
    COMMASPACE = ', '
    msg['To'] = COMMASPACE.join([from_mail, to_mail])
    msg.preamble = 'Something special'
    
    html = """\
    <html>
    <head></head>
    <body>
    {0}
    </body>
    </html>
    """.format(df.to_html())
    part1 = MIMEText(html, 'html')
    msg.attach(part1)

CodePudding user response:

The to_addr argument should be a list of strings if you want to send to multiple recipients.

The immediate problem in your code is that you are joining the from_addr with the (string or list) to_addr where you should be creating a single list to put in the recipients field.

As an aside, your code seems to be written for Python 3.5 or earlier. The email library was overhauled in 3.6 and is now quite a bit more versatile and logical. Probably throw away what you have and start over with the examples from the email documentation. Here is a basic refactoring (just quick and dirty; the structure is rather weird - why are you passing some strings as parameters whereas others are globals outside the function?). It removes some of the problems in your code simply because the modern API removes a lot of the boilerplate which was necessary with the older one.

import pandas as pd # I'm guessing ...?
from email.message import EmailMessage

...
df = pd.DataFrame(Table)

# Commenting out unused variables
# filename = str(date.today())   ".png"
# folder = "/results/"  # no need for an r string, no backslashes here

from_mail = "[email protected]"
from_password = cred.passwort 
to_mail = ['[email protected]', '[email protected]', '[email protected]', '[email protected]']

smtp_server = "smtp.gmail.com"
smtp_port = 465

def send_email(smtp_server, smtp_port, from_mail, from_password, to_mail):
    '''
        Send results via mail
    '''
 
    msg = EmailMessage()
    msg['Subject'] = 'Results'
    msg['From'] = from_mail
    msg['To'] = ', '.join(to_mail   [from_mail])
    # Don't muck with the preamble, especially if you don't understand what it is
    
    html = """\
    <html>
    <head></head>
    <body>
    {0}
    </body>
    </html>
    """.format(df.to_html())
    msg.set_content(html, 'html')
    
    with smtplib.SMTP_SSL(smtp_server, smtp_port) as server:
        server.ehlo()
        server.login(from_mail, from_password)
        # Some servers require a second ehlo() here

        # Use send_message instead of legacy sendmail method
        server.send_message(msg)
        server.quit()

send_email(smtp_server, smtp_port, from_mail, from_password, to_mail)

The generated HTML is still hideous but let's just hope nobody looks at the message source.

  •  Tags:  
  • Related