+ Reply to Thread
Results 1 to 10 of 10

Thread: Sending an email with python

  1. #1
    purpleflame's Avatar
    purpleflame is offline x10Hosting Member purpleflame is an unknown quantity at this point
    Join Date
    Dec 2008
    Posts
    17

    Sending an email with python

    I am interested in making a cron job that will send email. So to start off with I am making a script to send an email with a python script. I found a couple different ways to do this -- using sendmail and smtplib. I tried using the sendmail method with this script but I do not know where it went wrong.
    Code:
    # This script is to test using the sendmail pipe to send emails.
    
    #!/usr/bin/env python
    
    print "Content-type: text/plain"
    print
    
    import os
    
    MAIL = "/usr/sbin/sendmail"
    
    # Read the email message from a file.
    f = open('sampleemail.txt', 'r')
    mssg = f.read()
    f.close()
    
    # Open a pipe to the mail program and write the data to the pipe.
    p = os.popen("%s -t" % MAIL, 'w')
    p.write(mssg)
    exitcode = p.close()
    if exitcode:
        print "Exit code: %s" % exitcode
    I get an Internal Server Error 500. When I look at my error logs the only new listing is:
    Code:
    [Mon Apr 06 19:46:53 2009] [error] [client 141.217.222.214] File does not exist: /home/pf/public_html/500.shtml
    What is odd is that I also made one to test sending with smtplib. This script does the same thing but also sends the email. Odd fO.o
    Code:
    #!/usr/bin/env python
    
    import smtplib
    
    SERVER = "localhost"
    
    FROM = "purple@purpleflame.exofire.net"
    TO = ["alikakakhel@yahoo.com"] # must be a list
    
    SUBJECT = "Testing..."
    
    TEXT = "...working"
    
    # Prepare actual message
    
    message = """\
    From: %s
    To: %s
    Subject: %s
    
    %s
    """ % (FROM, ", ".join(TO), SUBJECT, TEXT)
    
    # Send the mail
    
    server = smtplib.SMTP(SERVER)
    server.sendmail(FROM, TO, message)
    server.quit()
    Any ideas?

  2. #2
    garrettroyce's Avatar
    garrettroyce is offline Generally Helpful Member garrettroyce is a glorious beacon of lightgarrettroyce is a glorious beacon of light
    Join Date
    Apr 2008
    Location
    IL, USA
    Posts
    3,746

    Re: Sending an email with python

    Isn't it "/usr/bin/sendmail" and not " "/usr/sbin/sendmail"
    gjr.gr - coming soon: secrets of OCD coding from a self taught tinkerer

  3. #3
    purpleflame's Avatar
    purpleflame is offline x10Hosting Member purpleflame is an unknown quantity at this point
    Join Date
    Dec 2008
    Posts
    17

    Re: Sending an email with python

    I thought of that possibility, but my cpanel tells me its what I put. Hence my putting it. I am on the absolut server if that helps. I tried changing it to what you wrote and trying anyway, but only had the same thing happen.

    Any idea the other script sends the mail, but also gives the error?

  4. #4
    misson is offline x10 Spammer misson is a jewel in the rough
    Join Date
    Mar 2008
    Location
    Libertatia
    Posts
    2,506

    Re: Sending an email with python

    Tests say /usr/sbin/sendmail is the winner.

    The path to sampleemail.txt is probably wrong, unless you put it in cgi-bin/.

    Always test for exceptions. Wrap a
    Code:
    try:
        ...
    except Exception, exc:
        print exc
    block around your code & see if you catch anything.

  5. #5
    purpleflame's Avatar
    purpleflame is offline x10Hosting Member purpleflame is an unknown quantity at this point
    Join Date
    Dec 2008
    Posts
    17

    Re: Sending an email with python

    My file sampleemail.txt is in the same folder as the script. The script has permissions 755. Is that not enough? Also I have it set so that python scripts can run in the folder the script is in.

    I tried putting the try structure in but I get the same thing. This time the error logs show this instead.

    Code:
    [Tue Apr 07 09:16:20 2009] [error] [client 141.217.222.214] File does not exist: /home/pf/public_html/favicon.ico
    [Tue Apr 07 09:16:18 2009] [error] [client 141.217.222.214] File does not exist: /home/pf/public_html/favicon.ico
    [Tue Apr 07 09:16:17 2009] [error] [client 141.217.222.214] File does not exist: /home/pf/public_html/500.shtml

  6. #6
    misson is offline x10 Spammer misson is a jewel in the rough
    Join Date
    Mar 2008
    Location
    Libertatia
    Posts
    2,506

    Re: Sending an email with python

    Quote Originally Posted by purpleflame View Post
    My file sampleemail.txt is in the same folder as the script.
    You might want to move it. I don't think it will create a security hole to leave it there, but cgi-bin is not meant for storing data.

    Quote Originally Posted by purpleflame View Post
    The script has permissions 755. Is that not enough? Also I have it set so that python scripts can run in the folder the script is in.

    I tried putting the try structure in but I get the same thing.
    Then you've got me stumped. I tested the following, which is basically your code plus the exception handler, and it worked for me:
    Code:
    #!/usr/bin/env python
    print "Content-type: text/plain"
    print
    
    import os, datetime
    
    MAIL="/usr/sbin/sendmail"
    
    try:
        # Read the email message from a file.
        f = open('sampleemail.txt', 'r')
        mssg = f.read()
        f.close()
        mssg += datetime.datetime.now().__str__() + "\n"
        
        exitcode=1
        # Open a pipe to the mail program and write the data to the pipe.
        p = os.popen("%s -t" % MAIL, 'w')
        p.write(mssg)
        exitcode = p.close()
        if exitcode:
            print "Exit code: %s" % exitcode
        else:
            print "Mail sent"
    except Exception, exc:
        print exc

    Wait a minute: is this the literal start to your script?
    Quote Originally Posted by purpleflame View Post
    Code:
    # This script is to test using the sendmail pipe to send emails.
    
    #!/usr/bin/env python
    If so, that's the problem. The shebang line must be the first line for the shell to know what executable to pass the script to. I had been assuming the comment was added when you posted the script.

    Anyway, now you know to always catch exceptions. You should also look into using subprocess rather than os.popen.
    Last edited by misson; 04-07-2009 at 09:42 AM.

  7. #7
    Parsa44 is offline x10 Sophmore Parsa44 is an unknown quantity at this point
    Join Date
    Aug 2008
    Posts
    232

    Re: Sending an email with python

    Why do it with python when you can do it with PHP, easier and simpler.

  8. #8
    purpleflame's Avatar
    purpleflame is offline x10Hosting Member purpleflame is an unknown quantity at this point
    Join Date
    Dec 2008
    Posts
    17

    Re: Sending an email with python

    Looks like the issue with not putting the shebang at the very beginning was the issue.

    So now I am trying to use subprocess instead of os, but it tells me:
    Code:
    'file' object has no attribute 'communicate'
    I went to the webpage you gave and tryed to replace the os usage with the subprocess usage.

    Code:
    #!/usr/bin/env python
    
    # This script is to test using the sendmail pipe to send emails.
    
    print "Content-type: text/plain"
    print
    
    import subprocess
    
    try:
        # Path to sendmail
        MAIL = "/usr/sbin/sendmail"
    
        # Read the email message from a file.
        f = open('sampleemail.txt', 'r')
        mssg = f.read()
        f.close()
        
        # Open a pipe to the mail program and write the data to the pipe using the subprocess library.
        p = subprocess.Popen("%s -t" % MAIL, shell=True, bufsize=0, stdin=subprocess.PIPE).stdin
        p.communicate(mssg)
        exitcode = p.terminate()
        
        if exitcode:
                print "Exit code: %s" % exitcode
    except Exception, exc:
        print exc
    I am not sure why it is going to file and not sendmail since that is what MAIL has in it. Am I supposed to use send_signal rather than communicate?

  9. #9
    misson is offline x10 Spammer misson is a jewel in the rough
    Join Date
    Mar 2008
    Location
    Libertatia
    Posts
    2,506

    Re: Sending an email with python

    Quote Originally Posted by purpleflame View Post
    So now I am trying to use subprocess instead of os, but it tells me:
    Code:
    'file' object has no attribute 'communicate'
    [...]
    I am not sure why it is going to file and not sendmail since that is what MAIL has in it. Am I supposed to use send_signal rather than communicate?
    That's because in your code, you set "p" to the process's stdin, which makes it a file (note the error message tells you this), not the process (a Popen). You use the 'write' method on files, 'communicate' on Popen objects. If ever you're getting an "object has no attribute" error, it's probably because a variable doesn't hold what you think it holds.

    Signals are a very basic IPC mechanism. You can only send 32 asynchronous messages (most with predefined meanings; older systems had fewer signals). If a process is handling a signal, it can't receive any more signals of the same type. Moreover, receiving a signal while handling another can cause problems (depending on how you've set up signal handling). In short, no, don't use send_signal.

    Also, there's no need to pass arguments with default values to a function when you're using keyword arguments.

    Try this:
    Code:
    #!/usr/bin/env python
    
    print "Content-type: text/plain"
    print
    
    import os, subprocess, datetime
    
    mailer = "/usr/sbin/sendmail"
    
    def readmsg(fname='../sampleemail.txt'):
        msgfile = open(fname, 'r')
        msg = msgfile.read()
        msgfile.close()
        return msg + datetime.datetime.now().__str__() + "\n"
    
    # Open a pipe to the mail program and write the data to the pipe.
    def sendmail(msg):
        p=subprocess.Popen([mailer,"-t"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        p.stdin.write(msg)
        p.stdin.close();
        return (p.returncode, p.stdout.read())
    
    try:
        print "Using", mailer
        # Read the email message from a file.
        msg = readmsg();
        print "Sending {\n", msg, "}"
        (returncode, rsltmsg) = sendmail(msg)
        if returncode:
            print "Sendmail failed with code", returncode
            if len(rsltmsg):
                print "Sendmail had this to say:", rsltmsg
    except IOError, exc:
        print "Error creating message:", exc
    except Exception, exc:
        print 'Error while mailing', exc
    You'll want to refactor to get rid of the "mailer" global, either by creating a class or using closures (examples of closures).

    Edit:
    Don't forget to move sampleemail.txt & update the script.
    Last edited by misson; 04-07-2009 at 08:57 PM.

  10. #10
    hardbyte is offline x10Hosting Member hardbyte is an unknown quantity at this point
    Join Date
    Nov 2007
    Posts
    6

    Re: Sending an email with python

    I had an issue with email sending from python also. The weird thing is it worked in the past. I think the server changed a few months ago and that somehow broke it. While writing this post I actually fixed my problem :-P

    Any how instead of using sendmail directly like you I used the python module "smtplib" which calls (hopefully) to any smtp listener.

    Code:
    import time
    
    testing = True
    
    import smtplib
    print "imported smtplib" 
    
    def mail(serverURL="localhost", sender='', to='', subject='', text=''): 
        """ 
        Usage: 
        mail('somemailserver.com', 'me@example.com', 'someone@example.com', 'test', 'This is a test') 
        """ 
        headers = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (sender, to, subject) 
        message = headers + text 
        mailServer = smtplib.SMTP(serverURL) 
        mailServer.sendmail(sender, to, message) 
        mailServer.quit() 
     
         
    def test(): 
        
        mailMe = ('localhost','noreply@example.com','example-user@example.com','Test send email','python email sending test')
        mail(*mailMe)
        print "Settings Used: ", mailMe
        
    if testing:
        print "cron script is running test at " + time.ctime()
        test()
    This seems to work so why bother with the touching the metal approach of using sendmail?


    p.s what the hell is with the un-trusting nature of this forum? Passing a turing test to post or search what is wrong with just a login capta like every other site on the interweb...
    Edit:
    Quote Originally Posted by Parsa44 View Post
    Why do it with python when you can do it with PHP, easier and simpler.
    Because python is cleaner, more powerful and most importantly "cooler"... ;)

    http://effbot.org/pyfaq/how-do-i-sen...hon-script.htm was useful for me by the way. It mentions your method purpleflame.
    Last edited by hardbyte; 04-19-2009 at 06:01 AM. Reason: Automerged Doublepost

+ Reply to Thread

Similar Threads

  1. Simple PHP Email Sending Form
    By dquigley in forum Programming Help
    Replies: 10
    Last Post: 12-13-2008, 02:33 PM
  2. Profiting from “Unsolicited Email Marketing”
    By arkad in forum Earning Money
    Replies: 0
    Last Post: 11-17-2008, 11:43 PM
  3. Help me in sending Email
    By Nahid_hossain in forum Programming Help
    Replies: 1
    Last Post: 10-22-2008, 11:40 PM
  4. Sending Email
    By persiantnt in forum Free Hosting
    Replies: 0
    Last Post: 06-10-2008, 09:33 AM
  5. Failed sending email PHP
    By N2PGames in forum Free Hosting
    Replies: 2
    Last Post: 06-18-2006, 06:28 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
x10hosting free hosting for the masses
dedicated servers