Simple programme - Just want to know whether this is correct way ofcoding

G

guptha

Hi group,
This is my first programme in python ,I need to know whether my code
is in the right path of performance

I wrote a code using multithreading to send mails

FROM = '....com'

SUBJECT = 'This is the subject'
MSGBODY = 'This the body of the message '
MAILSERVER = 'mail....com'
port = 25
username = 'username'
password = 'pass'

# trim the strings of any leading or trailing spaces
FROM = FROM.strip()
SUBJECT = SUBJECT.strip()
MSGBODY = MSGBODY.strip()
MAILSERVER = MAILSERVER.strip()
username = username.strip()
password = password.strip()


# set up email parameters
msg = MIMEMultipart()
msg['From'] = FROM
msg['Subject'] = SUBJECT

#--------------------------------------------------
print "Starting Multi Thread Method"

class MyThread(Thread):

def __init__(self, site, FROM, MSGBODY):
Thread.__init__(self)
self.site = site
self.FROM=FROM
self.MSGBODY=MSGBODY

def run(self):
#Connect to server
print 'Connecting to mail server ', MAILSERVER
try:
s = smtplib.SMTP(MAILSERVER,port)
print 'connected'
#s.set_debuglevel(1)
except:
print 'ERROR: Unable to connect to mail server', sys.exc_info ()[0]
sys.exit(1)

#login to server
if password <> '':
print 'Logging into mail server'
try:
s.login(username,password)
except:
print 'ERROR: Unable to login to mail server', MAILSERVER
print 'Please recheck your password'
sys.exit(1)
print "running for %s " %self.site
print s
s.sendmail(self.FROM, self.site, self.MSGBODY)
print "from %s" %self.FROM
print "msg %s" %self.MSGBODY
print "Emailed for site %s" %self.site
s.quit()
s.close()


a= time.time()
threads = []

for site in listTo:
T = MyThread(site,FROM,MSGBODY)
threads.append(T)
T.start()


for i in threads:
i.join()

print "Took %s seconds" %str(time.time()-a)

#-----------------------------------------------------

The code Works fine ,but I doubt about the performance issue ,My
intention is to send mails concurrently to large number of mail.
1.For every mail id i send It creates a new SMTP object,in case, if i
send to 1000 or more ids
a) It obliviously creates that much SMPT connections ,is this a
right approach .
Thanks in Advance
 
L

Lie Ryan

guptha said:
Hi group,
This is my first programme in python ,I need to know whether my code
is in the right path of performance

I wrote a code using multithreading to send mails

Can't you use BCC?
The code Works fine ,but I doubt about the performance issue ,My
intention is to send mails concurrently to large number of mail.
1.For every mail id i send It creates a new SMTP object,in case, if i
send to 1000 or more ids
a) It obliviously creates that much SMPT connections ,is this a
right approach .
Thanks in Advance

In a lot of cases involving internet, the bottleneck would be internet
speed. And for most purpose (except spamming) it is not really that
necessary to send so much email in so little time (assuming you send 1
mail per second -- which is really slow considering today's processor
and internet speed -- you can send 86400 mails per day). Larger mailing
list can also use BCC.
 
D

Dave Angel

guptha said:
Hi group,
This is my first programme in python ,I need to know whether my code
is in the right path of performance

I wrote a code using multithreading to send mails

FROM = '....com'

SUBJECT = 'This is the subject'
MSGBODY = 'This the body of the message '
MAILSERVER = 'mail....com'
port = 25
username = 'username'
password = 'pass'

# trim the strings of any leading or trailing spaces
FROM = FROM.strip()
SUBJECT = SUBJECT.strip()
MSGBODY = MSGBODY.strip()
MAILSERVER = MAILSERVER.strip()
username = username.strip()
password = password.strip()


# set up email parameters
msg = MIMEMultipart()
msg['From'] = FROM
msg['Subject'] = SUBJECT

#--------------------------------------------------
print "Starting Multi Thread Method"

class MyThread(Thread):

def __init__(self, site, FROM, MSGBODY):
Thread.__init__(self)
self.site = site
self.FROM=FROM
self.MSGBODY=MSGBODY

def run(self):
#Connect to server
print 'Connecting to mail server ', MAILSERVER
try:
s = smtplib.SMTP(MAILSERVER,port)
print 'connected'
#s.set_debuglevel(1)
except:
print 'ERROR: Unable to connect to mail server', sys.exc_info ()[0]
sys.exit(1)

#login to server
if password <> '':
print 'Logging into mail server'
try:
s.login(username,password)
except:
print 'ERROR: Unable to login to mail server', MAILSERVER
print 'Please recheck your password'
sys.exit(1)
print "running for %s " %self.site
print s
s.sendmail(self.FROM, self.site, self.MSGBODY)
print "from %s" %self.FROM
print "msg %s" %self.MSGBODY
print "Emailed for site %s" %self.site
s.quit()
s.close()


a= time.time()
threads = []

for site in listTo:
T = MyThread(site,FROM,MSGBODY)
threads.append(T)
T.start()


for i in threads:
i.join()

print "Took %s seconds" %str(time.time()-a)

#-----------------------------------------------------

The code Works fine ,but I doubt about the performance issue ,My
intention is to send mails concurrently to large number of mail.
1.For every mail id i send It creates a new SMTP object,in case, if i
send to 1000 or more ids
a) It obliviously creates that much SMPT connections ,is this a
right approach .
Thanks in Advance
Any program that launches multiple threads is not a "simple program,"
especially for a first time user.

I don't know smtplib at all, so these questions may be off-base. First,
sendmail() takes as its second argument a list of to_addr, so why not
send these all as a single operation? If that would work, this would
degenerate into a much simpler program. More importantly, it should
generate much less traffic between your machine and your smtp server,
and probably less traffic between that server and the actual destination
domains. I have to assume that if it's a single sendmail request, the
server would then batch-send them to each unique domain in the to_addrs
list. Anyway, what if the message body be a couple of megabytes, and
you're sending it to 100 people? Sending a single message with a list
in to_list would save tons of time.

Second, if you do have to send them all separately (for example, if you
had different mail_options, which you don't yet), then I question the
need or workability of using a separate thread for all of them. Trying
to open 1000 threads is very resource hungry, Trying to open that many
smtp connections is even worse. One of these is likely to fail. And
I'm guessing that beyond 10 or so, it'd run at least as fast with a
different approach.


If I had to do something like this, I'd expect to wind up with some
number (say 10) of threads, and a queue of things for them to do. So if
you had 1000 things, each thread would do approximately 100 of them.
Now, sharing a queue like that is more work, with more things to mess
up. Currently your threads share only read-only data, which makes
threads pretty straightforward.
 
P

Piet van Oostrum

guptha said:
g> Hi group,
g> This is my first programme in python ,I need to know whether my code
g> is in the right path of performance
g> I wrote a code using multithreading to send mails
g> FROM = '....com'
g> SUBJECT = 'This is the subject'
g> MSGBODY = 'This the body of the message '
g> MAILSERVER = 'mail....com'
g> port = 25
g> username = 'username'
g> password = 'pass'
g> # trim the strings of any leading or trailing spaces
g> FROM = FROM.strip()
g> SUBJECT = SUBJECT.strip()
g> MSGBODY = MSGBODY.strip()
g> MAILSERVER = MAILSERVER.strip()
g> username = username.strip()
g> password = password.strip()

g> # set up email parameters
g> msg = MIMEMultipart()
g> msg['From'] = FROM
g> msg['Subject'] = SUBJECT
g> #--------------------------------------------------
g> print "Starting Multi Thread Method"
g> class MyThread(Thread):
g> def __init__(self, site, FROM, MSGBODY):
g> Thread.__init__(self)
g> self.site = site
g> self.FROM=FROM
g> self.MSGBODY=MSGBODY
g> def run(self):
g> #Connect to server
g> print 'Connecting to mail server ', MAILSERVER
g> try:
g> s = smtplib.SMTP(MAILSERVER,port)
g> print 'connected'
g> #s.set_debuglevel(1)
g> except:
g> print 'ERROR: Unable to connect to mail server', sys.exc_info ()[0]
g> sys.exit(1)
g> #login to server
g> if password <> '':
g> print 'Logging into mail server'
g> try:
g> s.login(username,password)
g> except:
g> print 'ERROR: Unable to login to mail server', MAILSERVER
g> print 'Please recheck your password'
g> sys.exit(1)
g> print "running for %s " %self.site
g> print s
g> s.sendmail(self.FROM, self.site, self.MSGBODY)
g> print "from %s" %self.FROM
g> print "msg %s" %self.MSGBODY
g> print "Emailed for site %s" %self.site
g> s.quit()
g> s.close()

g> a= time.time()
g> threads = []
g> for site in listTo:
g> T = MyThread(site,FROM,MSGBODY)
g> threads.append(T)
g> T.start()

g> for i in threads:
g> i.join()
g> print "Took %s seconds" %str(time.time()-a)
g> #-----------------------------------------------------

Tuesday this same program with some minor differences was posted by
gganesh <[email protected]>. There was a discussion about that. So
did you copied that program with the suggested changes? I don't think it
is nice to have two parallel discussions on the same subject. And
copying without giving credits is not considered nice behaviour either.
Usually it is called plagiarism.
g> The code Works fine ,but I doubt about the performance issue ,My
g> intention is to send mails concurrently to large number of mail.
g> 1.For every mail id i send It creates a new SMTP object,in case, if i
g> send to 1000 or more ids
g> a) It obliviously creates that much SMPT connections ,is this a
g> right approach .

For such a big number of mails this is not the right approach. First
your operating system may not like it to have such a large number of
threads active. Second, the mail server probably doesn't like it that
you make such a large number of connections simultaneously. If the mail
server doesn't protest, probably its systems administrator will.
Moreover there is probably no benefit in having 1000 connections open to
the same mail server because long before there will be another
bottleneck such as your network connection or the CPU load of either
your computer or the mail server, unless you are on a very scalable
infrastructure.

A better solution will be to use a Thread Pool with a limited number of
simultaneous threads (my guess is that 10-20 or so would be good
enough).

And as I said to my students yesterday: You shouldn't program
multithreaded applications unless you have studied this subject
thoroughly. Of course I don't know how this applies to you.
 
S

Steven D'Aprano

The code Works fine ,but I doubt about the performance issue ,My
intention is to send mails concurrently to large number of mail. 1.For
every mail id i send It creates a new SMTP object,in case, if i send to
1000 or more ids
a) It obliviously creates that much SMPT connections ,is this a
right approach .

Why do you care? I assume you're running this code on a botnet, so why
care about performance?

[ha ha only serious]
 
N

namekuseijin

The code Works fine ,but I doubt about the performance issue ,My
intention is to send mails concurrently to large number of mail.
1.For every mail id i send It creates a new SMTP object,in case, if i
send to 1000 or more ids

why should I help a spammer... ;)
 
A

Aahz

This is my first programme in python ,I need to know whether my code
is in the right path of performance

I wrote a code using multithreading to send mails

Here's the Right Way to do this: install your a local mailserver on your
own machine and configure it to send to your external server. You should
be able to pump hundreds of messages through it in minimal time.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top