Poloniex API: Invalid instruction, Shiori
We’re attempting to make a request to the returnBalances endpoint of the Poloniex API using Python’s requests library but we’re getting back an “Invalid directive.” error. How do we fix it?
Here is the requests version of the code.
Running the code using Python Trio.6 we get
Hmmm… everything looks okay in the code. My very first thought is to see if we can replicate the behaviour when using urllib.request .
(If we were using Python Two.7 it would be urllib2 )
Here’s the code rewritten using urllib.request
And let’s see the output.
It works as expected. (but I gotz no bitcoinz ,_,)
So it seems like a good idea would be to debug both requests to see how they differ.
One way to do that is to use the nc (or netcat ) guideline to listen on a local port and point our requests at it. We can use the guideline nc -l 8080 to listen on port 8080
This means we will send our POST request to http://localhost:8080 instead of https://poloniex.com/tradingApi . We will also set the nonce value to 1 in both versions of the code as to have the exact same POST data.
Here’s the netcat output for the requests version.
And here is the output for the urllib.request version.
As we can see the Content-Length is identical as well as the POST data. This suggests to us that the problem lies in the headers.
The very first thing I notice is the Content-Type header in the urllib.request version that does not exist in the requests version.
So let’s go and by hand add that header to our headers dict in our requests code.
We also point our POST request back at the Poloniex API and run the code.
Okay superb! So it nows works with requests and it looks like the Content-Type header was the culprit.
So why is it not being set by requests ?
The data argument
Usually when passing form data you supply a dict to the data argument.
Let’s look at the netcat output.
So when we pass a dict it sets the header. However if we pass a string…
… the header does not get set.
There are many times that you want to send data that is not form-encoded. If you pass in a string instead of a dict, that data will be posted directly.
So not only does it skip the “urlencoding” of the data it also skips the sending of the Content-Type header which is causing the Poloniex API to “reject” our request.
We could switch data to a dict.
But as we need to turn it into a “string” for use in generating the signature it seems simpler to just leave data as it is and by hand send the Content-Type header with the request.
Older View Archive (65)
Web scraping: requests
Given the URL http://www.privataaffarer.se/borsguiden/analyser/ the purpose is to extract or “scrape” the stock data from the table on the page using Python. There are numerous pages of results so we would like to loop or “crawl” through numerous pages of the results.
Web scraping: NASA Pic of the Day
The objective is attempting to “scrape” pics from NASA’s Photo of the Day page using Python’s BeautifulSoup module. The pics are there when I look in the Inspector tab but they’re not there when I fetch the page using requests . What am I doing wrong?