hootnot / oanda-api-v20

OANDA REST-V20 API wrapper. Easy access to OANDA's REST v20 API with oandapyV20 package. Checkout the Jupyter notebooks!
MIT License
398 stars 107 forks source link

Issue with sending requests #68

Closed kevinwong15 closed 7 years ago

kevinwong15 commented 7 years ago

Hi,

I am new to Python and I am getting the following error when sending a request through the wrapper. Can you walk me through how I can diagnose the problem?

Traceback (most recent call last): File "<pyshell#12>", line 1, in rv = api.request(r) File "C:\Python36\lib\site-packages\oandapyV20\oandapyV20.py", line 306, in request request_args, headers=headers) File "C:\Python36\lib\site-packages\oandapyV20\oandapyV20.py", line 243, in __request response.content.decode('utf-8')) oandapyV20.exceptions.V20Error

I ran the following codes;

access_token = "My own token" client = API(access_token=access_token) r = accounts.AccountList() response = client.request(r)

hootnot commented 7 years ago

@kevinwong15 please show the full code you ran

almanshow commented 7 years ago

Hello,

I have kind of the same problem: I ran:

get a list of trades

from oandapyV20 import API import oandapyV20.endpoints.trades as trades api = API(access_token="mytokenhere") accountID = "myIDhere" r = trades.TradesList(accountID)

show the endpoint as it is constructed for this call

print("REQUEST:{}".format(r)) rv = api.request(r) print("RESPONSE:\n{}".format(json.dumps(rv, indent=2)))

And I have the following response:

REQUEST:v3/accounts/myaccount/trades

V20Error Traceback (most recent call last)

in () 7 # show the endpoint as it is constructed for this call 8 print("REQUEST:{}".format(r)) ----> 9 rv = api.request(r) 10 print("RESPONSE:\n{}".format(json.dumps(rv, indent=2))) C:\Users\user\Anaconda3\lib\site-packages\oandapyV20\oandapyV20.py in request(self, endpoint) 304 305 response = self.__request(method, url, --> 306 request_args, headers=headers) 307 content = response.content.decode('utf-8') 308 content = json.loads(content) C:\Users\user\Anaconda3\lib\site-packages\oandapyV20\oandapyV20.py in __request(self, method, url, request_args, headers, stream) 241 response.content.decode('utf-8')) 242 raise V20Error(response.status_code, --> 243 response.content.decode('utf-8')) 244 return response 245 V20Error:
hootnot commented 7 years ago

@almanshow missing in your code:

import json

I have no trouble running your piece of code:

import json
from oandapyV20 import API
import oandapyV20.endpoints.trades as trades
api = API(access_token="...")
accountID = "xxx-yyy-zzzzzz-abc"   # make sure this is a V20 account! and not a v1 account: 1234567
r = trades.TradesList(accountID)

print("REQUEST:{}".format(r))
rv = api.request(r)
print("RESPONSE:\n{}".format(json.dumps(rv, indent=2)))

Gives:


REQUEST:v3/accounts/xxx-yyy-zzzzzz-abc/trades
RESPONSE:
{
  "trades": [], 
  "lastTransactionID": "7775"
}

@kevinwong15 @almanshow : do you have a V20 token / account ? If not please create the V20 account and regenerate a new token.

almanshow commented 7 years ago

Hello,

Thank you for helping me. I am sure I have a V20 account and even importing json I still get the same error message.

What could be the problem?

hootnot commented 7 years ago

Wrap the request in a try/except to get details on the error:

import json
from oandapyV20 import API
import oandapyV20.endpoints.trades as trades
api = API(access_token="...")
accountID = "xxx-yyy-zzzzzz-abc"   # make sure this is a V20 account! and not a v1 account: 1234567
r = trades.TradesList(accountID)

print("REQUEST:{}".format(r))
try:
    rv = api.request(r)
except V20Error as err:
    print("ERROR: {}".format(err))
else:
    print("RESPONSE:\n{}".format(json.dumps(rv, indent=2)))
almanshow commented 7 years ago

This is what I got after running your code:

REQUEST:v3/accounts/101-004-5535280-002/trades

V20Error Traceback (most recent call last)

in () 9 try: ---> 10 rv = api.request(r) 11 except V20Error as err: C:\Users\user\Anaconda3\lib\site-packages\oandapyV20\oandapyV20.py in request(self, endpoint) 305 response = self.__request(method, url, --> 306 request_args, headers=headers) 307 content = response.content.decode('utf-8') C:\Users\user\Anaconda3\lib\site-packages\oandapyV20\oandapyV20.py in __request(self, method, url, request_args, headers, stream) 242 raise V20Error(response.status_code, --> 243 response.content.decode('utf-8')) 244 return response V20Error: During handling of the above exception, another exception occurred: NameError Traceback (most recent call last) in () 9 try: 10 rv = api.request(r) ---> 11 except V20Error as err: 12 print("ERROR: {}".format(err)) 13 else: NameError: name 'V20Error' is not defined
hootnot commented 7 years ago

sorry, please import the V20Error:

from oandapyV20.exceptions import V20Error

And please also run this curl command:

TOK="..."
ACCT="..."
curl -H "Content-Type: application/json" \
     -H "Authorization: Bearer $TOK" \
     -X GET  "https://api-fxpractice.oanda.com/v3/accounts/${ACCT}/trades"

like the Python code it should give:

{"trades":[],"lastTransactionID":"7775"}

of course you will get other output, but you should get a valid response.

almanshow commented 7 years ago

It returned:" ERROR:

".

hootnot commented 7 years ago

and the curl command ?

almanshow commented 7 years ago

What should I do in curl?

hootnot commented 7 years ago

perform the API request as I gave it in the earlier comment. Just fill in the TOK and ACCT variables and run it as a shell script or directly from the commandline

almanshow commented 7 years ago

Still makes me the same error.

hootnot commented 7 years ago

that is not possible, curl has nothing to do with the python code.

For a curl example check the OANDA docs http://developer.oanda.com/rest-live-v20/trade-ep/#collapse_2_example_curl_1 for an example too.

If you don't have it please install it and run it.

If curl fails you definitely have an auth issue regarding your token/account. So I would like to exclude that.

Or run this script:

import urllib3   # maybe you need a: pip install urllib3

TOKEN = "<yourtoken>"

http = urllib3.PoolManager()
r = http.request(
    'GET',
    'https://api-fxpractice.oanda.com/v3/accounts',
    headers={
        'Authorization': 'Bearer {}'.format(TOKEN)
    })
print(r.status)
print(r.data.decode('utf-8'))

If your token/account setup is OK, you will see:

200
{"accounts":[{"id":"<accountID>","tags":[]},{"id":"<accountID>","tags":[]}]}
hootnot commented 7 years ago

Another option: activate logging in DEBUG mode. You should get details how communication with oanda takes place.

import json
from oandapyV20 import API
from oandapyV20.exceptions import V20Error
import oandapyV20.endpoints.trades as trades
import logging

api = API(access_token="...")
accountID = "xxx-yyy-zzzzzz-abc"   # make sure this is a V20 account! and not a v1 account: 1234567

logging.basicConfig(
    filename="./sometest.log",
    level=logging.DEBUG,
    format='%(asctime)s [%(levelname)s] %(name)s : %(message)s',
)
logger = logging.getLogger(__name__)

r = trades.TradesList(accountID)

print("REQUEST:{}".format(r))
try:
    rv = api.request(r)
except V20Error as err:
    print("ERROR: {}".format(err))
    print("HTTP RESP: {}".format(err.code))
else:
    print("RESPONSE:\n{}".format(json.dumps(rv, indent=2)))

The output should show something like:

2017-04-08 21:00:46,172 [INFO] oandapyV20.oandapyV20 : performing request https://api-fxpractice.oanda.com/v3/accounts/............./trades
2017-04-08 21:00:46,188 [DEBUG] requests.packages.urllib3.connectionpool : Starting new HTTPS connection (1): api-fxpractice.oanda.com
2017-04-08 21:00:47,059 [DEBUG] requests.packages.urllib3.connectionpool : https://api-fxpractice.oanda.com:443 "GET /v3/accounts/...................../trades HTTP/1.1" 200 40

I'm pretty sure that you will see a 401 instead of 200 (logging and HTTP RESP OUTPUT)

401 is an Authorization error. It does not give a responsebody back to the client. So the ERROR shows no data. You already noticed that after you wrapped the code in the try/except block. Adding the HTTP RESP print statement should give you the HTTP-response code though.

hootnot commented 7 years ago

@kevinwong15 @almanshow : I can't help you without feedback. So please run one or both scripts above and share the output.

kevinwong15 commented 7 years ago

Hi Hootnot,

Thanks, I realized my mistake.

I used my real account token and point it on the practice environment.

hootnot commented 7 years ago

the environment is practice by default. Make sure that you specify:environment="live" when you want to operate on your live-account. Success with further coding!

ZeroJitter commented 6 years ago

Where exactly do I specify "environment=live" - I can authenticate and trade against fxpractice endpoints, however placing live credentials into ~/.v20.conf does not change the endpoints used from practice to live.

hootnot commented 6 years ago

@ZeroJitter you refer to ~/v20.conf ... so it looks like you use the v20 library of oanda since my lib, oandapyV20, does not use such a config file unless you wrote it yourself and made your code use it.

So if you use oandapyV20: see : http://oanda-api-v20.readthedocs.io/en/latest/oanda-api-v20.html#the-client for details.

Just pass it:

client = API(access_token=..., environment="live")

If you use the v20 lib of oanda please check the docs of that library