Andre Araujo
Andre Araujo

Reputation: 2400

How to fix error urllib.error.HTTPError: HTTP Error 400: BAD REQUEST?

I have a script(test.py) to test some api, like this:

def get_response(fct, data, method=GET):
    """
    Performs the query to the server and returns a string containing the
    response.
    """
    assert(method in (GET, POST))
    url = f'http://{hostname}:{port}/{fct}'
    if method == GET:
        encode_data = parse.urlencode(data)
        response = request.urlopen(f'{url}?{encode_data}')
    elif method == POST:
        response = request.urlopen(url, parse.urlencode(data).encode('ascii'))
    return response.read()

In terminal I call:

python test.py -H 0.0.0.0 -P 5000 --add-data

The traceback:

Traceback (most recent call last):
  File "test.py", line 256, in <module>
    add_plays()
  File "test.py", line 82, in add_plays
    get_response("add_channel", {"name": channel}, method=POST)
  File "test.py", line 43, in get_response
    response = request.urlopen(url, parse.urlencode(data).encode('ascii'))
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 223, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 532, in open
    response = meth(req, response)
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 642, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 570, in error
    return self._call_chain(*args)
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 504, in _call_chain
    result = func(*args)
  File "/usr/local/Cellar/python/3.6.5/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

The data is {"name": "Channel1"}. I couldn't understand what is wrong. Please can someone give some tip or show whats's wrong?

When I call using curl, works:

curl -X POST -H "Content-Type: application/json" -d  '{"name": "Channel1"}' http://0.0.0.0:5000/add_channel

Upvotes: 2

Views: 1732

Answers (1)

Andre Araujo
Andre Araujo

Reputation: 2400

I solved the problem change the test script:

  1. The api was expected a JSON_MIME_TYPE = 'application/json', so I add a header in a request as follow bellow.
  2. The scrit was using a wrong encode because some text in JSON couldn't be encode in Unicode, Eg:"Omö" encode in ascii launch the exception UnicodeEncodeError: 'ascii' codec can't encode character '\xf6' in position 1: ordinal not in range(128). So I changed to utf8.

Here is the fixed code:

def get_response(fct, data, method=GET):
    """
    Performs the query to the server and returns a string containing the
    response.
    """
    assert(method in (GET, POST))
    url = f'http://{hostname}:{port}/{fct}'
    if method == GET:
        encode_data = parse.urlencode(data)
        req = request.Request(f'{url}?{encode_data}'
                            , headers={'content-type': 'application/json'})
        response = request.urlopen(req)
    elif method == POST:
        params = json.dumps(data)
        binary_data = params.encode('utf8')
        req = request.Request(url
                            , data= binary_data
                            , headers={'content-type': 'application/json'})
        response = request.urlopen(req)
    x = response.read()
    return x

Upvotes: 1

Related Questions