Python email via sendmail with pdf attachment fails

Python email via sendmail with pdf attachment fails on any pdf file greater than 47k. Works correctly on files 47k and under. Why? Here is the code I am using. Also, is there any way to use a newer version of python in Ignition? It is really hard to research when most posts are for a newer version of python.

def SendPDFEmail(PDFPathAndFileName, PDFFileName, Subject, Message, EmailList):
	import smtplib
	from email.mime.multipart import MIMEMultipart
	from email.mime.application import MIMEApplication
	from email.mime.text import MIMEText
	debug = 5

    # prepare semicolon delimited email list for sendmail command
	recipients = [email.strip() for email in EmailList.split(";") if email.strip()]
	if debug >= 5: print "SendPDFEmail - Recipients:", recipients

	if not recipients:
		if debug >= 0: print("SendPDFEmail - No valid recipients found.")
		WriteToQCAuditFile("N/A", PDFFilename, "No email recipients - email not sent")
		return 'Error'

	msg = MIMEMultipart()
	msg.attach(MIMEText(Message, "plain"))
	msg['Subject'] = Subject
	msg['From'] = "Info@pf-pv.com"
	msg['To'] = ", ".join(recipients)

	try:
		with open(PDFPathAndFileName, "rb") as f:
			pdfAttachment = MIMEApplication(f.read(), _subtype="pdf")
			pdfAttachment.add_header('Content-Disposition', 'attachment', filename=PDFFileName)
			msg.attach(pdfAttachment)
	except IOError as e:
		if debug >= 0: print("SendPDFEmail - Error reading PDF file:", e)
		WriteToQCAuditFile("N/A", PDFFilename, "Error Reading PDF file - email not sent")
		return 'Error'

	try:
		server = smtplib.SMTP('10.10.101.2', 25, timeout=10)
		server.ehlo()
		server.sendmail("Info@pf-pv.com", recipients, msg.as_string())
		server.quit()
		if debug>= 1: print("SendPDFEmail - Email sent successfully.")
		return 'Success'
	except smtplib.SMTPException as e:
		if debug >= 0:  print("SendPDFEmail - SMTP error occurred:", str(e))
		WriteToQCAuditFile("N/A", PDFFilename, "SMTP error occured - email not sent")
		return 'Error'
	except Exception as e:
		if debug >= 0:  print("SendPDFEmail - Unexpected error:", str(e))
		WriteToQCAuditFile("N/A", PDFFilename, "Unexpected error occured - email not sent")
		return 'Error'

I would recommend using the built-in system.net.sendEmail() for this.
Link to manual page: system.net.sendEmail | Ignition User Manual

2 Likes

Thank you, I will give that a try

Also, since you're passing in the PDFPathAndFileName, you might want to checkout system.file.readFileAsBytes() so you can pass to the sendEmail() as it expects byte array for attachments.

Link: system.file.readFileAsBytes | Ignition User Manual

It isn't python. It is jython. For complex reasons, jython has not been ported to python3 syntax and features, and may never be.

As noted by others, do not use python methods for services that Ignition itself provides API.

I also recommend not using python stdlib or other libraries where Java itself, or one of the jars supplied by Ignition, provides native java methods. (Jython can use those.)

4 Likes

Thank you both, it worked great, I will always check for an ignition built in function before using the jython. And thanks for clarification on jython/python and that there is an underlying reason why it is using the older version, but do wish we could use a newer version. As you say, if I rely more on Ignition, the jython becomes much less important. Thanks again.