Question

Please consider this example from the Mailgun Docs located here: http://documentation.mailgun.com/api-sending.html#examples

def send_complex_message():
return requests.post(
    "https://api.mailgun.net/v2/samples.mailgun.org/messages",
    auth=("api", "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"),
    files=MultiDict([("attachment", open("files/test.jpg")),
                     ("attachment", open("files/test.txt"))]),
    data={"from": "Excited User <me@samples.mailgun.org>",
          "to": "foo@example.com",
          "cc": "baz@example.com",
          "bcc": "bar@example.com",
          "subject": "Hello",
          "text": "Testing some Mailgun awesomness!",
          "html": "<html>HTML version of the body</html>"})

This isn't working for me. When the email arrives, it only has one attachment. I'm using the MultiDict object in python-bottle. I broke out just the files dictionary so I could examine it as follows:

files=MultiDict([("attachment", ("file1.txt", "text file 1"),
                 ("attachment", ("file2.txt", "text file 2")])

When you do files.values(), it only has one entry "file2.txt." This makes sense. I see the same behavior if I attempt to append() an entry as well. if the "Key" is the same ("attachment" in this case) it overwrites the existing record.

If I give it unique keys like attachment-1, and attachment-2, the API accepts the post, however the mail is delivered with no attachments.

So I guess my questions are:

1) Is there a difference in the MultiDict object in bottle which is causing this to fail? It would seem having multiple entries in a dictionary with the same key wouldn't be allowed?

2) Is there something undocumented I should be doing to submit multiple files to mailgun? or is it impossible to do so?

Was it helpful?

Solution

You can actually use a list of tuples in the file param and eliminate the need for Multidict. Here's what it would look like:

import requests

print requests.post("https://api.mailgun.net/v2/samples.mailgun.org/messages",
                    auth=("api", "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"),
                    files=[("attachment", open("files/test.jpg")),
                           ("attachment", open("files/test.txt"))],
                    data={"from": "Excited User <me@samples.mailgun.org>",
                          "to": "foo@example.com",
                          "cc": "baz@example.com",
                          "bcc": "bar@example.com",
                          "subject": "Hello",
                          "text": "Testing some Mailgun awesomness!",
                          "html": "<html>HTML version of the body</html>"})

Disclaimer: I work for Mailgun!

OTHER TIPS

I know this is already answered, however, I thought I'd post how I got this working with multiple attachments.

Here is my python function, the attachments parameter is a list of file paths.

import requests


def send_complex_message(to, email_from, subject, html_body, attachments=None):
    '''
    to, email_from, subject, and html_body should be self explanatory.
    attachments is a list of file paths, like this:

    ['/tmp/tmp5paoks/image001.png','/tmp/tmp5paoks/test.txt']
    '''

    data={"from": email_from,
          "to": [to,""],
          "subject": subject,
          "html": html_body}

    files = None      
    if attachments:
        files = {}
        count=0
        for attachment in attachments:
            with open(attachment,'rb') as f:
                files['attachment['+str(count)+']'] = (os.path.basename(attachment), f.read())    
            count = count+1

    return requests.post("https://api.mailgun.net/v2/mydomain.com/messages",
        auth=(USER, PASSWORD),
        files=files,
        data=data)

I know it is a little verbose, however, it is working :-) .

I got the idea on how to build the files dictionary from here: https://gist.github.com/adamlj/8576660

Thanks~!

You can add multiple attachments and/or inline images with file names this way:

import requests

print requests.post("https://api.mailgun.net/v2/samples.mailgun.org/messages",
                    auth=("api", "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"),
                    files=[("attachment", ("test.pdf", open("files/test.pdf"))),
                           ("attachment", ("test.txt", open("files/test.txt"))),
                           ("inline", ("test.jpg", open("img/test.txt")))],
                    data={"from": "Excited User <me@samples.mailgun.org>",
                          "to": "foo@example.com",
                          "cc": "baz@example.com",
                          "bcc": "bar@example.com",
                          "subject": "Hello",
                          "text": "Testing some Mailgun awesomness!",
                          "html": "<html>HTML version of the body with an image <img src=\"cid:test.jpg\"></html>"})

I hope this helps for all of you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top