0

I'm trying to send a mail with an html attachment which contains a table from a Pandas dataframe and some plotted images in Python 3.7. When the data in the provided dataframe is not null and therefore there are plotted images to send, i wont run into the error. I also collect occuring errors in a list and add them to the final string which i want to sent with the mail.

def mailMe():

    # Create the container email message.
    msg = EmailMessage()
    msg['Subject'] = 'Mail'
    msg['From'] = sender
    msg['To'] = receiver

    #style overview table
    htmlTable = (
        df.style
        .set_table_styles(styles)
        .applymap(color_negative_red)
        .set_caption('Auswertung')
        .render()
    )

    #attach 100 dpi images
    if not len(pngfiles100)==0:
        for file in pngfiles100:
            try:
                with open(r'.\\temp\\'+file, 'rb') as fp:
                    img_data = fp.read()

                msg.add_attachment(img_data, maintype='image',
                                            subtype=imghdr.what(None, img_data),
                                            filename=file)
            except:
                continue

            fp.close()        

    #Error messages
    htmlTable+='\n'+'<p style="font-family:Arial;"><b>Errors:</b></p>'
    if not len(errors)==0:
        for i in errors:
            htmlTable+='\n'+'<p style="font-family:Arial;">'+i+'</p>'


    pngFolder=r'.\\temp\\' 
    htmlTable+=""" 
    <table>
    <tbody>
    """

    i=0
    for col in df.columns:
        tempDf=pd.DataFrame(data=df[col])
        tmpHtml = (
            tempDf.style
            .set_table_styles(styles)
            .applymap(color_negative_red)
            .render()
            )
        if not len(pngfiles50)==0:
            #embed 50 dpi images in mail
            htmlTable+=u'\n'+'<tr><td>'+tmpHtml+'</td>'+'<td><img src="cid:image'+str(i+1)+'"></td></tr>'+u'\n'
            try:
                fp=open(pngFolder+pngfiles50[i],'rb')
                msgImage = MIMEImage(fp.read())
                fp.close()
                msgImage.add_header('Content-ID','<image'+str(i+1)+'>')
                msg.attach(msgImage)
            except:
                continue
            i+=1

    htmlTable+="""
    </tbody>
    </table>
    """

    # Send the email via our own SMTP server.
    with smtplib.SMTP(host) as s:
        htmlTable = MIMEText(htmlTable,"html")
        msg.attach(htmlTable)
        s.send_message(msg)

Traceback:

Traceback (most recent call last):
  File "c:\Users\mmai\.vscode\extensions\ms-python.python-2019.8.30787\pythonFiles\ptvsd_launcher.py", line 43, in <module>
    main(ptvsdArgs)
  File "c:\Users\mmai\.vscode\extensions\ms-python.python-2019.8.30787\pythonFiles\lib\python\ptvsd\__main__.py", line 432, in main
    run()
  File "c:\Users\mmai\.vscode\extensions\ms-python.python-2019.8.30787\pythonFiles\lib\python\ptvsd\__main__.py", line 316, in run_file
    runpy.run_path(target, run_name='__main__')
  File "C:\Users\mmai\AppData\Local\Programs\Python\Python37-32\lib\runpy.py", line 263, in run_path
    pkg_name=pkg_name, script_name=fname)
  File "C:\Users\mmai\AppData\Local\Programs\Python\Python37-32\lib\runpy.py", line 96, in _run_module_code
    mod_name, mod_spec, pkg_name, script_name)
  File "C:\Users\mmai\AppData\Local\Programs\Python\Python37-32\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "c:\Users\mmai\Documents\Python\Mail.py", line 1043, in <module>
    OEM()
  File "c:\Users\mmai\Documents\Python\Mail.py", line 168, in __init__
    self.mailMe()
  File "c:\Users\mmai\Documents\Python\Mail.py", line 1035, in mailMe
    s.send_message(msg)
  File "C:\Users\mmai\AppData\Local\Programs\Python\Python37-32\lib\smtplib.py", line 964, in send_message
    g.flatten(msg_copy, linesep='\r\n')
  File "C:\Users\mmai\AppData\Local\Programs\Python\Python37-32\lib\email\generator.py", line 116, in flatten
    self._write(msg)
  File "C:\Users\mmai\AppData\Local\Programs\Python\Python37-32\lib\email\generator.py", line 181, in _write
    self._dispatch(msg)
  File "C:\Users\mmai\AppData\Local\Programs\Python\Python37-32\lib\email\generator.py", line 214, in _dispatch
    meth(msg)
  File "C:\Users\mmai\AppData\Local\Programs\Python\Python37-32\lib\email\generator.py", line 427, in _handle_text
    if _has_surrogates(msg._payload) and not self.policy.cte_type=='7bit':
  File "C:\Users\mmai\AppData\Local\Programs\Python\Python37-32\lib\email\utils.py", line 57, in _has_surrogates
    s.encode()
AttributeError: 'list' object has no attribute 'encode'

It seems there is a problem with s.send_message(msg) but i can't wrap my head around it. Sender and receiver are both a string and not a list.

Solved it by adding msg.add_attachment(htmlTable)

1
  • It tries to encode a string object but you gave a list one. Commented Aug 26, 2019 at 10:02

2 Answers 2

1

This may help you:

"".join(s).encode()  
Sign up to request clarification or add additional context in comments.

8 Comments

Thanks for your answer. That makes the AttributeError: 'list' object has no attribute 'encode'' error go away but now i got 'AttributeError: 'bytes' object has no attribute 'encode''` when i let htmlTable="".join(htmlTable).encode()
This can be resolved by htmlTable="".join(htmlTable).decode("utf-8").encode()
AttributeError: 'str' object has no attribute 'decode'. So I'm really confused why it gives me an AttributeError since it is already a string and not a list.
what is the output of "".join(htmlTable) ?
Just a long html string from the pandas dataframe table like table id="T_2397f478_c7f4_11e9_b8df_f4b7e2f93ce1" ><caption>Auswertung der letzten drei Schichten</caption><thead> <tr> <th class="index_name level0" >Maschine</th> <th class="col_heading level0 col0" >MA216</th> <th class="col_heading level0 col1" >MA158</th> <th class="col_heading level0 col2" >MA084</th> <th class="col_heading level0 col3" >MA195</th> <th class="col_heading level0 col4" >MA092</th> <th class="col_heading level0 col5" >MA088</th> </tr></thead><tbody>...
|
0

if receiver is a list, then use

for i in range(len(receiver)):
            s.sendmail(message['From'], receiver[i], message.as_string())

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.