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.
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
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 :)
The attachment example is now here: https://github.com/sendgrid/sendgrid-python/blob/master/USE_CASES.md#attachment
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.