Python email lib - How to remove attachment from existing message?
Question
I have an email that I'm reading with the Python email lib that I need to modify the attachments of. The email Message class has the "attach" method, but does not have anything like "detach". How can I remove an attachment from a multipart message? If possible, I want to do this without recreating the message from scratch.
Essentially I want to:
- Load the email
- Remove the mime attachments
- Add a new attachment
Solution
set_payload()
may help.
set_payload(payload[, charset])
Set the entire message object’s payload to payload. It is the client’s responsibility to ensure the payload invariants.
A quick interactive example:
>>> from email import mime,message
>>> m1 = message.Message()
>>> t1=email.MIMEText.MIMEText('t1\r\n')
>>> print t1.as_string()
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
t1
>>> m1.attach(t1)
>>> m1.is_multipart()
True
>>> m1.get_payload()
[<email.mime.text.MIMEText instance at 0x00F585A8>]
>>> t2=email.MIMEText.MIMEText('t2\r\n')
>>> m1.set_payload([t2])
>>> print m1.get_payload()[0].as_string()
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
t2
>>>
OTHER TIPS
Well, from my experience, in the context you are working, everything is a Message
object. The message, its parts, attachments, everything. So, to accomplish what you want to do, you need to
- parse the message using the Parser API (this will get you the root
Message
object) - Walk the structure, determining what you need and what you don't (using a method of a Message instance, - .walk()), - remember, that everything is a
Message
. - Attach whatever you need to attach to the parts you've extracted and you are good to go.
To reiterate, what you are working with is, essentially, a tree, where Message
objects with .is_multipart() == True are nodes and Message
objects with .is_multipart() == False are end-nodes (their payload is a string, not a bunch of Message
objects).
The way I've figured out to do it is:
- Set the payload to an empty list with set_payload
- Create the payload, and attach to the message.