0

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
2
  • Which of the above lines of code throws the TypeError? Commented Jul 13, 2017 at 16:03
  • oops, update the question Commented Jul 13, 2017 at 16:08

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

5 Comments

and without it I get "quote_from_bytes() expected bytes" :(
@Colton, you're constantly passing dictionaries instead of bytes
isn't that must be covered by post_data = urllib.parse.quote(req) and post_data_bytes = bytes(post_data, 'utf-8') ?
@Colton, I've explained it in my answer: req is a dictionary, you can't pass a dictionary to quote.
I guess I'll just have to pump up my skills in Python and rewrite the whole thing the way I see it, because the original script is just a mess and I have no enthusiasm cleaning it up. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.