0

I am trying to send XML content using smtplib in python3.

Below is my code:

#!/usr/bin/python


import smtplib
import os

fromAddress = "adipratapsingh.aps@gmail.com"
toAddress = "adirameshwarsingh.ars@gmail.com"

msg = "From: Aditya Thakur<"+fromAddress+">\r\n"
msg = msg + "To: Aditya Singh<"+toAddress+">\r\n"
msg = msg + "Reply-To: Aditya Thakur<"+fromAddress+">\r\n"
msg = msg + "Content-Type: text/xml\r\n"
msg = msg + "Subject: Python mail\r\n"
msg = msg + "\r\n"
msg = msg + """
<xml version="1.0" encoding="utf-8">
<Name>
    <Firstname>Aditya</Firstname>
    <Middlename>Rameshwarpratap</Middlename>
    <Lastname>Singh</Lastname>
</Name>  
"""

server = smtplib.SMTP("smtp.gmail.com:587")
server.starttls()
server.login(fromAddress, os.getenv("GMAIL_APP_PASSWORD"))
server.sendmail(fromAddress, toAddress, msg)
server.quit()

This code works fine with normal text mail and HTML mail. I also am able to send XML content to the client.

But the thing is that this XMl content is sent as a file(attachment) by the name "noname" and I am not able to specify any filename for it. It goes by the name "noname" without any extension. And so, my client is not even able to view it without renaming it to "noname.xml". Is there any way I can specify a name for my XML file I am sending?

Secondly, When my client renames the file to "noname.xml", an error pops up in the browser that says

"There are some extra characters at line 8 column 1. Extra content at the end of the document."  

Why is that?

NOTE: I want to use smtplib and nothing else.

Aditya Singh
  • 2,343
  • 1
  • 23
  • 42
  • Practically [all answers here](http://stackoverflow.com/questions/3362600/how-to-send-email-attachments-with-python) of how to send email attachments in Python can help. – Parfait Dec 04 '15 at 22:05

1 Answers1

0

Well this is an interesting problem. your mail is exactly what you wanted to send, with XML data as body, and is perfectly correct (only one extra empty line after the headers). If you had used a DebuggingServer from the smtpd module, you could have controlled that it was sent as:

From: Aditya Thakur<adipratapsingh.aps@gmail.com>
To: Aditya Singh<adirameshwarsingh.ars@gmail.com>
Reply-To: Aditya Thakur<adipratapsingh.aps@gmail.com>
Content-Type: text/xml
Subject: Python mail
X-Peer: 127.0.0.1


<xml version="1.0" encoding="utf-8">
<Name>
    <Firstname>Aditya</Firstname>
    <Middlename>Rameshwarpratap</Middlename>
    <Lastname>Singh</Lastname>
</Name>

But the problem is that mail readers normally only process plain text (dynosaurs only used that format) or multipart for HTML text or attachements. So here your client's mail reader wrongly declares the body as an attachement and as it cannot find a name says it is noname.

You could try to advise your client to use a better reader that would strictly respect the standards (I would never do that!) or use the email module from standard Python library to build a message that most readers will be able to understand: a plain text introduction message, and the XML file joined as an attachement.


Concerning the question why your client cannot open the XML file, it is just because the first line is wrong. The correct line should have ?:

<?xml version="1.0" encoding="UTF-8"?>

So you want to build a mail containing an attached XML file by hand. It would be simpler with the email module but as the XML file is just a text file, you can avoid the base64 encoding. You must:

  • create a multipart message
  • add it a text/plain part for the introduction text
  • add it an application/xml part for the xml file

As I already said, the email Python module could do that for you, but you can also do it by hand, provided you force the Content-Transfert-Encoding to 8bits to avoid any base64 encoding. The code becomes:

import smtplib

fromAddress = "adipratapsingh.aps@gmail.com"
toAddress = "adirameshwarsingh.ars@gmail.com"
boundary = "===============nextPart=="
msg = 'Content-Type: multipart/mixed; boundary="' + boundary + '"\n'
msg += "MIME-Version: 1.0\r\n"
msg += "From: Aditya Thakur<"+fromAddress+">\n"
msg += "To: Aditya Singh<"+toAddress+">\n"
msg += "Reply-To: Aditya Thakur<"+fromAddress+">\n"
msg += "Subject:  Python mail\n"
msg += "\nThis is a multipart message\n"

# intro text
msg += '--' + boundary + "\n"
msg += '''Content-Type: text/plain; charset="utf8"
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit

Here is the expected XML file.
'''

# attached xml
msg += '--' + boundary + "\n"
msg += '''MIME-Version: 1.0
Content-Transfer-Encoding: 8bits
Content-Disposition: attachement; filename="filename.xml"
Content-Type: application/xml; name="filename.xml"; charset="utf-8"

'''
msg += '''<?xml version="1.0" encoding="utf-8"?>
<Name>
    <Firstname>Aditya</Firstname>
    <Middlename>Rameshwarpratap</Middlename>
    <Lastname>Singh</Lastname>
</Name> 
'''
msg += '--' + boundary + "\n"

# send the mail
server = smtplib.SMTP("smtp.gmail.com:587")
server.starttls()
server.login(fromAddress, os.getenv("GMAIL_APP_PASSWORD"))
server.sendmail(fromAddress, toAddress, msg)
server.quit()
server.close()
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • So can u give me any resource which shows how do we send attachments with plain SMTP protocol? Without using any libraries of any programming language? – Aditya Singh Dec 04 '15 at 16:41