sendgrid / sendgrid-python

The Official Twilio SendGrid Python API Library
https://sendgrid.com
MIT License
1.53k stars 711 forks source link

HTTP Error 400: Bad Request on - sendgrid (6.0.5) #828

Closed ianarsenault closed 4 years ago

ianarsenault commented 5 years ago

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 = [
    ("ian@example.com", 'Ian One'),
    ("ian2@example.com", 'Ian Two')
]
message = Mail(
    from_email=('no-reply@example.com', '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": "no-reply@example.com" },
  "personalizations": [
    {
      "to": [
        { "name": "Ian One", "email": "ian@example.com" },
        { "name": "Ian Two", "email": "ian2@example.com" }
      ]
    }
  ],
  "subject": "Email Alert",
  "content": [
    {
      "value": "<strong>and easy to do anywhere, even with Python</strong>",
      "type": "text/html"
    }
  ]
}

Technical details:

thinkingserious commented 5 years ago

Hello @ianarsenault,

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

With best regards,

Elmer

ianarsenault commented 5 years ago

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='from_email@example.com',
    to_emails='to@example.com',
    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

202
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 = [
    ('ian2@test.com', 'Example Name 0'),
    ('ian3@test.com', 'Example Name 1')
]
message = Mail(
    from_email='from@example.com',
    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

ianarsenault commented 5 years ago

@thinkingserious Further testing using a different template

import os
from sendgrid import SendGridAPIClient

message = {
    'personalizations': [
        {
            'to': [
                {
                    'email': 'ian1@test.com'
                }
            ],
            'subject': 'Sending with Twilio SendGrid is Fun'
        }
    ],
    'from': {
        'email': 'test@example.com'
    },
    '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': 'ian1@test.com'
                },
                {
                    'email': 'ian2@test.com'
                }
            ],
            '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.

ianarsenault commented 5 years ago

@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

newtonkiragu commented 4 years ago

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="support@email.com",
    to_email="example@email.com",
    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
Samuel-Montoya commented 4 years ago

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

newtonkiragu commented 4 years ago

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

Seluj78 commented 4 years ago

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.

Seluj78 commented 4 years ago

https://github.com/sendgrid/python-http-client/issues/133

linehammer commented 4 years ago

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.

Seluj78 commented 4 years ago

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.

Seluj78 commented 4 years ago

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

childish-sambino commented 4 years ago

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.

thinkingserious commented 4 years ago

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

bitnetservices commented 4 years ago

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

childish-sambino commented 4 years ago

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)
vijaya1109 commented 4 years ago

i got a forbidden error how to fix it

childish-sambino commented 4 years ago

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

eman32387 commented 4 years ago

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.

elebumm commented 3 years ago

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.