to send emails with images you need to use MIMEMultipart, but the basic approach:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
msg = MIMEMultipart('alternative')
msg['Subject'] = "subject"
msg['From'] = from_addr
msg['To'] = to_addr
part = MIMEImage(open('/path/to/image', 'rb').read())
s = smtplib.SMTP('localhost')
s.sendmail(from_addr, to_addr, msg.as_string())
s.quit()
will produce an email with empty body and the image as an attachment.
The better way, ie to have the image as part of the body of the email, requires to write an HTML body that refers to that image:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
msg = MIMEMultipart('alternative')
msg['Subject'] = "subject
msg['From'] = from_addr
msg['To'] = to_addr
text = MIMEText('<img src="cid:image1">', 'html')
msg.attach(text)
image = MIMEImage(open('/path/to/image', 'rb').read())
# Define the image's ID as referenced in the HTML body above
image.add_header('Content-ID', '<image1>')
msg.attach(image)
s = smtplib.SMTP('localhost')
s.sendmail(from_addr, to_addr, msg.as_string())
s.quit()
The trick is to define an image with a specific Content-ID and make that the only item in an HTML body: now you have an email with contains that specific image as the only content of the body, embedded in it.