I'm trying to send attachments via email with python but I'm getting this error:
msg.attach(msgImage)
AttributeError: 'str' object has no attribute 'attach'
Here is the code:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.mime.image import MIMEImage
def send_email():
fromaddr = 'testevpsa1#gmail.com'
toaddrs = 'Toemail'
global msg
subject = 'RESPOSTA'
message = 'Subject: %s\n\n%s' % (subject, msg)
username = 'testevpsa1#gmail.com'
password = 'xxxxxxxx'
server = smtplib.SMTP('smtp.gmail.com:587')
server.starttls()
server.login(username,password)
fp = open ('C:\Python27\Scripts\pares.txt', 'rb')
msgImage = MIMEImage (fp.read(), _subtype='txt')
fp.close()
msg.attach(msgImage)
server.sendmail(fromaddr, toaddrs, message, msg.as_string())
server.quit()
msg = 'Email test, please, see the attachments'
send_email()
Anyone has a hint of what is the problem?
Your code is weird and incorrect. You start using advanced concepts without a basic knowledge of the language, smtp protocol and email module.
msg variable in your code has str type. str is a plain string - a list of characters. It doesn't have method .attach.
I guess you wanted to use an instance of the class email.message instead of a string. Also, there's no need to use global variable. Global variables are bad, and it's totally unnecessary to use global variable in your case.
Related
Documentation is here for how to send an email: https://docs.python.org/3/library/email.examples.html
The full code I tried to run was...
# Import smtplib for the actual sending function
import smtplib
# Import the email modules we'll need
from email.message import EmailMessage
# Open the plain text file whose name is in textfile for reading.
# Create a text/plain message
msg = EmailMessage("HI")
# me == the sender's email address
# you == the recipient's email address
msg['Subject'] = "SubjectLine"
msg['From'] = aaaaa#gmail.com
msg['To'] = aaaaa#yahoo.com
# Send the message via our own SMTP server.
s = smtplib.SMTP('localhost')
s.send_message(msg)
s.quit()
I get an error at the 16th line of code
msg['Subject'] = "SubjectLine"
The error is: 'str' object has no attribute 'header_max_count'
You seem to have a misunderstanding on how to instantiate an instance of EmailMessage, and it's unclear why you've passed the string "HI" as an argument. The documentation clearly mentions that this argument is meant to take on policy information, which would include the header_max_count attribute it seems to expect.
Remove this otherwise unnecessary use of "HI" in your code:
msg = EmailMessage()
Using the email and smtp libraries, I have developed a script that automatically sends mail via outlook's smtp server.
I enter the content of the mail and after the content is written I want to send the picture at the bottom.
But it sends the picture not at the bottom as I want it, but at the top of the mail content.
Example mail ( This is only image ) : https://ibb.co/d5HFwRG
My code:
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
def send_mail(gender, messages, subject):
global msg
try:
msg = MIMEMultipart()
s = smtplib.SMTP(host="SMTP.office365.com", port=587)
s.starttls()
s.login(mail, password)
msg['From'] = mail
msg['To'] = example#outlook.com
msg['Subject'] = messages
msg.attach(MIMEText(message, 'plain', 'utf-8'))
attachment = open("image.jpg", "rb")
p = MIMEBase('application', 'octet-stream')
p.set_payload((attachment).read())
encoders.encode_base64(p)
p.add_header('Content-Disposition', "attachment; filename= %s" % image)
msg.attach(p)
s.send_message(msg)
del msg
except Exception as e:
print(e)
My code is actually much more complex, but I just showed you the function I use to send mail.
I had to change the names of some variables while adding them here, so the above code may not work for you, you need to edit it.
How can I get that picture sent in the Mail to the bottom?
I did some google researches and found a lot of stuff. Unfortunately I do not understand what I found so I need to open a new "public request". As I told in my title already I want to attach a .txt file to my email. Sorry to ask that again after thousands of people already did this, but here is my method to send the mail:
import smtplib, ssl
from email.mime.multipart import MIMEMultipart
from email.mime.multipart import MIMEBase
from email.mime.text import MIMEText
from email.utils import formatdate
from email import encoders
import config
#creating file to write the keys in later
file = open("my_filename.txt", "w+")
#creating subject and message for the email
subject = "Test123 new / updated"
msg = "look in attachment"
def send_mail(subject, msg)
try:
server = smtplib.SMTP("smtp.gmail.com:587")
server.ehlo()
server.starttls()
server.login(config.EMAIL_ADDRESS, config.PASSWORD)
message = "Subject: {}\n\n{}".format(subject, msg)
server.sendmail(config.EMAIL_ADDRESS, config.EMAIL_RECEIVER, message)
server.quit()
print("success: Email sent!")
except:
print("Email failed to send")
This worked fine for me (just managed it with some research too. To attach the file finally I found something like that:
msg = MIMEMultipart()
#some other code to create a mail with subject and stuff like that
msg.attach(MIMEText(text))
If I change "text" to "my_filename.txt" it do not work. What do I need to change?
ahh, I had an other own idea. I removed the line "msg = "look in attachment"" and instead of this I used the method file.read(). So my line where I send the mail looks like this now:
server.sendmail(config.EMAIL_ADDRESS, config.EMAIL_RECEIVER, file.read())
I've just started learning Python and I'm trying to code a bot where it emails a HTML message along with a .docx (Microsoft Word) attachment. Here's my code and it works fine, but I'm confused with a few of the parameters.
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
import os
#Email Variables
myemail = "myemail#hotmail.com"
recipient = "recipientemail#hotmail.com"
#Specifying MIME variables to include in email header
mime_details = MIMEMultipart('mixed')
mime_details['Subject'] = "This is my email subject!"
mime_details['From'] = myemail
mime_details['To'] = recipient
#Creating body of message
html_body = """\
<html>\
<p>\
My email message!
</p>\
</html>\
"""
#Attaching File To Email
os.chdir('C:\\Users\Kyle\Desktop\')
openfile = open('testfile.docx', 'rb')
doc = MIMEApplication(openfile.read(), _subtype='vnd.openxmlformats-officedocument.wordprocessingml.document')
doc.add_header('Content-Disposition', 'attachment', filename='My Content.docx')
mime_details.attach(doc)
openfile.close()
#Recording MIME types of email parts
htmlpart = MIMEText(html_body, _subtype='html')
#Attaching parts to message container
mime_details.attach(htmlpart)
#Sending message via SMTP server
s = smtplib.SMTP(host='smtp.live.com', port=587)
s.ehlo()
s.starttls()
s.login(myemail, 'password')
s.sendmail(myemail, recipient, mime_details.as_string())
s.quit()
I have a few questions regarding the code above, and I would greatly appreciate it if you can help me clear whatever confused thoughts I have regarding the modules above.
A) The add_header module
mime_details['Subject'] = "This is my email subject!"
mime_details['From'] = myemail
mime_details['To'] = recipient
As you can see from the snippet above, I clearly defined each header variable in the MIMEMultipart envelope. According to Python's docs, these values will be added to the header directly. I tried using the add_header() method directly as an alternative, something like:
mime_details.add_header(Subject = "This is my email subject!", To = recipient, From = myemail)
But it gave me errors. Any idea why?
B) At the last few lines of my code, I had to append a .as_string() to the payload I was sending. I tried taking it out but it gave me a TypeError: expected string or buffer.
The Python docs give me this:
as_string(unixfrom=False, maxheaderlen=0, policy=None)
Return the entire message flattened as a string.
I assume that I have to append this in every case? the mime_details object has two parts to it - the HTML message and the .docx file. Both will be converted to strings? What about image files?
C) When I open my file to attach, I read it in 'rb' mode.
Here's the code:
openfile = open('testfile.docx', 'rb')
I tried using 'r' but it raises an error. I've read up on this and 'rb' mode simply opens the file in binary. Why would it make sense to open a .docx file in binary mode? Am I to use 'rb' mode for ALL non.txt files?
D) Finally, I've seen some people use base64 encoding for attachments. I've searched around and a particularly popular script over here is below (from How to send email attachments with Python):
import smtplib, os
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.utils import COMMASPACE, formatdate
from email import encoders
def send_mail( send_from, send_to, subject, text, files=[], server="localhost", port=587, username='', password='', isTls=True):
msg = MIMEMultipart()
msg['From'] = send_from
msg['To'] = COMMASPACE.join(send_to)
msg['Date'] = formatdate(localtime = True)
msg['Subject'] = subject
msg.attach( MIMEText(text) )
for f in files:
part = MIMEBase('application', "octet-stream")
part.set_payload( open(f,"rb").read() )
encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="{0}"'.format(os.path.basename(f)))
msg.attach(part)
smtp = smtplib.SMTP(server, port)
if isTls: smtp.starttls()
smtp.login(username,password)
smtp.sendmail(send_from, send_to, msg.as_string())
smtp.quit()
Why does content need to be encoded in base64? Does this apply to all files and is a general thing to be added, or can I ignore this? What situations am I to invoke that method?
Finally, being a noob at Python, some of my code above may be redundant\badly structured. If you have any tips\suggestions on how I can improve my simply script, please do let me know.
Thank you!
I want to send an email with an attachment using the following code (Python 3.1)
(greatly simplified to show the example)
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
msg = MIMEMultipart()
msg['From'] = from_addr
msg['To'] = to_addr
msg['Subject'] = subject
msg.attach(MIMEText(body))
fp = open(att_file)
msg1 = MIMEText(fp.read())
attachment = msg1.add_header('Content-Disposition', 'attachment', filename=att_file)
msg.attach(attachment)
# set string to be sent as 3rd parameter to smptlib.SMTP.sendmail()
send_string = msg.as_string()
The attachment object msg1 returns 'email.mime.text.MIMEText' object at ', but when the msg1.add_header(...) line runs the result is None, hence the program falls-over in msg.as_string() because no part of the attachment can have a None value. (Traceback shows "'NoneType' object has no attribute 'get_content_maintype'" in line 118 of _dispatch in generator.py, many levels down from msg.as_string())
Has anyone any idea what the cause of the problem might be? Any help would be appreciated.
Alan Harris-Reid
Use:
msg.attach(msg1)