Sending mail via sendmail from python

If I want to send mail not via SMTP, but rather via sendmail, is there a library for python that encapsulates this process?

Better yet, is there a good library that abstracts the whole 'sendmail -versus- smtp' choice?

I'll be running this script on a bunch of unix hosts, only some of which are listening on localhost:25; a few of these are part of embedded systems and can't be set up to accept SMTP.

As part of Good Practice, I'd really like to have the library take care of header injection vulnerabilities itself -- so just dumping a string to popen('/usr/bin/sendmail', 'w') is a little closer to the metal than I'd like.

If the answer is 'go write a library,' so be it ;-)


Asked by: Darcy526 | Posted: 24-09-2021






Answer 1

Header injection isn't a factor in how you send the mail, it's a factor in how you construct the mail. Check the email package, construct the mail with that, serialise it, and send it to /usr/sbin/sendmail using the subprocess module:

import sys
from email.mime.text import MIMEText
from subprocess import Popen, PIPE


msg = MIMEText("Here is the body of my message")
msg["From"] = "me@example.com"
msg["To"] = "you@example.com"
msg["Subject"] = "This is the subject."
p = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE)
# Both Python 2.X and 3.X
p.communicate(msg.as_bytes() if sys.version_info >= (3,0) else msg.as_string()) 

# Python 2.X
p.communicate(msg.as_string())

# Python 3.X
p.communicate(msg.as_bytes())

Answered by: Chelsea897 | Posted: 25-10-2021



Answer 2

This is a simple python function that uses the unix sendmail to deliver a mail.

def sendMail():
    sendmail_location = "/usr/sbin/sendmail" # sendmail location
    p = os.popen("%s -t" % sendmail_location, "w")
    p.write("From: %s\n" % "from@somewhere.com")
    p.write("To: %s\n" % "to@somewhereelse.com")
    p.write("Subject: thesubject\n")
    p.write("\n") # blank line separating headers from body
    p.write("body of the mail")
    status = p.close()
    if status != 0:
           print "Sendmail exit status", status

Answered by: Melissa478 | Posted: 25-10-2021



Answer 3

Jim's answer did not work for me in Python 3.4. I had to add an additional universal_newlines=True argument to subrocess.Popen()

from email.mime.text import MIMEText
from subprocess import Popen, PIPE

msg = MIMEText("Here is the body of my message")
msg["From"] = "me@example.com"
msg["To"] = "you@example.com"
msg["Subject"] = "This is the subject."
p = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE, universal_newlines=True)
p.communicate(msg.as_string())

Without the universal_newlines=True I get

TypeError: 'str' does not support the buffer interface

Answered by: Roman839 | Posted: 25-10-2021



Answer 4

Python 3.5+ version:

import subprocess
from email.message import EmailMessage

def sendEmail(from_addr, to_addrs, msg_subject, msg_body):
    msg = EmailMessage()
    msg.set_content(msg_body)
    msg['From'] = from_addr
    msg['To'] = to_addrs
    msg['Subject'] = msg_subject

    sendmail_location = "/usr/sbin/sendmail"
    subprocess.run([sendmail_location, "-t", "-oi"], input=msg.as_bytes())

Answered by: David493 | Posted: 25-10-2021



Answer 5

This question is very old, but it's worthwhile to note that there is a message construction and e-mail delivery system called Marrow Mailer (previously TurboMail) which has been available since before this message was asked.

It's now being ported to support Python 3 and updated as part of the Marrow suite.

Answered by: Sydney415 | Posted: 25-10-2021



Answer 6

It's quite common to just use the sendmail command from Python using os.popen

Personally, for scripts i didn't write myself, I think just using the SMTP-protocol is better, since it wouldn't require installing say an sendmail clone to run on windows.

https://docs.python.org/library/smtplib.html

Answered by: Haris833 | Posted: 25-10-2021



Answer 7

I was just searching around for the same thing and found a good example on the Python website: http://docs.python.org/2/library/email-examples.html

From the site mentioned:

# Import smtplib for the actual sending function
import smtplib

# Import the email modules we'll need
from email.mime.text import MIMEText

# Open a plain text file for reading.  For this example, assume that
# the text file contains only ASCII characters.
fp = open(textfile, 'rb')
# Create a text/plain message
msg = MIMEText(fp.read())
fp.close()

# me == the sender's email address
# you == the recipient's email address
msg['Subject'] = 'The contents of %s' % textfile
msg['From'] = me
msg['To'] = you

# Send the message via our own SMTP server, but don't include the
# envelope header.
s = smtplib.SMTP('localhost')
s.sendmail(me, [you], msg.as_string())
s.quit()

Note that this requires that you have sendmail/mailx set up correctly to accept connections on "localhost". This works on my Mac, Ubuntu and Redhat servers by default, but you may want to double-check if you run into any issues.

Answered by: Connie436 | Posted: 25-10-2021



Answer 8

The easiest answer is the smtplib, you can find docs on it here.

All you need to do is configure your local sendmail to accept connection from localhost, which it probably already does by default. Sure, you're still using SMTP for the transfer, but it's the local sendmail, which is basically the same as using the commandline tool.

Answered by: Maddie599 | Posted: 25-10-2021



Similar questions

python - Sending emails with sendmail doesn't work for large emails

I'm using python's sendmail in the following way: msg = <SOME MESSAGE> s = smtplib.SMTP('localhost') s.sendmail(me, you, msg.as_string()) s.quit() This usually works fine (I.e I get the email) but it fails (I.e no exception is shown but the email just doesn't arrive) when the message is pretty big (around 200 lines). Any ideas what can cause this?


python - Sending emails with sendmail doesn't work for large emails

I'm using python's sendmail in the following way: msg = <SOME MESSAGE> s = smtplib.SMTP('localhost') s.sendmail(me, you, msg.as_string()) s.quit() This usually works fine (I.e I get the email) but it fails (I.e no exception is shown but the email just doesn't arrive) when the message is pretty big (around 200 lines). Any ideas what can cause this?


python - Sending emails with sendmail doesn't work for large emails

I'm using python's sendmail in the following way: msg = <SOME MESSAGE> s = smtplib.SMTP('localhost') s.sendmail(me, you, msg.as_string()) s.quit() This usually works fine (I.e I get the email) but it fails (I.e no exception is shown but the email just doesn't arrive) when the message is pretty big (around 200 lines). Any ideas what can cause this?


Python: send a mail in html with sendmail

Can someone tell me how to send a mail in a HTML format with sendmail in python? I would like to send this: <pre>some code</pre> Python version is 2.4.3 and can't be updated.


sendmail - python mail no subject coming through

i am sending gmail via python but I do not get any subject. I realize the code I am showing you does not have any subject but i have tried many variations without success. can someone tell me how to implement a subject. The subject will be the same every time. fromaddr = 'XXXX@gmail.com' toaddrs = 'jason@XXX.com' msg = 'Portal Test had an error' #provide gmail user name and...


linux - sendmail from python program

In the below code ,the mails that are going from the system are going to a spam folder for the user ,the python code is given below.I suspect that sender from is going as root@. How to correct this def sendmail(to,fr,subject,msg): sendmail_location = "/usr/sbin/sendmail" # sendmail location p = os.popen("%s -t" % sendmail_location, "w") p.write("From: %s\n" % fr) p.write("Reply-to: %s\...


linux - sendmail succeeds, but python smtplib fails to connect

this works: printf 'hi' | sendmail -f myname@example.com myname@example.com but this fails: def send_mail(send_from, send_to, subject, text, files=[ ], server="localhost"): assert type(send_to)==list msg = MIMEMultipart() msg['From'] = send_from msg['To'] = COMMASPACE.join(send_to) msg['Date'] = formatdate(localtime=True...


python - sendmail with HTML message

I am programming with Python. I already have a function that sends an email with a message and an attachment....My only problem is that I want the message to be HTML, but mine does not respect that..... Here is the function that I'm using def enviarCorreo(fromaddr, toaddr, text, file): msg = MIMEMultipart('mixed') msg['From'] = fromaddr msg['To'] = toaddr msg['Subject'] = 'asunto' msg...


python smtp sendmail with TLS -- Failed

I wrote a python script to send a mail and the code as followed: smtp = smtplib.SMTP(MYMAILSERVER, '587') try: smtp.set_debuglevel(1) smtp.ehlo() if smtp.has_extn('STARTTLS'): smtp.starttls() smtp.ehlo() smtp.login(MYLOGINNAME, PASSWORD) smtp.sendmail(FROM, TO, CONTENT) finally: smtp.quit() I got the messages as followed: .......


How to send HTML email usind sendmail command from Python

I have the next code: def send_email(self, alert_emails, subj, msg): global alert_from p = os.popen("/usr/sbin/sendmail -t" , 'w') p.write("To: %s\n" % (','.join(alert_emails),)) p.write("From: %s\n" % (alert_from,)) p.write("Subject: %s\n\n" % (subj,)) p.write(msg) return p.close() It sends plain text messages. How can I change it to send HTML messages instead? Th...


python - Sendmail not parsing tabs

I'm using sendmail on one of my servers to send out error reports. I'm building this report by appending to a string and then I use sendmail to send the email. However, sendmail does not recognize the tabs in the string. I'm wondering how do I fix this? def sendMail(data): sendmail_location = "/usr/sbin/sendmail" # sendmail location p = os.popen("%s -t" % sendmail_location, "w") p.write("F...


Python sendmail with Cc

I already programmed a function which sends mails with atachments, images on text and other things, but now I need the function to use de Cc (Carbon Copy) function in order to send copies to different emails. I have done some changes on the function and it works but not as I want. THe email is sent to the address ("toaddr") and the mail shows that there are other emails added as Cc("tocc") emails, but the ...






Still can't find your answer? Check out these communities...



PySlackers | Full Stack Python | NHS Python | Pythonist Cafe | Hacker Earth | Discord Python



top