Sendgrid-python: PDF file attachment Error 400

Created on 17 Nov 2016  路  11Comments  路  Source: sendgrid/sendgrid-python

Issue Summary

I'm trying to attach a PDF file to my email sent with sendgrid. But the Sendgrid Python library is throwing an error HTTP Error 400: Bad Request.

Steps to Reproduce

Here is my code :

sg = sendgrid.SendGridAPIClient(apikey=os.environ.get('SENDGRID_API_KEY'))

from_email = Email("[email protected]")
subject = "subject"
to_email = Email("[email protected]")
content = Content("text/html", email_body)

pdf = open(pdf_path, "rb").read().encode("base64")
attachment = Attachment()
attachment.set_content(pdf)
attachment.set_type("application/pdf")
attachment.set_filename("test.pdf")
attachment.set_disposition("attachment")
attachment.set_content_id(number)

mail = Mail(from_email, subject, to_email, content)
mail.add_attachment(attachment)

response = sg.client.mail.send.post(request_body=mail.get())

print(response.status_code)
print(response.body)
print(response.headers)

I think this is a problem due to the base64 encode

pdf = open(pdf_path, "rb").read().encode("base64")

I tried with this line to test : https://github.com/sendgrid/sendgrid-python/blob/ca96c8dcd66224e13b38ab8fd2d2b429dd07dd02/examples/helpers/mail/mail_example.py#L66

And it works. But when I'm using my PDF base64 encoded I have the error 400

Technical details:

  • sendgrid-python Version: master latest commit
  • Python Version: 2.7.9
help wanted community enhancement

Most helpful comment

Hi, I filled out the form thank you so much.

It's a good idea to put this snippet for the file attachment.

All 11 comments

I found a solution. I replaced this line :

pdf = open(pdf_path, "rb").read().encode("base64")

By this :

with open(pdf_path,'rb') as f:
    data = f.read()
    f.close()

encoded = base64.b64encode(data)

Now it works. I can send encoded file in the set_content :

attachment.set_content(encoded)

Thanks for the sharing the solution @JonathanVandal!

Please fill out this form so we can send you some swag :)

I'm re-opening this issue so that we can put this use case here: https://github.com/sendgrid/sendgrid-python/blob/master/USE_CASES.md

Hi, I filled out the form thank you so much.

It's a good idea to put this snippet for the file attachment.

Im currently having issues with this same thing at the moment, i was receiving the 400 error and with the code change the 400 error went away but now i am hitting the issue where my code is still not picking up the PDF file from my "/tmp" folder.

import os
from sendgrid.helpers.mail import *
import base64


sg = sendgrid.SendGridAPIClient(apikey='')
from_email = Email("")
to_email = Email("")
subject = "Attachment test"
content = Content("text/plain", "and easy to do anywhere, even with Python")
mail = Mail(from_email, subject, to_email, content)
response = sg.client.mail.send.post(request_body=mail.get())


with open('/tmp/test.pdf','rb') as f:
    data = f.read()
    f.close()

encoded = base64.b64encode(data)


attachment1 = Attachment()
attachment1.set_content(encoded)
attachment1.set_type("pdf")
attachment1.set_filename("test.pdf")
attachment1.set_disposition("inline")
attachment1.set_content_id("Ticket")
mail.add_attachment(attachment1)

print(response.status_code)
print(response.body)
print(response.headers)


if response.status_code == 202:
    print ("Message was successful")

Any help with this would be fantstic cheers in advanced.

@120GBSSD: Which python version are you using?

@ittus Sorry i am using 2.7 on ubuntu.

@120GBSSD Does it works if you remove the code to attach the pdf ? Do you receive the email ?

@JonathanVandal Yes the code does work without, it even works with the pdf attachment code included it just won't pick up the pdf so when i run the code it sends the email correctly but just with no attachment.

Try to initialize your data variable like this :

data = None
with open('/tmp/test.pdf','rb') as f:
    data = f.read()
    f.close()

And change this attachment parameters (set_type and set_disposition) :

attachment1 = Attachment()
attachment1.set_content(encoded)
attachment1.set_type("application/pdf"") // change pdf to application/pdf
attachment1.set_filename("test.pdf")
attachment1.set_disposition("attachment")  // change inline to attachment
attachment1.set_content_id("Ticket")

mail = Mail(from_email, subject, to_email, content)
mail.add_attachment(attachment1)
response = sg.client.mail.send.post(request_body=mail.get())

Call sg.client.mail.send.post(request_body=mail.get()) after the attachment mail.add_attachment(attachment)

I think the last fix will solve your problem. Because you are calling mail.get() before the pdf attachment code. Then mail.get() send the mail without the attachment. That is why you receive the mail without the pdf.

@JonathanVandal That resolved it, thank you very much for the help you are a life saver :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hugomallinson picture hugomallinson  路  3Comments

thinkingserious picture thinkingserious  路  5Comments

sohamnavadiya picture sohamnavadiya  路  4Comments

MadReal picture MadReal  路  4Comments

ArchTaqi picture ArchTaqi  路  4Comments