MIMEText UTF-8 encode problems when sending email

33,689

Solution 1

It seems that, in python3, a Header object is needed to encode a Subject as utf-8:

# -*- coding: utf-8 -*-
from email.mime.text import MIMEText
from email.header import Header
s = 'ação'
m = MIMEText(s, 'plain', 'utf-8')
m['Subject'] = Header(s, 'utf-8')
print(repr(m.as_string()))

Output:

'Content-Type: text/plain; charset="utf-8"\nMIME-Version: 1.0\nContent-Transfer-Encoding: base64\nSubject: =?utf-8?b?YcOnw6Nv?=\n\nYcOnw6Nv\n

So the original script would become:

servidor = smtplib.SMTP()
servidor.connect(HOST, PORT)
servidor.login(user, usenha)
assunto = str(self.lineEdit.text())
para = str(globe_email)             
texto = str(self.textEdit.toPlainText())
corpo = MIMEText(texto, 'plain', 'utf-8')
corpo['From'] = user
corpo['To'] = para
corpo['Subject'] = Header(assunto, 'utf-8')
servidor.sendmail(user, [para], corpo.as_string())

Solution 2

I've improved the answer with other way to connect with the server and loggin, because the other way i had the problem to authenticate with the application and people can see all the libraries that should be use

from email.mime.text import MIMEText
from email.header import Header
import smtplib

user='[email protected]'
pwd='password'
server = smtplib.SMTP('smtp.office365.com', 587) #it works with outlook
server.ehlo()
server.starttls()
server.login(user, pwd)
assunto = 'Teste'
para = '[email protected]'
texto = 'Niterói é uma cidade incrível '
corpo = MIMEText(texto, 'plain', 'utf-8')
corpo['From'] = user
corpo['To'] = para
corpo['Subject'] = Header(assunto, 'utf-8')
try:
    server.sendmail(user, [para], corpo.as_string())
    print('email was sent')
except:
    print('error')
server.quit()
Share:
33,689
jonathan.hepp
Author by

jonathan.hepp

Updated on July 05, 2022

Comments

  • jonathan.hepp
    jonathan.hepp almost 2 years

    Here is a part of my code which sends an email:

    servidor = smtplib.SMTP()
    servidor.connect(HOST, PORT)
    servidor.login(user, usenha)
    assunto = str(self.lineEdit.text())
    para = str(globe_email)             
    texto = self.textEdit.toPlainText()
    textos = str(texto)
    corpo = MIMEText(textos.encode('utf-8'), _charset='utf-8')
    corpo['From'] = user
    corpo['To'] = para
    corpo['Subject'] = assunto
    servidor.sendmail(user, [para], corpo.as_string())
    

    Everything is ok except the part of the Subject. When I try to send a string with special characters (e.g. "ação") it raises this error:

    UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-2: ordinal not in range(128)
    

    How can I send emails with special characters in the Subject of MIMEText?

  • abestrad
    abestrad almost 4 years
    Thanks for your answer, but can you please expand on this answer? Review [How do I write a good answer?]( stackoverflow.com/help/how-to-answer)
  • Al Martins
    Al Martins over 3 years
    It seems? It is on the documentation: docs.python.org/2/library/email.header.html
  • ekhumoro
    ekhumoro over 3 years
    @AlMartins Yes, "seems". I just tested this with Python-3.2.6, Python-3.3.0 and Python-3.8.6, and I got the exact same output whether a Header object was used or not. This is probably due to compat32. Presumably the OP was using an earlier version of Python3 which had different behaviour. So it seems the current documentation is somewhat misleading, since a Header object isn't necessarily required. However, for the sake of backward compatibility, it seems best to continue using it.
  • Al Martins
    Al Martins over 3 years
    Not successful on Python 3 using Flask. html.encode('utf-8') works.