Colton
Colton

Reputation: 5

TypeError: encoding without a string argument

I looked up lots of similar question, but sadly none of them are close to mine.

I have a simple script that checks balance from exchange. It is a part of an unofficial API wrapper written in python and my understanding is it stuck somewhere between python 2 and python 3. I fixed errors one by one, but I'm completely stuck with this one. Here is the code:

import urllib.parse
import urllib.request
import json
import time
import hmac,hashlib


class Poloniex():
    def __init__(self, APIKey, Secret):
        self.APIKey = APIKey
        self.Secret = Secret

    def api_query(self, command, req={}):
        self.req = bytes(req, 'utf-8')
        req['command'] = command
        req['nonce'] = int(time.time()*1000)
        post_data = urllib.parse.quote(req)
        my_key = self.Secret
        my_key_bytes = bytes(my_key, 'utf-8')
        post_data_bytes = bytes(post_data, 'utf-8')

        sign = hmac.new(my_key_bytes, post_data_bytes, hashlib.sha512).hexdigest()
        headers = {
        'Sign': sign,
        'Key': my_key_bytes,
        #'Content-Type': 'application/json'
        }

        ret = urllib.request.urlopen(
            urllib.parse.quote('https://poloniex.com/tradingApi', safe=':/'), post_data_bytes,
                headers)
        jsonRet = json.loads(ret.read())
        return self.post_process(jsonRet)

    def returnBalances(self):
        return self.api_query('returnBalances')



inst = Poloniex("AAA-BBB", "123abcdef")

balance = inst.returnBalances()
print(balance)

Looks like I have a problem with syntax, but even after RTM I can't figure this out. It throws me:

TypeError: encoding without a string argument

and before that I had:

TypeError: quote_from_bytes() expected bytes

which was 'fixed' by

self.req = bytes(req, 'utf-8')

Can anybody please point me in the right direction?

Thank you.

UPD

sorry, forgot the traceback

Traceback (most recent call last):
  File "script.py", line 43, in <module>
    balance = inst.returnBalances()
  File "script.py", line 37, in returnBalances
    return self.api_query('returnBalances')
  File "script.py", line 18, in api_query
    post_data = urllib.parse.quote(req)
  File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/parse.py", line 775, in quote
    return quote_from_bytes(string, safe)
  File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/parse.py", line 800, in quote_from_bytes
    raise TypeError("quote_from_bytes() expected bytes")
TypeError: quote_from_bytes() expected bytes

Upvotes: 0

Views: 10770

Answers (1)

ForceBru
ForceBru

Reputation: 44838

In your code, req is a dictionary, but you're attempting to convert it to bytes here: self.req = bytes(req, 'utf-8'), which doesn't make sense since only strings can be converted this way.

The second error is caused by the fact that urllib.parse.quote works only with strings and bytes, but you're passing it a dictionary.

Upvotes: 2

Related Questions