Home > Net >  Python code behaves differently when in a loop
Python code behaves differently when in a loop

Time:04-30

I wanted to try to send emails with python and found some barebone code to do so online

import smtplib

gmail_user = '[email protected]'
gmail_pw = 'myPassword'

sent_from = gmail_user

to = ['[email protected]', '[email protected]']

subject = 'Some Subject'
body = 'Some body'

email_text = """\
From: %s
To: %s
Subject: %s
%s
""" % (sent_from, ", ".join(to), subject, body)

try:
    smtp_server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
    smtp_server.ehlo()
    smtp_server.login(gmail_user, gmail_pw)
    smtp_server.sendmail(sent_from, to, email_text)
    smtp_server.close()
    print("Success")
except Exception as ex:
    print("Error: ", ex)

Now I wanted to send an email to every target separately so I added a foreach loop within the code. This resulted in the Email headers being messed up and all the headers were interpreted as the From header. Although when I printed them out, they looked fine

After being very confused as to why this happens I decided to try to wrap the entire code in a for loop with one iteration which - according to my understanding - should change nothing at all. But in fact it does produce the same issue as described above. This is how I wrapped the code in a loop:

import smtplib

for i in range(1):
    gmail_user = '[email protected]'
    gmail_pw = 'myPassword'

    sent_from = gmail_user

    to = ['[email protected]', '[email protected]']

    subject = 'Some Subject'
    body = 'Some body'

    email_text = """\
    From: %s
    To: %s
    Subject: %s
    %s
    """ % (sent_from, ", ".join(to), subject, body)

    try:
        smtp_server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
        smtp_server.ehlo()
        smtp_server.login(gmail_user, gmail_pw)
        smtp_server.sendmail(sent_from, to, email_text)
        smtp_server.close()
        print("Success")
    except Exception as ex:
        print("Error: ", ex)

Why does a for loop with one iteration change anything about the workings of the code if literally everything is done within it?

CodePudding user response:

this is the code you would want I suspect:

import smtplib

gmail_user = '[email protected]'
gmail_pw = 'MyPassword'

sent_from = gmail_user

to = ['[email protected]', '[email protected]']

subject = 'Some Subject for multiple people'
body = 'Some body for a few'


smtp_server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
smtp_server.ehlo()
smtp_server.login(gmail_user, gmail_pw)

for email in to:
    email_text = 'Subject:{}\n\n{}'.format(subject, body)
    
    try:
        smtp_server.sendmail(sent_from, email, email_text)
        print("Success")
    except Exception as ex:
        print("Error: ", ex)
smtp_server.close()

You had 2 main problems with how you were approaching it. For whatever reason, if you logged in inside of a loop, it would fail. I've moved this to the start and called close() at the end to prevent logging in multiple times as well. The second issue you had was to do with how you were formatting the email data itself. I used this answers example to assist with making this work, so see this for more: How to add a subject to an email being sent with gmail?

Hopefully, this solves your issue! Many thanks, GhostDog

  • Related