TypeError: POST data should be bytes, an iterable of bytes, or a file object. It can not be of type str

0

I'm trying to translate a code from Python 2.7 to 3.6

Code 2.7 works perfectly:

from urllib2 import Request, urlopen

values = """
   {
    "exchange_code": "PLNX",
    "exchange_market": "BTC/USDT"
   }
"""

headers = {
'Content-Type': 'application/json',
'X-API-KEY': 'xxxxxx',
'X-API-SECRET': 'yyyyyy'
}

request = Request('https://api.coinigy.com/api/v1/ticker', data=values, headers=headers)
response_body = urlopen(request).read()
print response_body

The code for 3.6:

from urllib.request import Request, urlopen

values = """
   {
    "exchange_code": "PLNX",
    "exchange_market": "BTC/USDT"
   }
"""

headers = {
'Content-Type': 'application/json',
'X-API-KEY': 'xxxxxx',
'X-API-SECRET': 'yyyyyy'
}

request = Request('https://api.coinigy.com/api/v1/ticker', data=values, headers=headers)
response_body = urlopen(request).read()
print(response_body)

Returns the following error:

  

TypeError Traceback (most recent call last)    in ()         1 request = Request (' link ', values, headers = headers)   ---- > 2 response_body = urlopen (request)         3 print (response_body)

     

C: \ Users \ Marcelo \ Anaconda3 \ lib \ urllib \ request.py in urlopen (url, date, timeout, cafile, capath, cadefault, context)       221 else:       222 opener = _opener   - > 223 return opener.open (url, date, timeout)       224       225 def install_opener (opener):

     

C: \ Users \ Marcelo \ Anaconda3 \ lib \ urllib \ request.py in open (self, fullurl, date, timeout)       522 for processor in self.process_request.get (protocol, []):       523 meth = getattr (processor, meth_name)   - > 524 req = meth (req)       525       526 response = self._open (req, data)

     

C: \ Users \ Marcelo \ Anaconda3 \ lib \ urllib \ request.py in do_request_ (self, request)      1246 msg="POST data should be bytes, an iterable of bytes," \      1247 "or a file object. It can not be of type str."   - > 1248 raise TypeError (msg)      1249 if not request.has_header ('Content-type'):      1250 request.add_unredirected_header (

     

TypeError: POST data should be bytes, an iterable of bytes, or a file object. It can not be of type str.

Thanks for the help.

    
asked by anonymous 21.03.2017 / 00:23

1 answer

2

Try this code:

from urllib.request import Request, urlopen

values = """
   {
    "exchange_code": "PLNX",
    "exchange_market": "BTC/USDT"
   }
"""

headers = {
    'Content-Type': 'application/json',
    'X-API-KEY': 'xxxxx',
    'X-API-SECRET': 'yyyyyy'
}

request = Request('https://api.coinigy.com/api/v1/ticker', data=values.encode('utf-8'), headers=headers)
response_body = urlopen(request).read()
print(response_body)

The problem was apparently in the way you were dealing with the dictionary. It was necessary to encode the values before.

From the documentation (English):

  

For an HTTP POST request method, data should be buffered in the standard application / x-www-form-urlencoded format. The urllib.parse.urlencode () function takes a mapping or sequence of 2-tuples and returns an ASCII string in this format. It should be encoded to bytes before being used as the data parameter .

Translation of the highlighted section:

  

The parameter must be converted to bytes before being used as   parameter of the data variable.

    
21.03.2017 / 12:26