Send Email With File Attachment From Python
by Mike Levin
Tuesday, August 02, 2022I did the work of expanding the sendemail.py program to:
- Use HTML for the body of the email message (with plain text alternative)
- Include an attached image (able to be used in HTML img tags)
I didn’t show a video of this because it was basically just a bunch of tedious code wrangling, but now I’m up to the point of including a zipped file attachment containing multiple items.
I’ve done the setup work for that in Jupyter and am ready to move it into the LXD Linux container.
I need to expand the sendmail.py file a little bit in order to attach the file. I can do that for the video.
Get the bit of code that’s not in the Jupyter Notebook yet and put it here.
mimecats = MIMEBase('application', 'octet-stream')
with open(Path('cats.zip'), 'br') as zfh:
mimecats.set_payload(zfh.read())
encoders.encode_base64(mimecats)
mimecats.add_header('Content-Disposition', "attachment; filename= %s" % filename)
msgdict.attach(mimecats)
I completed this project and here is the code:
import shlex
import schedule
from time import sleep
from os import environ
from sys import stdout
from datetime import datetime
from subprocess import Popen, PIPE
pulse_count = 0
def run(command, cwd=None):
process = Popen(
shlex.split(command),
stdout=PIPE,
cwd=cwd,
bufsize=1,
universal_newlines=True,
shell=False,
)
for line in process.stdout:
line = line.rstrip()
print(line)
stdout.flush()
def hello():
print("Hello World")
def pulse():
global pulse_count
pulse_count += 1
anow = f"{pulse_count} - {datetime.now()}"
with open('/tmp/scheduler.txt', 'a') as fh:
print(f"{anow} is written to /tmp/scheduler.txt")
fh.write((anow) + '\n')
def sendmail():
print("Sending email")
pyx = "/home/ubuntu/py310/bin/python3.10"
cwd = "/home/ubuntu/github/scheduler/"
cmd = f"{pyx} {cwd}sendcats.py"
run(cmd, cwd=cwd)
print("The pulse service has started.")
schedule.every(10).seconds.do(hello)
schedule.every(5).seconds.do(pulse)
schedule.every(1).minute.do(sendmail)
while True:
schedule.run_pending()
sleep(1)