2

I'm trying to make a POST request to the Coinigy API in Python 3. This is the code I've been running.

from urllib.request import Request, urlopen
from urllib.parse import urlencode

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

values = {
"exchange_code": "BINA",
"exchange_market": "BTC/USDT",
"type": "all"
}


values = urlencode(values).encode("utf-8")
headers = urlencode(headers).encode("utf-8")


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

I'm getting the following error:

 AttributeError                            Traceback (most recent call last)
 <ipython-input-41-504342401726> in <module>()
      19 
      20 
 ---> 21 request = Request('https://api.coinigy.com/api/v1/data', 
 data=values, headers=headers)
      22 response_body = urlopen(request,values).read()
      23 print(response_body)

 ~/anaconda3/lib/python3.6/urllib/request.py in __init__(self, url, 
 data, headers, origin_req_host, unverifiable, method)
     333         self.data = data
     334         self._tunnel_host = None
 --> 335         for key, value in headers.items():
     336             self.add_header(key, value)
     337         if origin_req_host is None:

 AttributeError: 'bytes' object has no attribute 'items'

With a past POST request I wrote to their API for pulling down account activity info, I found I needed to use urlencode(headers).encode("utf-8") to get it in the right format to pass through the API. But now that doesn't seem to work. https://coinigy.docs.apiary.io/#reference/account-data/activity-log/activity

If I comment out the headers encode into utf-8 line, it seems to get through to Coinigy, but then it returns the following error code:

 b'{"err_num":"1057-14-01","err_msg":"Missing or empty parameters:"}'

But the urllib.request says that you must pass headers as a dictionary {} so I can't understand what is wrong, it should be the right data structure.

2 Answers 2

2

You should not URL encode your headers. Request expects headers to be a dictionary:

headers should be a dictionary, and will be treated as if add_header() was called with each key and value as arguments.

These are HTTP headers and when sent over the wire are in the form (newline-separated, colon space between header name and value):

User-Agent: Mozilla/5.0 blah blah
Content-Length: 500

So you should pass your headers dictionary in without doing urlencode on it.

This github repo might also be helpful to you: https://github.com/coinigy/api/blob/master/coinigy_api_rest.py

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

9 Comments

Thanks Bailey, yes exactly, I had read that Request requires headers as a dictionary, but when I do this, I get the following error code back from Coinigy.
Probably not. When you don't include the headers (one of which authenticates your request with your API key), coinigy returns that error because you are missing the headers. Try not serializing the headers (just pass the dict into the Request).
Ah yep, so apparently your values need to be JSON not urlended. from json import dumps; Request(data=dumps(values))
Sorry to be more clear, when I pass headers as a dictionary I get the following error from the endpoint: b'{"err_num":"1057-14-01","err_msg":"Missing or empty parameters:"}' No longer a Python attribute error which is good, but this is the structure mentioned in their documentation. At least as far as I can understand it.
Yes. And the API requires that your values be JSON encoded. Right now it is urlencoded.
|
0

As an update with Bailey's corrections: 1) Passing the values as JSON encoded rather than URL encoded. 2) utf-8 encoding the values

This is the correct code which works now, thanks!

from urllib.request import Request, urlopen
from urllib.parse import urlencode
from json import dumps

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

values = {
    'exchange_code': 'BINA',
    'exchange_market': 'BTC/USDT',
    'type': 'all'
}

values = dumps(values).encode('utf-8')
request = Request('https://api.coinigy.com/api/v1/data/', data=values, 
    headers=headers)

response_body = urlopen(request).read()
print(response_body)

Comments

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.