Sendgrid-python: HTTP Error 400: Bad Request on - sendgrid (6.0.5)

Created on 21 Aug 2019  路  20Comments  路  Source: sendgrid/sendgrid-python

Issue Summary

Using the basic template for 6.05 I'm getting 400 bad request error.

Steps to Reproduce

  1. Run pip install
sudo pip3 install sendgrid 
  1. Run script
import os
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail
from urllib.request import HTTPError
import python_http_client

to_emails = [
    ("[email protected]", 'Ian One'),
    ("[email protected]", 'Ian Two')
]
message = Mail(
    from_email=('[email protected]', 'Example 01'),
    to_emails=to_emails,
    subject='Email Alert',
    html_content='<strong>and easy to do anywhere, even with Python</strong>')

print(message.get())
try:
    sendgrid_client = SendGridAPIClient(os.environ.get('RD_OPTION_SENDGRID_API_KEY'))
    response = sendgrid_client.send(message)
    print(response.status_code)
    print(response.body)
    print(response.headers)
except (HTTPError, python_http_client.exceptions.BadRequestsError) as error:
    print(error)

Response = HTTP Error 400: Bad Request

Output of message.get()

{
  "from": { "name": "Example 01", "email": "[email protected]" },
  "personalizations": [
    {
      "to": [
        { "name": "Ian One", "email": "[email protected]" },
        { "name": "Ian Two", "email": "[email protected]" }
      ]
    }
  ],
  "subject": "Email Alert",
  "content": [
    {
      "value": "<strong>and easy to do anywhere, even with Python</strong>",
      "type": "text/html"
    }
  ]
}


Technical details:

  • sendgrid-python Version: sendgrid (6.0.5)
  • Python Version: 3.5

    I'm a bit baffled how the basic template fails to send here?

support

Most helpful comment

Do note that often there are additional details about the error in the response body. Example how to catch and log/print send failures:

except Exception as e:
    print(e)
    print(e.body)

All 20 comments

Hello @ianarsenault,

I am unable to reproduce the error. Does the hello email example work for you?

With best regards,

Elmer

Hi @thinkingserious thanks for the response.

I just ran the hello email fine.

import os
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail

message = Mail(
    from_email='[email protected]',
    to_emails='[email protected]',
    subject='Sending with Twilio SendGrid is Fun',
    html_content='<strong>and easy to do anywhere, even with Python</strong>')
try:
    sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
    response = sg.send(message)
    print(response.status_code)
    print(response.body)
    print(response.headers)
except Exception as e:
    print(str(e))

Output

b''
Server: nginx
Date: Wed, 21 Aug 2019 18:24:12 GMT
Content-Length: 0
Connection: close
X-Message-Id: pB0meu6MSJ2y4i-dWZfSuA
Access-Control-Allow-Origin: https://sendgrid.api-docs.io
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Authorization, Content-Type, On-behalf-of, x-sg-elas-acl
Access-Control-Max-Age: 600
X-No-CORS-Reason: https://sendgrid.com/docs/Classroom/Basics/API/cors.html

When I try to use multiple to_emails per the docs -> https://github.com/sendgrid/sendgrid-python/blob/master/use_cases/send_a_single_email_to_multiple_recipients.md

to_emails = [
    ('[email protected]', 'Example Name 0'),
    ('[email protected]', 'Example Name 1')
]
message = Mail(
    from_email='[email protected]',
    to_emails=to_emails,
    subject='Sending with Twilio SendGrid is Fun',
    html_content='<strong>and easy to do anywhere, even with Python</strong>')

I get python_http_client.exceptions.BadRequestsError: HTTP Error 400: Bad Request

@thinkingserious Further testing using a different template

import os
from sendgrid import SendGridAPIClient

message = {
    'personalizations': [
        {
            'to': [
                {
                    'email': '[email protected]'
                }
            ],
            'subject': 'Sending with Twilio SendGrid is Fun'
        }
    ],
    'from': {
        'email': '[email protected]'
    },
    'content': [
        {
            'type': 'text/html',
            'value': '<strong>and easy to do anywhere, even with Python</strong>'
        }
    ]
}

api_key = "******"

try:
    sg = SendGridAPIClient(api_key)
    response = sg.send(message)
    print(response.status_code)
    print(response.body)
    print(response.headers)
except Exception as e:
    print(str(e))

This runs fine, however when I try and add a second email

message = {
    'personalizations': [
        {
            'to': [
                {
                    'email': '[email protected]'
                },
                {
                    'email': '[email protected]'
                }
            ],
            'subject': 'Sending with Twilio SendGrid is Fun'
        }
    ],
......

I get the HTTP Error 400: Bad Request

The issue looks to be when it's multiple to_emails.

@thinkingserious do you have any suggestions or examples that work with multilpe to_emails? This has broken a few scripts and I've tried rolling back a few versions but continue getting HTTP 400 bad requests when trying to add multiple to_email's

I am having the same error.

point to note: I am using sendgrid transactional templates

To reproduce the error:

  1. run pip install
    pip install sendgrid
  2. run script
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail

sg = SendGridAPIClient(apikey="the_api_key")

email_data = Mail(
    from_email="[email protected]",
    to_email="[email protected]",
    subject="THIS IS A SAMPLE SUBJECT!",
)

email_data.dynamic_template_data = json.dumps({
        "username": "Nindo",
        "item_name": "some item",
        "item_slug": "path/to/some/item",
        "template_id": "the_actual_transactional_template_id",
        "message_type": "EMAIL"
})

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

Output:

Internal Server Error: /stores/event/event_id/
Traceback (most recent call last):
  File "/Users/Retina15/project/virtual/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
    response = get_response(request)
  File "/Users/Retina15/project/virtual/lib/python3.6/site-packages/django/core/handlers/base.py", line 128, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/Retina15/project/virtual/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/Retina15/project/virtual/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/Users/Retina15/project/virtual/lib/python3.6/site-packages/rest_framework/viewsets.py", line 116, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/Retina15/project/virtual/lib/python3.6/site-packages/rest_framework/views.py", line 495, in dispatch
    response = self.handle_exception(exc)
  File "/Users/Retina15/project/virtual/lib/python3.6/site-packages/rest_framework/views.py", line 455, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/Users/Retina15/project/virtual/lib/python3.6/site-packages/rest_framework/views.py", line 492, in dispatch
    response = handler(request, *args, **kwargs)
  File "/Users/Retina15/project/virtual/lib/python3.6/site-packages/rest_framework/mixins.py", line 84, in partial_update
    return self.update(request, *args, **kwargs)
  File "/Users/Retina15/project/virtual/lib/python3.6/site-packages/rest_framework/mixins.py", line 70, in update
    self.perform_update(serializer)
  File "/Users/Retina15/project/virtual/lib/python3.6/site-packages/rest_framework/mixins.py", line 80, in perform_update
    serializer.save()
  File "/Users/Retina15/project/virtual/lib/python3.6/site-packages/rest_framework/serializers.py", line 209, in save
    self.instance = self.update(self.instance, validated_data)
  File "/Users/Retina15/project/store/serializers/event.py", line 357, in update
    response = sg.client.mail.send.post(request_body=email_data.get())
  File "/Users/Retina15/project/virtual/lib/python3.6/site-packages/python_http_client/client.py", line 252, in http_request
    return Response(self._make_request(opener, request, timeout=timeout))
  File "/Users/Retina15/project/virtual/lib/python3.6/site-packages/python_http_client/client.py", line 172, in _make_request
    return opener.open(request, timeout=timeout)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 532, in open
    response = meth(req, response)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 642, in http_response
    'http', request, response, code, msg, hdrs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 570, in error
    return self._call_chain(*args)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 504, in _call_chain
    result = func(*args)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 650, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 400: Bad Request

Any fix for this? Having the same issue using the requests module.

@Samuel-Montoya what sendgrid version are you using?
meanwhile, try this out
stack overflow(AttributeError: 'SendGridAPIClient' object has no attribute 'send')

Hello,

I am having the same error using flask-sendgrid. I have the latest version of sendgrid installed. When launching my flask server, I can send one email fine then when I request to send another one it fails.

The 400 Bad Request error is an HTTP status code indicates that the request you sent to the webserver was malformed , in other words, the data stream sent by the client to the server didn't follow the rules. It means that the request itself has somehow incorrect or corrupted and the server couldn't understand it. There are a number of different causes for a 400: Bad Request Error . It might be a malformed request syntax, invalid request message framing, or deceptive request routing . In most cases, the problem is on the website itself, and there's not much you can do about that.

Thanks @linehammer, I figured that out 馃槈 As I stated in my other issue (sendgrid/python-http-client#133), it seems that flask-sendgrid send twice the to parametter after the second request.

Link to the flask_sendgrid issue https://github.com/frankV/flask-sendgrid/issues/19

Using your examples provided I've not been able to recreate the issue locally. There are docs here for more reasons why a 400 may be returned (e.g., to email addresses are not unique, too many personalizations, empty subject, etc.), but I'm not seeing any issues with the payloads in your examples.

Recommend double-checking to make sure your code is not violating any of those requirements and, if not, filing a support ticket to further debug the request.

Hello @ianarsenault,

Thanks for submitting a GitHub issue! We are very sorry that you are running into this problem. In order to better serve you, as this does not present itself as a library specific issue, we would like to ask that you reach out to our support team at https://support.sendgrid.com.

Thank you!

SendGrid DX Team

Another observation is if you just try to send with Subject only (aka empty body). It responds with Http 404 Bad Request, too.

Do note that often there are additional details about the error in the response body. Example how to catch and log/print send failures:

except Exception as e:
    print(e)
    print(e.body)

i got a forbidden error how to fix it

@vijaya1109 Print the error response body for more details. Example: https://github.com/sendgrid/sendgrid-python/blob/master/use_cases/error_handling.md

I encountered 400 Error when trying to send to multiple recipients in BCC.
Found the resolution here: https://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/errors.html
Hope it helps.

I received this error and got this error message: The content value must be a string at least one character in length.

For me, I have somewhere in my database that gets pulled to put the message of the email. I just forgot to put something in that message so it was trying to send a black email that provided the error above.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jeffoneill picture jeffoneill  路  4Comments

thinkingserious picture thinkingserious  路  5Comments

thinkingserious picture thinkingserious  路  3Comments

hanhaa picture hanhaa  路  4Comments

ArchTaqi picture ArchTaqi  路  4Comments