Attach generated PDF in Mailgun message Django/Python

By : Trik
Source: Stackoverflow.com
Question!

I'm trying to switch our application from python mail to Mailgun but am having trouble with emails that have attachments. Specifically PDF's that are generated by the application (not stored in the file system).

Have no problems sending emails without attachments.

Currently we generate the PDF as such:

pdf = StringIO()
draw_pdf(pdf, params)
pdf.seek(0)
attachment = MIMEApplication(pdf.read())
attachment.add_header("Content-Disposition", "attachment", filename=filename)
pdf.close()

And then attach and mail it as such:

from django.core.mail import EmailMultiAlternatives
msg = EmailMultiAlternatives(subject, text_content, from_email, to_email)

if html_content:
    msg.attach_alternative(html_content, "text/html")

if attachment:
    msg.attach(attachment)

msg.send()

Works great... how can we convert to a Mailgun call?

I've tried various things including just passing it as file as is (unsuccessfully):

requests.post(mailgun_url, auth=("api", mailgun_api), data=data, files=attachment)

The above works fine without the attachment. data contains to, from, o:tags... etc.

Any help would be appreciated. Thanks!

EDIT

I was able to get it to work by changing my PDF code and getting the requests.post structured properly:

filename = "pdf_attachment.pdf"
pdf = StringIO()
draw_pdf(pdf, params)
pdf.seek(0)

attachment = ("attachment", (filename, pdf.read()))

r = requests.post(mailgun_url, auth=("api", mailgun_api), data=data, files=[attachment])
By : Trik


Answers
I was able to get it to work by changing my PDF code and getting the requests.post structured properly:

filename = "pdf_attachment.pdf"
pdf = StringIO()
draw_pdf(pdf, params)
pdf.seek(0)

attachment = ("attachment", (filename, pdf.read()))

r = requests.post(mailgun_url, auth=("api", mailgun_api), data=data, files=[attachment]
By : Trik


According to the docs it the files argument should be either a dictionary or a list of tuples. It must be looking for a name of some sorts.

requests.post(
    ...,
    files=[("attachment", open("files/test.jpg"))],
)


This video can help you solving your question :)
By: admin